Skip to content

Commit 687febc

Browse files
Merge pull request #49 from supervoidcoder/child-process-tree
Child-process-tree
2 parents e44a56a + 790ac4a commit 687febc

2 files changed

Lines changed: 77 additions & 18 deletions

File tree

main.cpp

Lines changed: 75 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,8 @@ UPDATE: This is done now!!
218218
DWORD parentPid = 0;
219219
HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
220220
if (hSnapshot == INVALID_HANDLE_VALUE) return;
221+
DWORD targetpid = pid; // the function already passes pid into us, but
222+
// just to be safe that pid doesn't get overwritten in the loop below
221223
std::string exeName = "Unknown/Dead Process";
222224
std::vector<std::string> exeNames;
223225
std::vector<ULONGLONG> exeTimes; // sorry for the crap code but idk how to make multidimensional arrays yet 😭😭😭
@@ -258,7 +260,44 @@ UPDATE: This is done now!!
258260

259261
if (!found) break;
260262
}
261-
CloseHandle(hSnapshot);
263+
// we're close... but not done yet. we need to find the CHILDREN of the process now.
264+
// We can create another loop, but this time going downwards, checking if a process
265+
// tells us that our target pid is it's parent. This time, we don't have to worry about
266+
// Checking if the parent is alive, because, well, since the target IS the parent,
267+
// it must be alive.
268+
int children = 0; // i wonder what would happen if you could set an emoji as var name
269+
if (Process32First(hSnapshot, &pe32)) {
270+
do {
271+
272+
// this time, our target pid is already stored at the very top of our list.
273+
// this means we don't have to add target pid stuff.
274+
// TODO: (for future optimization) we should probably move this before the
275+
// the previous loop, since emplacing to the front requires shifting the entire list
276+
// and therefore is inefficient, robbing us of a couple milliseconds of precious cpu time :(
277+
278+
if (pe32.th32ParentProcessID == targetpid) {
279+
exeName = WideToString(pe32.szExeFile); // this stores the name of our pid we're looking at in a var
280+
exeNames.emplace(exeNames.begin(), exeName); // this adds this to the front of the list
281+
// in this case, we are adding stuff to the front of the list, since we're looking at children
282+
// you might've noticed this doesn't have an emplace_front() like emplace_back() since
283+
// it's inefficient and the creators of the vector lib didn't do it
284+
pidNames.emplace(pidNames.begin(), pe32.th32ProcessID);
285+
ULONGLONG childTime = GetProcessCreationTime(pe32.th32ProcessID);
286+
exeTimes.emplace(exeTimes.begin(), childTime); // we don't even use this but we need to keep all the vectors the same length
287+
parentPids.emplace(parentPids.begin(), pe32.th32ProcessID); // just fill it up, we aren't using it
288+
children++; // keeps track of how many children we have (that sounds wrong when you say it)
289+
290+
}
291+
292+
293+
294+
295+
} while (Process32Next(hSnapshot, &pe32));
296+
297+
}
298+
299+
300+
CloseHandle(hSnapshot); // we're only closing the handle until we finish messing with the snapshot
262301
//phew thankfully we're done with that mess
263302
// now we need to reverse all the vector lists we made so
264303
// that the ancestry tree is correctly diisplayed from root to children like witr
@@ -269,34 +308,53 @@ CloseHandle(hSnapshot);
269308
std::reverse(parentPids.begin(), parentPids.end());
270309
// now get the size of one of the lists to know how many we got (they should all be the same length)
271310
size_t nameSize = exeNames.size();
311+
272312

273313
for (size_t i = 0; i < nameSize; i++ ){ // size_t is an unsigned integer designed to be ridiculously big to handle monstrosities,
274314
// idk just in case some psycho has a gazillion nested procs
275-
315+
276316
// surprise we have nested for loops
277317
for (size_t j = 0; j < i; j++) {
318+
size_t targetIndex = nameSize - children - 1;
319+
if (i < nameSize - children || j < targetIndex) {
278320
std::cout << " "; // this adds indentation
279321
}
322+
}
280323
if (i > 0) {
324+
325+
std::cout << " "; // add one indentation att start so it looks cleaner
326+
if (IsVirtualTerminalModeEnabled()) {
327+
std::cout << "\033[35m└─\033[0m "; // it's the little thingy thing └─ unicode from witr
328+
} else {
329+
std::cout << "└─ ";
330+
}}
331+
332+
if (IsVirtualTerminalModeEnabled()) {
333+
if (targetpid == pidNames[i]) {
334+
std::cout << "\033[1;32m" << exeNames[i] << " (PID " << pidNames[i] << ")" << "\033[0m" << std::endl;
335+
} else {
336+
std::cout << exeNames[i] << " (PID " << pidNames[i] << ")" << std::endl;
337+
}
338+
}else {
339+
if (targetpid == pidNames[i]) {
340+
std::cout << exeNames[i] << " (PID " << pidNames[i] << ") ⬅" << std::endl;
341+
342+
// since we don't have virtual terminal colors to highlight it,
343+
// we're gonna use arrows
344+
}
345+
else {
346+
std::cout << exeNames[i] << " (PID " << pidNames[i] << ")" << std::endl;
347+
}
348+
349+
350+
351+
281352

282-
std::cout << "└─ "; // it's the little thingy thing └─ unicode from witr
283-
}
284-
std::cout << exeNames[i] << " (PID " << pidNames[i] << ")" << std::endl;
353+
}
285354

286-
}
287355

288-
if (nameSize > 0) {
289-
DWORD lastParentPid = parentPids.back();
290-
ULONGLONG lastParentTime = GetProcessCreationTime(lastParentPid);
291-
ULONGLONG lastChildTime = exeTimes.back();
292356

293-
if (lastParentPid != 0 && lastParentPid != 4 &&
294-
(lastParentTime == 0 || lastParentTime >= lastChildTime)) {
295-
for (size_t j = 0; j < nameSize; j++) {
296-
std::cout << " ";
297-
}
298-
std::cout << "└─ [Parent Process Exited]" << std::endl;
299-
}
357+
300358
}
301359
}
302360

tests/process/process.bat

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
win-witr winlogon.exe
22
win-witr lsass.exe
3-
win-witr win-witr.exe
3+
win-witr win-witr.exe
4+
win-witr wininit.exe

0 commit comments

Comments
 (0)