I use Python 3.6, psutil. psutil displays the list of modules, but does not display their PID. For C ++ there is such , but how to adapt this code for ctypes? Are there any examples? I apologize for the absolutely Nubian questions, I have been suffering for a long time with this task. The initial task was to obtain the PID (and preferably the base address) of the DLL file loaded by the process. Or maybe there are ways to get PID modules without ctypes and C / C ++ code? Tell me please.

  • Look at this option, maybe this is what you need. - Pavel_K
  • It is not that. This is only for Linux. Needed for Windows. - Alexey Petrodiy
  • The psutil documentation seems to have a PID process mapping. Like this (I can't check): >>> import psutil >>> [p.info for p in psutil.process_iter(attrs=['pid', 'name']) if 'python' in p.info['name']] - Pavel_K
  • @ Alexey Petrodiy, how do you get the list of process modules via psutil? In general, in theory, modules cannot have a PID (Process ID), since these are process modules, not processes, but they should still have some kind of ID. - insolor
  • EnumProcessModulesEx way, an example of EnumProcessModulesEx : Is there a way to list all DLLs loaded in ALL processes using Python? - insolor

1 answer 1

An example with ctypes via snapshot of modules for the current process

 from ctypes import ( POINTER, Structure, byref, create_unicode_buffer, c_byte, c_char, c_ulong, c_void_p, sizeof, windll ) INVALID_HANDLE_VALUE = -1 TH32CS_SNAPMODULES = 8 TH32CS_SNAPMODULES32 = 16 CloseHandle = windll.kernel32.CloseHandle CreateToolhel32Snapshot = windll.kernel32.CreateToolhelp32Snapshot FormatMessage = windll.kernel32.FormatMessageW GetCurrentProcessId = windll.kernel32.GetCurrentProcessId GetLastError = windll.kernel32.GetLastError Module32First = windll.kernel32.Module32First Module32Next = windll.kernel32.Module32Next def getlasterror(): msg = create_unicode_buffer(0x100) num = FormatMessage(0x12FF, None, GetLastError(), 1024, msg, len(msg), None) print(msg.value if num else 'Ахтунг! Что-то странное произошло.') class ModuleSnap(object): def __init__(self, pid): self._snap = CreateToolhel32Snapshot( TH32CS_SNAPMODULES | TH32CS_SNAPMODULES32, pid ) if INVALID_HANDLE_VALUE == self._snap: raise OSError(getlasterror()) def __del__(self): if not CloseHandle(self._snap): getlasterror() def __enter__(self): return self def __exit__(self, e_type, e_value, e_trace): del self class tagMODULEENTRY32(Structure): _fields_ = [ ('dwSize', c_ulong), ('th32ModuleID', c_ulong), ('th32ProcessID', c_ulong), ('GlblcntUsage', c_ulong), ('ProccntUsage', c_ulong), ('modBaseAddr', POINTER(c_byte)), ('modBaseSize', c_ulong), ('hModule', c_void_p), ('szModule', c_char * 256), ('_szExePath', c_char * 260), ] def __init__(self): self.dwSize = sizeof(self) @property def szExePath(self): return str(self._szExePath, 'ascii', 'replace') if __name__ == '__main__': # на месте GetCurrentProcessId можно указать PID нужного процесса with ModuleSnap(GetCurrentProcessId()) as hndl: me, arr = tagMODULEENTRY32(), [] ok = Module32First(hndl._snap, byref(me)) while (ok): arr.append({'Module' : me.szExePath, 'BaseAddress' : hex(me.hModule)}) ok = Module32Next(hndl._snap, byref(me)) print(arr) 
  • with ModuleSnap(GetCurrentProcessId()) as hndl: ^ IndentationError: unindent does not match any outer indentation level change the code at all. - Alexey Petrodiy
  • Apparently you have crookedly copied the code to which, in fact, the error indicates (IndentationError - error of indents). - greg zakharov
  • I apologize. I do not sleep the second day. Everything works, thank you very much! - Alexey Petrodiy