c++winapintdll

Get process's thread information in windows OS


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.


Solution

  • 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;
      }
    }