I'm new in c++ programming and I'm coding a tool to enumerate information of all process running on windows OS.
After researching, googling, I have found a useful library Ntdll.lib and header winternl.h that helping me gathering information about process by using NtQuerySystemInformation() function. Everything work fine, I have call that function and retrieved the array of structure SYSTEM_PROCESS_INFORMATION that contains information about the process entry, here is my piece of code:
DWORD dwRet;
DWORD dwSize = 0;
NTSTATUS Status = STATUS_INFO_LENGTH_MISMATCH;
while (true)
{
// Check if pointer p is not NULL then free it
if (p != NULL) { VirtualFree(p, 0, MEM_RELEASE); }
p = (PSYSTEM_PROCESS_INFORMATION)VirtualAlloc(NULL, dwSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
// Query system to get the process list information
Status = NtQuerySystemInformation(SystemProcessInformation, (PVOID)p, (ULONG)dwSize, &dwRet);
if (Status == STATUS_SUCCESS)
{
cout << "Query process information successfully!!" << endl;
break;
}
else if (Status != STATUS_INFO_LENGTH_MISMATCH)
{
VirtualFree(p, 0, MEM_RELEASE);
p = NULL;
cout << "NtQuerySystemInformation failed with error code: " << Status << endl;
return FALSE;
}
// Add more 16kb to buffer in case there is more process opened during this loop
dwSize = dwRet + (2 << 14);
}
The problem appears when I was looking for thread details of processes, in particular, I don't know how to get the array of structure SYSTEM_THREAD_INFORMATION with NtQuerySystemInformation() function.
I have read the docs here: https://learn.microsoft.com/en-us/windows/win32/api/winternl/nf-winternl-ntquerysysteminformation and it says that each SYSTEM_PROCESS_INFORMATION structure returned by NtQuerySystemInformation() has 1 or more SYSTEM_THREAD_INFORMATION structure followed in memory but I don't know how to interact with them. Anyone has an idea for my problem? I'm just a newbie in c++ programming and I'm studying in user mode code so sorry if my question is silly or not worth asking.
Starting from your PSYSTEM_PROCESS_INFORMATION p
:
while (p) {
PSYSTEM_THREAD_INFORMATION pt = (PSYSTEM_THREAD_INFORMATION)(p + 1);
for (int t = 0; t < p->NumberOfThreads; t++) {
std::cout << "Start address of thread " << t << " is " << std::hex << pt->StartAddress << std::dec << std::endl;
pt++; // Adds sizeof(SYSTEM_THREAD_INFORMATION) to the address in pt
}
if (p->NextEntryOffset) {
p = PSYSTEM_PROCESS_INFORMATION((void *)p + NextEntryOffset);
} else {
p = nullptr;
}
}