Search code examples
pythonwindowswinapidlltasklist

tasklist does not list all Modules in 64-systems


I've got some problem. I'll tried to get all modules(dll files) for all processes on my machine. I tried to do this command in CMD:

tasklist /m

But it's a problem with 64-bit systems. If you`re running a 32-bit programm on 64-bit machine it does not list all modules, only

ntdll.dll, wow64.dll, wow64win.dll, wow64cpu.dll

Then i tried to do this with Python script, using pywin32 (win32api).

This is code:

import win32security,win32file,win32api,ntsecuritycon,win32con,win32process

processes = win32process.EnumProcesses()

for pid in processes:
    dll_list = []
    try:
        if pid:
            print('pid:', pid)
            ph = win32api.OpenProcess(win32con.MAXIMUM_ALLOWED, False, pid)
            dll = win32process.EnumProcessModules(ph)
            for dll_name in dll:
                dll_name_norm = win32process.GetModuleFileNameEx(ph, dll_name)
                dll_list.append(dll_name_norm)

            print("dll_list: ", dll_list)
            print("--------------")
    except:
        print("Error")
        print("--------------")

But result is the same. =( Please, help me with this, how I can see all dll files, load by each process.

P.S. It can be only standart Windows tools like command line, tasklist (NOT ListDlls, Process Explorer or the same thing) or script in Python.

Thank you a lot!


Solution

  • EnumProcessModules just shows processes with the same bittiness as Python. Instead, call EnumProcessModulesEx with dwFilterFlag=LIST_MODULES_ALL.

    Your current code requires the win32api module, which only recently added EnumProcessModulesEx, and which is not in the standard library. Here is a solution that uses only the standard library:

    from ctypes import byref, create_unicode_buffer, sizeof, WinDLL
    from ctypes.wintypes import DWORD, HMODULE, MAX_PATH
    
    Psapi = WinDLL('Psapi.dll')
    Kernel32 = WinDLL('kernel32.dll')
    
    PROCESS_QUERY_INFORMATION = 0x0400
    PROCESS_VM_READ = 0x0010
    
    LIST_MODULES_ALL = 0x03
    
    def EnumProcesses():
        buf_count = 256
        while True:
            buf = (DWORD * buf_count)()
            buf_size = sizeof(buf)
            res_size = DWORD()
            if not Psapi.EnumProcesses(byref(buf), buf_size, byref(res_size)):
                raise OSError('EnumProcesses failed')
            if res_size.value >= buf_size:
                buf_count *= 2
                continue
            count = res_size.value // (buf_size // buf_count)
            return buf[:count]
    
    def EnumProcessModulesEx(hProcess):
        buf_count = 256
        while True:
            buf = (HMODULE * buf_count)()
            buf_size = sizeof(buf)
            needed = DWORD()
            if not Psapi.EnumProcessModulesEx(hProcess, byref(buf), buf_size,
                                              byref(needed), LIST_MODULES_ALL):
                raise OSError('EnumProcessModulesEx failed')
            if buf_size < needed.value:
                buf_count = needed.value // (buf_size // buf_count)
                continue
            count = needed.value // (buf_size // buf_count)
            return map(HMODULE, buf[:count])
    
    def GetModuleFileNameEx(hProcess, hModule):
        buf = create_unicode_buffer(MAX_PATH)
        nSize = DWORD()
        if not Psapi.GetModuleFileNameExW(hProcess, hModule,
                                          byref(buf), byref(nSize)):
            raise OSError('GetModuleFileNameEx failed')
        return buf.value
    
    def get_process_modules(pid):
        hProcess = Kernel32.OpenProcess(
            PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
            False, pid)
        if not hProcess:
            raise OSError('Could not open PID %s' % pid)
        try:
            return [
                GetModuleFileNameEx(hProcess, hModule)
                for hModule in EnumProcessModulesEx(hProcess)]
        finally:
            Kernel32.CloseHandle(hProcess)
    
    for pid in EnumProcesses():
        try:
            dll_list = get_process_modules(pid)
            print('dll_list: ', dll_list)
        except OSError as ose:
            print(str(ose))
        print('-' * 14)