Search code examples
pythonwindowswinapitoken

Get all threads of a process using win32api (Python)


Let's say I have the following code that gets a handle to a process:

pid = 1234
procHandle = win32api.OpenProcess(win32con.MAXIMUM_ALLOWED,pywintypes.FALSE,pid)

How would I list and get handles on it's threads?


Solution

  • as far i know not exist public api which enumerated threads in process. but exist NtQuerySystemInformation and SystemProcessInformation or SystemExtendedProcessInformation - it return list of all processes and threads in system. by using this you can found all threads in process by id, not need open process

    NTSTATUS DumpProcessThreads(_Out_ ULONG_PTR dwProcessId)
    {
        NTSTATUS status;
        ULONG cb = 0x10000;
        do 
        {
            status = STATUS_NO_MEMORY;
    
            if (PVOID buf = LocalAlloc(0, cb + 0x1000))
            {
                if (0 <= (status = NtQuerySystemInformation(SystemExtendedProcessInformation, buf, cb, &cb)))
                {
                    status = STATUS_INVALID_CID;
    
                    union {
                        PVOID pv;
                        PBYTE pb;
                        PSYSTEM_PROCESS_INFORMATION pspi;
                    };
    
                    pv = buf;
                    ULONG NextEntryOffset = 0;
    
                    do 
                    {
                        pb += NextEntryOffset;
    
                        if (pspi->UniqueProcessId == (HANDLE)dwProcessId)
                        {
                            status = STATUS_SUCCESS;
    
                            if (ULONG NumberOfThreads = pspi->NumberOfThreads)
                            {
                                PSYSTEM_EXTENDED_THREAD_INFORMATION TH = pspi->TH;
    
                                do 
                                {
                                    DbgPrint("%p: %p(%p) [%p]\n", 
                                        TH->ClientId.UniqueThread, 
                                        TH->StartAddress, 
                                        TH->Win32StartAddress, 
                                        TH->TebAddress);
    
                                } while (TH++, --NumberOfThreads);
                            }
                            break;
                        }
    
                    } while (NextEntryOffset = pspi->NextEntryOffset);
                }
    
                LocalFree(buf);
            }
    
        } while (status == STATUS_INFO_LENGTH_MISMATCH);
    
        return status;
    }