1

I'm using the ctypes module and WinAPI to find the process name by PID. I've been looking at this example written in C/C++ and it's working except for the fact that the size of my szExeFile is 0 for every process. Am I missing something while using this API?

def find_pid_with_name(process_name: str):
    entry = PROCESSENTRY32()
    entry.dwSize = sizeof(PROCESSENTRY32)

    snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, None)

    if Process32First(snapshot, byref(entry)) == TRUE:
        while Process32Next(snapshot, byref(entry)) == TRUE:
            print(libc.wcslen(entry.szExeFile))

    CloseHandle(snapshot)

My structure definition for PROCESSENTRY32:

MAX_PATH = 260
class PROCESSENTRY32(Structure):
    _fields_ = [
        ("dwSize", c_ulong),
        ("cntUsage", c_ulong),
        ("th32ProcessID", c_ulong),
        ("th32DefaultHeapID", POINTER(c_ulong)),
        ("th32ModuleId", c_ulong),
        ("cntThreads", c_ulong),
        ("th32ParentProcessID", c_ulong),
        ("dwFlags", c_ulong),
        ("szExeFile", c_wchar * MAX_PATH)
    ]

And my function definitions:

CreateToolhelp32Snapshot = windll.kernel32.CreateToolhelp32Snapshot
CreateToolhelp32Snapshot.argtypes = [c_ulong, POINTER(c_ulong)]
CreateToolhelp32Snapshot.restype = c_ulong

libc = CDLL("msvcrt")
libc.wcslen.argtypes = [c_wchar_p]

Process32First = windll.kernel32.Process32First
Process32First.argtypes = [c_ulong, POINTER(PROCESSENTRY32)]
Process32First.restype = c_ubyte

Process32Next = windll.kernel32.Process32Next
Process32Next.argtypes = [c_ulong, POINTER(PROCESSENTRY32)]
Process32Next.restype = c_ubyte
Community
  • 1
  • 1
jacob
  • 4,656
  • 1
  • 23
  • 32

1 Answers1

3

See definition for PROCESSENTRY32W

Yours is missing pcPriClassBase

("dwSize", c_ulong),
("cntUsage", c_ulong),
("th32ProcessID", c_ulong),
("th32DefaultHeapID", POINTER(c_ulong)),
("th32ModuleId", c_ulong),
("cntThreads", c_ulong),
("th32ParentProcessID", c_ulong),
("pcPriClassBase" , c_long),<=======
("dwFlags", c_ulong),
("szExeFile", c_wchar * MAX_PATH)

Also try the following fo return type and arg type

Process32First.argtypes = [ c_void_p , POINTER( PROCESSENTRY32 ) ]
Process32First.rettype = c_int

Process32Next.argtypes = [ c_void_p , POINTER(PROCESSENTRY32) ]
Process32Next.rettype = c_int

Note, in WinAPI BOOL is a macro for int, HANDLE is a macro for void*

The C++ source which you are using is missing the first entry. It's supposed to use a do-while loop instead. You can deal with that later. For example:

HANDLE handle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (handle)
{
    PROCESSENTRY32 process;
    process.dwSize = sizeof(PROCESSENTRY32);
    Process32First(handle, &process);
    do
    {
        std::wcout << process.szExeFile << "\n";
    } while (Process32Next(handle, &process));
    CloseHandle(handle);
}
Barmak Shemirani
  • 30,904
  • 6
  • 40
  • 77