From 98c8f4bab86ab27c7591b7a758ab0c0785e542c5 Mon Sep 17 00:00:00 2001 From: supervoidcoder <88671013+supervoidcoder@users.noreply.github.com> Date: Mon, 26 Jan 2026 22:10:27 -0500 Subject: [PATCH 1/9] feat: added user entry on output. Now it shows what user started a specific process. --- main.cpp | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 58 insertions(+), 1 deletion(-) diff --git a/main.cpp b/main.cpp index 9796ce0..bd0da87 100644 --- a/main.cpp +++ b/main.cpp @@ -303,6 +303,59 @@ void PrintErrorHints(int errorCode) { } } +std::optional GetUserNameFromProcess(DWORD id) +{ + HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, id); // 1- OpenProcess + std::wstring endUser = L""; + std::wstring endDomain = L""; + + if (hProcess != NULL) + { + HANDLE hToken = NULL; + + if (OpenProcessToken(hProcess, TOKEN_QUERY, &hToken)) // 2- OpenProcessToken + { + DWORD tokenSize = 0; + GetTokenInformation(hToken, TokenUser, NULL, 0, &tokenSize); + + if (tokenSize > 0) + { + BYTE* data = new BYTE[tokenSize]; + GetTokenInformation(hToken, TokenUser, data, tokenSize, &tokenSize); // 3- GetTokenInformation + TOKEN_USER* pUser = (TOKEN_USER*)data; + PSID pSID = pUser->User.Sid; + DWORD userSize = 0; + DWORD domainSize = 0; + SID_NAME_USE sidName; + LookupAccountSid(NULL, pSID, NULL, &userSize, NULL, &domainSize, &sidName); + wchar_t* user = new wchar_t[userSize + 1]; + wchar_t* domain = new wchar_t[domainSize + 1]; + LookupAccountSid(NULL, pSID, user, &userSize, domain, &domainSize, &sidName); // 4- LookupAccountSid + user[userSize] = L'\0'; + domain[domainSize] = L'\0'; + endUser = user; + endDomain = domain; + delete[] domain; + delete[] user; + delete[] data; + } + + CloseHandle(hToken); + } + + CloseHandle(hProcess); + + if (endUser != L"") + return endUser; + } + + return {}; +} +// I just straight up stole this function from Stack Overflow lol +// https://stackoverflow.com/questions/2686096/c-get-username-from-process +// Permalink: https://stackoverflow.com/a/73242956 +// Thanks! + void PrintAncestry(DWORD pid) { @@ -558,7 +611,11 @@ void PIDinspect(DWORD pid) { // ooh guys look i'm in the void } // Use our little lookup table to give hints for specific errors - + + std::cout << "User: " << GetUserNameFromProcess(pid); + // literally very rough start i just rushed to get this done + // still needs lots of error handling, some code modifying + // so far i dont even know if the function works due to how rushed i did this From a0fd0c7ba18c66b88b2afbc9bb7e62973ae26641 Mon Sep 17 00:00:00 2001 From: supervoidcoder <88671013+supervoidcoder@users.noreply.github.com> Date: Mon, 26 Jan 2026 22:12:30 -0500 Subject: [PATCH 2/9] fix: Convert Wide String to regular string so that cout can process it while displaying user. --- main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.cpp b/main.cpp index bd0da87..b6940f5 100644 --- a/main.cpp +++ b/main.cpp @@ -612,7 +612,7 @@ void PIDinspect(DWORD pid) { // ooh guys look i'm in the void // Use our little lookup table to give hints for specific errors - std::cout << "User: " << GetUserNameFromProcess(pid); + std::cout << "User: " << WideToString(GetUserNameFromProcess(pid)); // literally very rough start i just rushed to get this done // still needs lots of error handling, some code modifying // so far i dont even know if the function works due to how rushed i did this From 410c6ca7d7895a230d0212ad2c4a3d43b2b2ac69 Mon Sep 17 00:00:00 2001 From: supervoidcoder <88671013+supervoidcoder@users.noreply.github.com> Date: Mon, 26 Jan 2026 22:22:04 -0500 Subject: [PATCH 3/9] feat: fixed wstring errors and added blue colors for user --- main.cpp | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/main.cpp b/main.cpp index b6940f5..001d0fb 100644 --- a/main.cpp +++ b/main.cpp @@ -611,8 +611,22 @@ void PIDinspect(DWORD pid) { // ooh guys look i'm in the void } // Use our little lookup table to give hints for specific errors - - std::cout << "User: " << WideToString(GetUserNameFromProcess(pid)); + auto user = GetUserNameFromProcess(pid); // dang it dude it feels like such a war crime using auto in c++ 😭✌️ + if (user.has_value()) { + if (IsVirtualTerminalModeEnabled()) { + std::cout << "\033[1;34mUser\033[0m: " << WideToString(user.value()); + else { + std::cout << "User: " << WideToString(user.value()); + } + + } else { + if (IsVirtualTerminalModeEnabled()) { + std::cout << "\033[1;34mUser\033[0m: \033[1;31mN/A (Failed to access info)\033[0m"; + } else { + std::cout << "User: N/A (Failed to access info)"; + } + } + // literally very rough start i just rushed to get this done // still needs lots of error handling, some code modifying // so far i dont even know if the function works due to how rushed i did this From a9142c172dc9c1d85914180b2186c7191def313c Mon Sep 17 00:00:00 2001 From: supervoidcoder <88671013+supervoidcoder@users.noreply.github.com> Date: Mon, 26 Jan 2026 22:27:10 -0500 Subject: [PATCH 4/9] fix: syntax error due to misplaced braces --- main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.cpp b/main.cpp index 001d0fb..3860e58 100644 --- a/main.cpp +++ b/main.cpp @@ -615,7 +615,7 @@ void PIDinspect(DWORD pid) { // ooh guys look i'm in the void if (user.has_value()) { if (IsVirtualTerminalModeEnabled()) { std::cout << "\033[1;34mUser\033[0m: " << WideToString(user.value()); - else { + } else { std::cout << "User: " << WideToString(user.value()); } From fa95faf0a574afab86c7ee6c49179d7c8325c6f4 Mon Sep 17 00:00:00 2001 From: supervoidcoder <88671013+supervoidcoder@users.noreply.github.com> Date: Mon, 26 Jan 2026 22:34:39 -0500 Subject: [PATCH 5/9] fix: Permission error fixed by adding a fallback when calling process_query_information and add a PROCESS_QUERY_LIMITED_INFORMATION fallback --- main.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/main.cpp b/main.cpp index 3860e58..5e57e9b 100644 --- a/main.cpp +++ b/main.cpp @@ -305,7 +305,12 @@ void PrintErrorHints(int errorCode) { std::optional GetUserNameFromProcess(DWORD id) { - HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, id); // 1- OpenProcess + HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, id); + + + if (!hProcess && GetLastError() == ERROR_ACCESS_DENIED) { + hProcess = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, id); // cute fallback + } std::wstring endUser = L""; std::wstring endDomain = L""; From 3ec04e373b949a565c2f41d7e51da6601c4ac0f4 Mon Sep 17 00:00:00 2001 From: supervoidcoder <88671013+supervoidcoder@users.noreply.github.com> Date: Tue, 27 Jan 2026 15:18:59 -0500 Subject: [PATCH 6/9] feat: add TrustedInstaller.exe to CI tests --- tests/process/process.bat | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/process/process.bat b/tests/process/process.bat index fddac5c..8c6dd2c 100644 --- a/tests/process/process.bat +++ b/tests/process/process.bat @@ -1,4 +1,6 @@ win-witr winlogon.exe win-witr lsass.exe win-witr win-witr.exe -win-witr wininit.exe \ No newline at end of file + +win-witr wininit.exe +win-witr TrustedInstaller.exe From b1d8fd65b11b5811ae918578fd520f4d44dd8667 Mon Sep 17 00:00:00 2001 From: supervoidcoder <88671013+supervoidcoder@users.noreply.github.com> Date: Tue, 27 Jan 2026 15:33:11 -0500 Subject: [PATCH 7/9] fix: remove trusted installer (didn't work) --- tests/process/process.bat | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/process/process.bat b/tests/process/process.bat index 8c6dd2c..84ae8e1 100644 --- a/tests/process/process.bat +++ b/tests/process/process.bat @@ -1,6 +1,5 @@ win-witr winlogon.exe win-witr lsass.exe win-witr win-witr.exe - win-witr wininit.exe -win-witr TrustedInstaller.exe + From 5e40214997421536741c81bd5ac6dd745a1148ff Mon Sep 17 00:00:00 2001 From: supervoidcoder <88671013+supervoidcoder@users.noreply.github.com> Date: Tue, 27 Jan 2026 15:50:13 -0500 Subject: [PATCH 8/9] feat: Add error checks for token/SID queries to prevent crashes and invalid data. GetTokenInformation (line 329) and LookupAccountSid (line 338) return values are ignored. If either fails, pUser->User.Sid is dereferenced with invalid data or user/domain buffers contain garbage, leading to crashes or corrupted output. The second call to each function must return successfully before using its results. Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --- main.cpp | 42 +++++++++++++++++++++++++++++------------- 1 file changed, 29 insertions(+), 13 deletions(-) diff --git a/main.cpp b/main.cpp index 5e57e9b..1067c59 100644 --- a/main.cpp +++ b/main.cpp @@ -321,28 +321,44 @@ std::optional GetUserNameFromProcess(DWORD id) if (OpenProcessToken(hProcess, TOKEN_QUERY, &hToken)) // 2- OpenProcessToken { DWORD tokenSize = 0; - GetTokenInformation(hToken, TokenUser, NULL, 0, &tokenSize); + if (!GetTokenInformation(hToken, TokenUser, nullptr, 0, &tokenSize) && + GetLastError() != ERROR_INSUFFICIENT_BUFFER) { + CloseHandle(hToken); + CloseHandle(hProcess); + return {}; + } if (tokenSize > 0) { - BYTE* data = new BYTE[tokenSize]; - GetTokenInformation(hToken, TokenUser, data, tokenSize, &tokenSize); // 3- GetTokenInformation - TOKEN_USER* pUser = (TOKEN_USER*)data; + std::vector data(tokenSize); + if (!GetTokenInformation(hToken, TokenUser, data.data(), tokenSize, &tokenSize)) { + CloseHandle(hToken); + CloseHandle(hProcess); + return {}; + } + TOKEN_USER* pUser = reinterpret_cast(data.data()); PSID pSID = pUser->User.Sid; DWORD userSize = 0; DWORD domainSize = 0; SID_NAME_USE sidName; - LookupAccountSid(NULL, pSID, NULL, &userSize, NULL, &domainSize, &sidName); - wchar_t* user = new wchar_t[userSize + 1]; - wchar_t* domain = new wchar_t[domainSize + 1]; - LookupAccountSid(NULL, pSID, user, &userSize, domain, &domainSize, &sidName); // 4- LookupAccountSid - user[userSize] = L'\0'; - domain[domainSize] = L'\0'; + if (!LookupAccountSidW(nullptr, pSID, nullptr, &userSize, nullptr, &domainSize, &sidName) && + GetLastError() != ERROR_INSUFFICIENT_BUFFER) { + CloseHandle(hToken); + CloseHandle(hProcess); + return {}; + } + std::wstring user(userSize, L'\0'); + std::wstring domain(domainSize, L'\0'); + if (!LookupAccountSidW(nullptr, pSID, user.data(), &userSize, domain.data(), &domainSize, &sidName)) { + CloseHandle(hToken); + CloseHandle(hProcess); + return {}; + } + user.resize(userSize); + domain.resize(domainSize); endUser = user; endDomain = domain; - delete[] domain; - delete[] user; - delete[] data; + } } CloseHandle(hToken); From cd1c3c7df8a7c73a6724751b6031110e8f6a2706 Mon Sep 17 00:00:00 2001 From: supervoidcoder <88671013+supervoidcoder@users.noreply.github.com> Date: Tue, 27 Jan 2026 15:55:02 -0500 Subject: [PATCH 9/9] fix: misplaced brace } --- main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/main.cpp b/main.cpp index 1067c59..e3b2dc9 100644 --- a/main.cpp +++ b/main.cpp @@ -359,7 +359,7 @@ std::optional GetUserNameFromProcess(DWORD id) endUser = user; endDomain = domain; } - } + CloseHandle(hToken); }