From fb0171b8b907bce914b09413f890ad5d6d837d04 Mon Sep 17 00:00:00 2001 From: Clement Rouault Date: Mon, 21 Mar 2016 13:18:01 +0100 Subject: [PATCH] WinpProcess in not a PROCESSENTRY32 anymore --- TODO | 11 +++++- ctypes_generation/winfunc.txt | 26 ++++++++++++++ windows/generated_def/winfuncs.py | 18 +++++++++- windows/winobject.py | 53 ++++++++++++++++++++++------- windows/winproxy.py | 56 +++++++++++++++++++++++-------- 5 files changed, 135 insertions(+), 29 deletions(-) diff --git a/TODO b/TODO index dc99b43..3ad2bc8 100644 --- a/TODO +++ b/TODO @@ -37,6 +37,11 @@ TODO: * What about ``NtWow64QueryVirtualMemory64`` ? +CHANGELOG: + + * NEW REGISTRY -> change examples and documentation + * WinProcess is not a PROCESSENTRY32 anymore (change doc) + FIXME: - WMI - COM initialisation when injected in another process @@ -46,4 +51,8 @@ FIXME: - setup.py build seems to raise an error - winutils.create_process : use WinProcess._from_handle - - Push("[ECX]") in simple_x64 as a "H" rex and i think it should not.. \ No newline at end of file + - Push("[ECX]") in simple_x64 as a "H" rex and i think it should not.. + +RESSOURCE + + * read http://www.codeproject.com/Articles/18975/Listing-Used-Files \ No newline at end of file diff --git a/ctypes_generation/winfunc.txt b/ctypes_generation/winfunc.txt index f67e17e..8ea8625 100644 --- a/ctypes_generation/winfunc.txt +++ b/ctypes_generation/winfunc.txt @@ -1057,4 +1057,30 @@ BOOL WINAPI DuplicateHandle( _In_ DWORD dwDesiredAccess, _In_ BOOL bInheritHandle, _In_ DWORD dwOptions +); + +DWORD WINAPI GetModuleBaseNameA( + _In_ HANDLE hProcess, + _In_opt_ HMODULE hModule, + _Out_ LPCSTR lpBaseName, + _In_ DWORD nSize +); + +DWORD WINAPI GetModuleBaseNameW( + _In_ HANDLE hProcess, + _In_opt_ HMODULE hModule, + _Out_ LPWSTR lpBaseName, + _In_ DWORD nSize +); + +DWORD WINAPI GetProcessImageFileNameA( + _In_ HANDLE hProcess, + _Out_ LPCSTR lpImageFileName, + _In_ DWORD nSize +); + +DWORD WINAPI GetProcessImageFileNameW( + _In_ HANDLE hProcess, + _Out_ LPWSTR lpImageFileName, + _In_ DWORD nSize ); \ No newline at end of file diff --git a/windows/generated_def/winfuncs.py b/windows/generated_def/winfuncs.py index 80e99d3..ceadc5c 100644 --- a/windows/generated_def/winfuncs.py +++ b/windows/generated_def/winfuncs.py @@ -3,7 +3,7 @@ from ctypes import * from ctypes.wintypes import * from .winstructs import * -functions = ['ExitProcess', 'TerminateProcess', 'GetLastError', 'GetCurrentProcess', 'CreateFileA', 'CreateFileW', 'LdrLoadDll', 'NtQuerySystemInformation', 'NtQueryInformationProcess', 'NtQueryVirtualMemory', 'NtCreateThreadEx', 'NtQueryInformationThread', 'GetExitCodeThread', 'GetExitCodeProcess', 'VirtualAlloc', 'VirtualAllocEx', 'VirtualFree', 'VirtualFreeEx', 'VirtualProtect', 'VirtualQuery', 'VirtualQueryEx', 'GetModuleFileNameA', 'GetModuleFileNameW', 'CreateThread', 'CreateRemoteThread', 'VirtualProtect', 'CreateProcessA', 'CreateProcessW', 'GetThreadContext', 'NtGetContextThread', 'SetThreadContext', 'NtSetContextThread', 'OpenThread', 'OpenProcess', 'CloseHandle', 'ReadProcessMemory', 'NtWow64ReadVirtualMemory64', 'WriteProcessMemory', 'CreateToolhelp32Snapshot', 'Thread32First', 'Thread32Next', 'Process32First', 'Process32Next', 'Process32FirstW', 'Process32NextW', 'GetProcAddress', 'LoadLibraryA', 'LoadLibraryW', 'OpenProcessToken', 'LookupPrivilegeValueA', 'LookupPrivilegeValueW', 'AdjustTokenPrivileges', 'FindResourceA', 'FindResourceW', 'SizeofResource', 'LoadResource', 'LockResource', 'GetVersionExA', 'GetVersionExW', 'GetVersion', 'GetCurrentThread', 'GetCurrentThreadId', 'GetCurrentProcessorNumber', 'AllocConsole', 'FreeConsole', 'GetStdHandle', 'SetStdHandle', 'SetThreadAffinityMask', 'WriteFile', 'GetExtendedTcpTable', 'GetExtendedUdpTable', 'SetTcpEntry', 'AddVectoredContinueHandler', 'AddVectoredExceptionHandler', 'TerminateThread', 'ExitThread', 'RemoveVectoredExceptionHandler', 'ResumeThread', 'SuspendThread', 'WaitForSingleObject', 'GetThreadId', 'LoadLibraryExA', 'LoadLibraryExW', 'SymInitialize', 'SymFromName', 'SymLoadModuleEx', 'SymSetOptions', 'SymGetTypeInfo', 'DeviceIoControl', 'GetTokenInformation', 'RegOpenKeyExA', 'RegOpenKeyExW', 'RegGetValueA', 'RegGetValueW', 'RegCloseKey', 'Wow64DisableWow64FsRedirection', 'Wow64RevertWow64FsRedirection', 'Wow64EnableWow64FsRedirection', 'Wow64GetThreadContext', 'SetConsoleCtrlHandler', 'WinVerifyTrust', 'GlobalAlloc', 'GlobalFree', 'GlobalUnlock', 'GlobalLock', 'OpenClipboard', 'EmptyClipboard', 'CloseClipboard', 'SetClipboardData', 'GetClipboardData', 'EnumClipboardFormats', 'GetClipboardFormatNameA', 'GetClipboardFormatNameW', 'WinVerifyTrust', 'OpenProcessToken', 'OpenThreadToken', 'GetTokenInformation', 'SetTokenInformation', 'GetSidIdentifierAuthority', 'GetSidSubAuthority', 'GetSidSubAuthorityCount', 'DebugBreak', 'WaitForDebugEvent', 'ContinueDebugEvent', 'DebugActiveProcess', 'DebugActiveProcessStop', 'DebugSetProcessKillOnExit', 'DebugBreakProcess', 'GetProcessId', 'Wow64SetThreadContext', 'GetMappedFileNameW', 'GetMappedFileNameA', 'RtlInitString', 'RtlInitUnicodeString', 'RtlAnsiStringToUnicodeString', 'OpenEventA', 'OpenEventW', 'NtOpenEvent', 'NtAlpcConnectPort', 'NtAlpcSendWaitReceivePort', 'lstrcmpA', 'lstrcmpW', 'CreateFileMappingA', 'CreateFileMappingW', 'MapViewOfFile', 'OpenSCManagerA', 'OpenSCManagerW', 'EnumServicesStatusExA', 'EnumServicesStatusExW', 'EnumWindows', 'GetWindowTextA', 'GetWindowTextW', 'GetWindowModuleFileNameA', 'GetWindowModuleFileNameW', 'CryptCATAdminCalcHashFromFileHandle', 'CryptCATAdminEnumCatalogFromHash', 'CryptCATAdminAcquireContext', 'CryptCATCatalogInfoFromContext', 'CryptCATAdminReleaseCatalogContext', 'CryptCATAdminReleaseContext', 'GetLogicalDriveStringsA', 'GetLogicalDriveStringsW', 'GetVolumeInformationA', 'GetVolumeInformationW', 'GetVolumeNameForVolumeMountPointA', 'GetVolumeNameForVolumeMountPointW', 'GetDriveTypeA', 'GetDriveTypeW', 'QueryDosDeviceA', 'QueryDosDeviceW', 'NtQueryObject', 'DuplicateHandle'] +functions = ['ExitProcess', 'TerminateProcess', 'GetLastError', 'GetCurrentProcess', 'CreateFileA', 'CreateFileW', 'LdrLoadDll', 'NtQuerySystemInformation', 'NtQueryInformationProcess', 'NtQueryVirtualMemory', 'NtCreateThreadEx', 'NtQueryInformationThread', 'GetExitCodeThread', 'GetExitCodeProcess', 'VirtualAlloc', 'VirtualAllocEx', 'VirtualFree', 'VirtualFreeEx', 'VirtualProtect', 'VirtualQuery', 'VirtualQueryEx', 'GetModuleFileNameA', 'GetModuleFileNameW', 'CreateThread', 'CreateRemoteThread', 'VirtualProtect', 'CreateProcessA', 'CreateProcessW', 'GetThreadContext', 'NtGetContextThread', 'SetThreadContext', 'NtSetContextThread', 'OpenThread', 'OpenProcess', 'CloseHandle', 'ReadProcessMemory', 'NtWow64ReadVirtualMemory64', 'WriteProcessMemory', 'CreateToolhelp32Snapshot', 'Thread32First', 'Thread32Next', 'Process32First', 'Process32Next', 'Process32FirstW', 'Process32NextW', 'GetProcAddress', 'LoadLibraryA', 'LoadLibraryW', 'OpenProcessToken', 'LookupPrivilegeValueA', 'LookupPrivilegeValueW', 'AdjustTokenPrivileges', 'FindResourceA', 'FindResourceW', 'SizeofResource', 'LoadResource', 'LockResource', 'GetVersionExA', 'GetVersionExW', 'GetVersion', 'GetCurrentThread', 'GetCurrentThreadId', 'GetCurrentProcessorNumber', 'AllocConsole', 'FreeConsole', 'GetStdHandle', 'SetStdHandle', 'SetThreadAffinityMask', 'WriteFile', 'GetExtendedTcpTable', 'GetExtendedUdpTable', 'SetTcpEntry', 'AddVectoredContinueHandler', 'AddVectoredExceptionHandler', 'TerminateThread', 'ExitThread', 'RemoveVectoredExceptionHandler', 'ResumeThread', 'SuspendThread', 'WaitForSingleObject', 'GetThreadId', 'LoadLibraryExA', 'LoadLibraryExW', 'SymInitialize', 'SymFromName', 'SymLoadModuleEx', 'SymSetOptions', 'SymGetTypeInfo', 'DeviceIoControl', 'GetTokenInformation', 'RegOpenKeyExA', 'RegOpenKeyExW', 'RegGetValueA', 'RegGetValueW', 'RegCloseKey', 'Wow64DisableWow64FsRedirection', 'Wow64RevertWow64FsRedirection', 'Wow64EnableWow64FsRedirection', 'Wow64GetThreadContext', 'SetConsoleCtrlHandler', 'WinVerifyTrust', 'GlobalAlloc', 'GlobalFree', 'GlobalUnlock', 'GlobalLock', 'OpenClipboard', 'EmptyClipboard', 'CloseClipboard', 'SetClipboardData', 'GetClipboardData', 'EnumClipboardFormats', 'GetClipboardFormatNameA', 'GetClipboardFormatNameW', 'WinVerifyTrust', 'OpenProcessToken', 'OpenThreadToken', 'GetTokenInformation', 'SetTokenInformation', 'GetSidIdentifierAuthority', 'GetSidSubAuthority', 'GetSidSubAuthorityCount', 'DebugBreak', 'WaitForDebugEvent', 'ContinueDebugEvent', 'DebugActiveProcess', 'DebugActiveProcessStop', 'DebugSetProcessKillOnExit', 'DebugBreakProcess', 'GetProcessId', 'Wow64SetThreadContext', 'GetMappedFileNameW', 'GetMappedFileNameA', 'RtlInitString', 'RtlInitUnicodeString', 'RtlAnsiStringToUnicodeString', 'OpenEventA', 'OpenEventW', 'NtOpenEvent', 'NtAlpcConnectPort', 'NtAlpcSendWaitReceivePort', 'lstrcmpA', 'lstrcmpW', 'CreateFileMappingA', 'CreateFileMappingW', 'MapViewOfFile', 'OpenSCManagerA', 'OpenSCManagerW', 'EnumServicesStatusExA', 'EnumServicesStatusExW', 'EnumWindows', 'GetWindowTextA', 'GetWindowTextW', 'GetWindowModuleFileNameA', 'GetWindowModuleFileNameW', 'CryptCATAdminCalcHashFromFileHandle', 'CryptCATAdminEnumCatalogFromHash', 'CryptCATAdminAcquireContext', 'CryptCATCatalogInfoFromContext', 'CryptCATAdminReleaseCatalogContext', 'CryptCATAdminReleaseContext', 'GetLogicalDriveStringsA', 'GetLogicalDriveStringsW', 'GetVolumeInformationA', 'GetVolumeInformationW', 'GetVolumeNameForVolumeMountPointA', 'GetVolumeNameForVolumeMountPointW', 'GetDriveTypeA', 'GetDriveTypeW', 'QueryDosDeviceA', 'QueryDosDeviceW', 'NtQueryObject', 'DuplicateHandle', 'GetModuleBaseNameA', 'GetModuleBaseNameW', 'GetProcessImageFileNameA', 'GetProcessImageFileNameW'] # ExitProcess(uExitCode): ExitProcessPrototype = WINFUNCTYPE(VOID, UINT) @@ -693,3 +693,19 @@ NtQueryObjectParams = ((1, 'Handle'), (1, 'ObjectInformationClass'), (1, 'Object DuplicateHandlePrototype = WINFUNCTYPE(BOOL, HANDLE, HANDLE, HANDLE, LPHANDLE, DWORD, BOOL, DWORD) DuplicateHandleParams = ((1, 'hSourceProcessHandle'), (1, 'hSourceHandle'), (1, 'hTargetProcessHandle'), (1, 'lpTargetHandle'), (1, 'dwDesiredAccess'), (1, 'bInheritHandle'), (1, 'dwOptions')) +# GetModuleBaseNameA(hProcess, hModule, lpBaseName, nSize): +GetModuleBaseNameAPrototype = WINFUNCTYPE(DWORD, HANDLE, HMODULE, LPCSTR, DWORD) +GetModuleBaseNameAParams = ((1, 'hProcess'), (1, 'hModule'), (1, 'lpBaseName'), (1, 'nSize')) + +# GetModuleBaseNameW(hProcess, hModule, lpBaseName, nSize): +GetModuleBaseNameWPrototype = WINFUNCTYPE(DWORD, HANDLE, HMODULE, LPWSTR, DWORD) +GetModuleBaseNameWParams = ((1, 'hProcess'), (1, 'hModule'), (1, 'lpBaseName'), (1, 'nSize')) + +# GetProcessImageFileNameA(hProcess, lpImageFileName, nSize): +GetProcessImageFileNameAPrototype = WINFUNCTYPE(DWORD, HANDLE, LPCSTR, DWORD) +GetProcessImageFileNameAParams = ((1, 'hProcess'), (1, 'lpImageFileName'), (1, 'nSize')) + +# GetProcessImageFileNameW(hProcess, lpImageFileName, nSize): +GetProcessImageFileNameWPrototype = WINFUNCTYPE(DWORD, HANDLE, LPWSTR, DWORD) +GetProcessImageFileNameWParams = ((1, 'hProcess'), (1, 'lpImageFileName'), (1, 'nSize')) + diff --git a/windows/winobject.py b/windows/winobject.py index e63eabe..fd4c610 100644 --- a/windows/winobject.py +++ b/windows/winobject.py @@ -145,6 +145,18 @@ class System(object): res.append(utils.swallow_ctypes_copy(process_entry)) return res + @staticmethod + def enumerate_processes(): + process_entry = PROCESSENTRY32() + process_entry.dwSize = ctypes.sizeof(process_entry) + snap = winproxy.CreateToolhelp32Snapshot(windef.TH32CS_SNAPPROCESS, 0) + winproxy.Process32First(snap, process_entry) + res = [] + res.append(WinProcess._from_PROCESSENTRY32(process_entry)) + while winproxy.Process32Next(snap, process_entry): + res.append(WinProcess._from_PROCESSENTRY32(process_entry)) + return res + @staticmethod def enumerate_threads(): thread_entry = WinThread() @@ -159,9 +171,6 @@ class System(object): - - - class WinThread(THREADENTRY32, AutoHandle): """Represent a thread """ @utils.fixedpropety @@ -675,18 +684,33 @@ class CurrentProcess(Process): raise ValueError("Not a syswow process") return windows.syswow64.get_current_process_syswow_peb() -class WinProcess(PROCESSENTRY32, Process): +class WinProcess(Process): """A Process on the system""" - is_pythondll_injected = 0 - is_remote_slave_running = False + def __init__(self, pid=None, handle=None, name=None, ppid=None): + if pid is None and handle is None: + raise ValueError("Need at lead or to create a {0}".format(type(self).__name)) + + if pid is not None: self._pid = pid + if handle is not None: self._handle = handle + if name is not None: self._name = name + if ppid is not None: self._ppid = ppid + @staticmethod def _from_handle(handle): - pid = winproxy.GetProcessId(handle) - proc = [p for p in windows.system.processes if p.pid == pid][0] - proc._handle = handle - dbgprint("Process {0} from handle {1}".format(proc, hex(handle)), "HANDLE") - return proc + #pid = winproxy.GetProcessId(handle) + #proc = [p for p in windows.system.processes if p.pid == pid][0] + #proc._handle = handle + #dbgprint("Process {0} from handle {1}".format(proc, hex(handle)), "HANDLE") + return WinProcess(handle=handle) + + @classmethod + def _from_PROCESSENTRY32(cls, entry): + #print("_from_PROCESSENTRY32") + name = entry.szExeFile.decode() + pid = entry.th32ProcessID + ppid = entry.th32ParentProcessID + return WinProcess(pid=pid, name=name, ppid=ppid) @utils.fixedpropety @@ -695,7 +719,10 @@ class WinProcess(PROCESSENTRY32, Process): :type: :class:`str` """ - return self.szExeFile[:].decode() + buffer = ctypes.c_buffer(0x1024) + rsize = winproxy.GetProcessImageFileNameA(self.handle, buffer) + # GetProcessImageFileNameA returns the fullpath + return buffer[:49].decode().split("\\")[-1] @utils.fixedpropety def pid(self): @@ -703,7 +730,7 @@ class WinProcess(PROCESSENTRY32, Process): :type: :class:`int` """ - return self.th32ProcessID + return winproxy.GetProcessId(self.handle) @utils.fixedpropety def ppid(self): diff --git a/windows/winproxy.py b/windows/winproxy.py index c2b2ee2..775f0b3 100644 --- a/windows/winproxy.py +++ b/windows/winproxy.py @@ -517,30 +517,58 @@ def DuplicateHandle(hSourceProcessHandle, hSourceHandle, hTargetProcessHandle, l # TODO: might be in another DLL depending of version # Should handle this.. -@OptionalExport(Kernel32Proxy("GetMappedFileNameW")) -def GetMappedFileNameW(hProcess, lpv, lpFilename, nSize=None): + +def GetMappedFileNameWWrapper(hProcess, lpv, lpFilename, nSize=None): if nSize is None: nSize = ctypes.sizeof(lpFilename) return GetMappedFileNameW.ctypes_function(hProcess, lpv, lpFilename, nSize) +GetMappedFileNameW = OptionalExport(Kernel32Proxy("GetMappedFileNameW"))(GetMappedFileNameWWrapper) -@OptionalExport(Kernel32Proxy("GetMappedFileNameA")) -def GetMappedFileNameA(hProcess, lpv, lpFilename, nSize=None): + +def GetMappedFileNameAWrapper(hProcess, lpv, lpFilename, nSize=None): if nSize is None: nSize = ctypes.sizeof(lpFilename) return GetMappedFileNameA.ctypes_function(hProcess, lpv, lpFilename, nSize) +GetMappedFileNameA = OptionalExport(Kernel32Proxy("GetMappedFileNameA"))(GetMappedFileNameAWrapper) if GetMappedFileNameA is None: - @PsapiProxy("GetMappedFileNameW") - def GetMappedFileNameW(hProcess, lpv, lpFilename, nSize=None): - if nSize is None: - nSize = ctypes.sizeof(lpFilename) - return GetMappedFileNameW.ctypes_function(hProcess, lpv, lpFilename, nSize) + GetMappedFileNameW = PsapiProxy("GetMappedFileNameW")(GetMappedFileNameWWrapper) + GetMappedFileNameA = PsapiProxy("GetMappedFileNameA")(GetMappedFileNameAWrapper) - @PsapiProxy("GetMappedFileNameA") - def GetMappedFileNameA(hProcess, lpv, lpFilename, nSize=None): - if nSize is None: - nSize = ctypes.sizeof(lpFilename) - return GetMappedFileNameA.ctypes_function(hProcess, lpv, lpFilename, nSize) + +def GetModuleBaseNameAWrapper(hProcess, hModule, lpBaseName, nSize=None): + if nSize is None: + nSize = len(lpBaseName) + return GetModuleBaseNameAWrapper.ctypes_function(hProcess, hModule, lpBaseName, nSize) +GetModuleBaseNameA = OptionalExport(Kernel32Proxy("GetMappedFileNameA"))(GetModuleBaseNameAWrapper) + + +def GetModuleBaseNameWWrapper(hProcess, hModule, lpBaseName, nSize=None): + if nSize is None: + nSize = len(lpBaseName) + return GetModuleBaseNameWWrapper.ctypes_function(hProcess, hModule, lpBaseName, nSize) +GetModuleBaseNameA = OptionalExport(Kernel32Proxy("GetModuleBaseNameW"))(GetModuleBaseNameWWrapper) + +if GetModuleBaseNameA is None: + GetModuleBaseNameA = PsapiProxy("GetModuleBaseNameA")(GetModuleBaseNameAWrapper) + GetModuleBaseNameW = PsapiProxy("GetModuleBaseNameW")(GetModuleBaseNameWWrapper) + + +def GetProcessImageFileNameAWrapper(hProcess, lpImageFileName, nSize=None): + if nSize is None: + nSize = len(lpImageFileName) + return GetProcessImageFileNameAWrapper.ctypes_function(hProcess, lpImageFileName, nSize) +GetProcessImageFileNameA = OptionalExport(Kernel32Proxy("GetProcessImageFileNameA"))(GetProcessImageFileNameAWrapper) + +def GetProcessImageFileNameWWrapper(hProcess, lpImageFileName, nSize=None): + if nSize is None: + nSize = len(lpImageFileName) + return GetProcessImageFileNameWWrapper.ctypes_function(hProcess, lpImageFileName, nSize) +GetProcessImageFileNameW = OptionalExport(Kernel32Proxy("GetProcessImageFileNameW"))(GetProcessImageFileNameWWrapper) + +if GetProcessImageFileNameA is None: + GetProcessImageFileNameA = PsapiProxy("GetProcessImageFileNameA")(GetProcessImageFileNameAWrapper) + GetProcessImageFileNameW = PsapiProxy("GetProcessImageFileNameW")(GetProcessImageFileNameWWrapper) # Debug API