From e99e3aa39db1bcf165f15911c4cdcdaac2c3c2df Mon Sep 17 00:00:00 2001 From: Clement Rouault Date: Fri, 11 Dec 2015 11:41:14 +0100 Subject: [PATCH] syswow 64bits stub are now generated :) --- TODO.txt | 2 + generated_def/winfuncs.py | 6 +- syswow64.py | 236 +++++++++++--------------------------- winobject.py | 14 ++- winproxy.py | 11 ++ 5 files changed, 93 insertions(+), 176 deletions(-) create mode 100644 TODO.txt diff --git a/TODO.txt b/TODO.txt new file mode 100644 index 0000000..96bbb1c --- /dev/null +++ b/TODO.txt @@ -0,0 +1,2 @@ +TODO: + - get thread context (clean code + 32<->64 compat) \ No newline at end of file diff --git a/generated_def/winfuncs.py b/generated_def/winfuncs.py index 92d3187..d67753e 100644 --- a/generated_def/winfuncs.py +++ b/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', 'NtQuerySystemInformation', 'NtQueryInformationProcess', 'NtQueryVirtualMemory', 'VirtualAlloc', 'VirtualAllocEx', 'VirtualFree', 'VirtualFreeEx', 'VirtualProtect', 'VirtualQuery', 'VirtualQueryEx', 'GetModuleFileNameA', 'GetModuleFileNameW', 'CreateThread', 'CreateRemoteThread', 'VirtualProtect', 'CreateProcessA', 'CreateProcessW', 'GetThreadContext', 'SetThreadContext', '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', 'SetConsoleCtrlHandler'] +functions = ['ExitProcess', 'TerminateProcess', 'GetLastError', 'GetCurrentProcess', 'CreateFileA', 'CreateFileW', 'NtQuerySystemInformation', 'NtQueryInformationProcess', 'NtQueryVirtualMemory', 'NtCreateThreadEx', 'VirtualAlloc', 'VirtualAllocEx', 'VirtualFree', 'VirtualFreeEx', 'VirtualProtect', 'VirtualQuery', 'VirtualQueryEx', 'GetModuleFileNameA', 'GetModuleFileNameW', 'CreateThread', 'CreateRemoteThread', 'VirtualProtect', 'CreateProcessA', 'CreateProcessW', 'GetThreadContext', 'SetThreadContext', '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', 'SetConsoleCtrlHandler'] # ExitProcess(uExitCode): ExitProcessPrototype = WINFUNCTYPE(VOID, UINT) @@ -41,6 +41,10 @@ NtQueryInformationProcessParams = ((1, 'ProcessHandle'), (1, 'ProcessInformation NtQueryVirtualMemoryPrototype = WINFUNCTYPE(NTSTATUS, HANDLE, PVOID, MEMORY_INFORMATION_CLASS, PVOID, SIZE_T, PSIZE_T) NtQueryVirtualMemoryParams = ((1, 'ProcessHandle'), (1, 'BaseAddress'), (1, 'MemoryInformationClass'), (1, 'MemoryInformation'), (1, 'MemoryInformationLength'), (1, 'ReturnLength')) +# NtCreateThreadEx(ThreadHandle, DesiredAccess, ObjectAttributes, ProcessHandle, lpStartAddress, lpParameter, CreateSuspended, dwStackSize, Unknown1, Unknown2, Unknown3): +NtCreateThreadExPrototype = WINFUNCTYPE(NTSTATUS, PHANDLE, ACCESS_MASK, LPVOID, HANDLE, LPTHREAD_START_ROUTINE, LPVOID, BOOL, DWORD, DWORD, DWORD, LPVOID) +NtCreateThreadExParams = ((1, 'ThreadHandle'), (1, 'DesiredAccess'), (1, 'ObjectAttributes'), (1, 'ProcessHandle'), (1, 'lpStartAddress'), (1, 'lpParameter'), (1, 'CreateSuspended'), (1, 'dwStackSize'), (1, 'Unknown1'), (1, 'Unknown2'), (1, 'Unknown3')) + # VirtualAlloc(lpAddress, dwSize, flAllocationType, flProtect): VirtualAllocPrototype = WINFUNCTYPE(LPVOID, LPVOID, SIZE_T, DWORD, DWORD) VirtualAllocParams = ((1, 'lpAddress'), (1, 'dwSize'), (1, 'flAllocationType'), (1, 'flProtect')) diff --git a/syswow64.py b/syswow64.py index a177a24..dbe272a 100644 --- a/syswow64.py +++ b/syswow64.py @@ -1,9 +1,12 @@ import struct import ctypes import codecs +import functools + import windows import windows.native_exec.simple_x64 as x64 from generated_def.winstructs import * +from windows.winproxy import NeededParameter, OptionalExport, NtdllProxy, error_ntstatus # Special code for syswow64 process CS_32bits = 0x23 @@ -23,7 +26,8 @@ dummy_jump = "\xea" + struct.pack("".format(self.winproxy_function.__name__, param_name)) + + if self.raw_call is None: + self.raw_call = generate_syswow64_call(self.winproxy_function) + return self.raw_call(*args) + setattr(python_proxy, "ctypes_function", perform_call) + return python_proxy + + +@Syswow64ApiProxy(windows.winproxy.NtCreateThreadEx) +def NtCreateThreadEx_32_to_64(ThreadHandle=None, DesiredAccess=0x1fffff, ObjectAttributes=0, ProcessHandle=NeededParameter, lpStartAddress=NeededParameter, lpParameter=NeededParameter, CreateSuspended=0, dwStackSize=0, Unknown1=0, Unknown2=0, Unknown3=0): + if ThreadHandle is None: + ThreadHandle = byref(HANDLE()) + return NtCreateThreadEx_32_to_64.ctypes_function(ThreadHandle, DesiredAccess, ObjectAttributes, ProcessHandle, lpStartAddress, lpParameter, CreateSuspended, dwStackSize, Unknown1, Unknown2, Unknown3) + + +ProcessBasicInformation = 0 +@Syswow64ApiProxy(windows.winproxy.NtQueryInformationProcess) +def NtQueryInformationProcess_32_to_64(ProcessHandle, ProcessInformationClass=ProcessBasicInformation, ProcessInformation=NeededParameter, ProcessInformationLength=0, ReturnLength=None): + if ProcessInformation is not None and ProcessInformationLength == 0: + ProcessInformationLength = ctypes.sizeof(ProcessInformation) + if type(ProcessInformation) == PROCESS_BASIC_INFORMATION: + ProcessInformation = byref(ProcessInformation) + if ReturnLength is None: + ReturnLength = byref(ULONG()) + return NtQueryInformationProcess_32_to_64.ctypes_function(ProcessHandle, ProcessInformationClass, ProcessInformation, ProcessInformationLength, ReturnLength) + + +@Syswow64ApiProxy(windows.winproxy.NtQueryVirtualMemory) +def NtQueryVirtualMemory_32_to_64(ProcessHandle, BaseAddress, MemoryInformationClass=MemoryBasicInformation, MemoryInformation=NeededParameter, MemoryInformationLength=0, ReturnLength=None): + if ReturnLength is None: + ReturnLength = byref(ULONG()) + if MemoryInformation is not None and MemoryInformationLength == 0: + MemoryInformationLength = ctypes.sizeof(MemoryInformation) + if type(MemoryInformation) == MEMORY_BASIC_INFORMATION64: + MemoryInformation = byref(MemoryInformation) + return NtQueryVirtualMemory_32_to_64.ctypes_function(ProcessHandle, BaseAddress, MemoryInformationClass, MemoryInformation, MemoryInformationLength, ReturnLength) diff --git a/winobject.py b/winobject.py index 926bd82..cd6628a 100644 --- a/winobject.py +++ b/winobject.py @@ -17,11 +17,13 @@ import windows.native_exec.simple_x64 as x64 from . import utils from windows.dbgprint import dbgprint from windows.generated_def.winstructs import * +from windows.generated_def.ntstatus import NtStatusException from .generated_def import windef import windows.pe_parse as pe_parse + class AutoHandle(object): """An abstract class that allow easy handle creation/destruction""" def _get_handle(self): @@ -215,9 +217,9 @@ class Process(AutoHandle): if windows.current_process.bitness == 32 and self.bitness == 64: res = MEMORY_BASIC_INFORMATION64() try: - v = windows.syswow64.NtQueryVirtualMemory_32_to_64(self, addr, res) - except WindowsError as e: - if e.winerror & 0xffffffff == 0XC000000D: + v = windows.syswow64.NtQueryVirtualMemory_32_to_64(ProcessHandle=self.handle, BaseAddress=addr, MemoryInformation=res) + except NtStatusException as e: + if e.code & 0xffffffff == 0XC000000D: raise winproxy.Kernel32Error("NtQueryVirtualMemory_32_to_64") raise return res @@ -451,7 +453,7 @@ class WinProcess(PROCESSENTRY32, Process): def create_thread(self, addr, param): """Create a remote thread""" if windows.current_process.bitness == 32 and self.bitness == 64: - return windows.syswow64.NtCreateThreadEx_32_to_64(self, addr, param) + return windows.syswow64.NtCreateThreadEx_32_to_64(ProcessHandle=self.handle, lpStartAddress=addr, lpParameter=param) return WinThread._from_handle(winproxy.CreateRemoteThread(hProcess=self.handle, lpStartAddress=addr, lpParameter=param)) def load_library(self, dll_path): @@ -471,7 +473,7 @@ class WinProcess(PROCESSENTRY32, Process): x = windows.remotectypes.transform_type_to_remote64bits(PROCESS_BASIC_INFORMATION) # Fuck-it <3 data = (ctypes.c_char * ctypes.sizeof(x))() - windows.syswow64.NtQueryInformationProcess_32_to_64(self, data, ctypes.sizeof(x)) + windows.syswow64.NtQueryInformationProcess_32_to_64(self.handle, ProcessInformation=data, ProcessInformationLength=ctypes.sizeof(x)) peb_offset = x.PebBaseAddress.offset peb_addr = struct.unpack("