From 59a0c933f9cbbfc0a7e52d5f013574eee4ef6342 Mon Sep 17 00:00:00 2001 From: Clement Rouault Date: Wed, 16 Sep 2015 10:10:49 +0200 Subject: [PATCH] Use OptionalExport for ntreadsyswow + add some function --- make.bat => doc/make.bat | 0 {source => doc/source}/conf.py | 0 {source => doc/source}/generated_doc.rst | 0 {source => doc/source}/index.rst | 0 {source => doc/source}/native_exec.rst | 0 {source => doc/source}/pe_parse.rst | 0 {source => doc/source}/rem_python.rst | 0 {source => doc/source}/test.rst | 0 {source => doc/source}/utils.rst | 0 generated_def/winfuncs.py | 15 +++++- k32testing.py | 58 ++++++++++++++++-------- 11 files changed, 52 insertions(+), 21 deletions(-) rename make.bat => doc/make.bat (100%) rename {source => doc/source}/conf.py (100%) rename {source => doc/source}/generated_doc.rst (100%) rename {source => doc/source}/index.rst (100%) rename {source => doc/source}/native_exec.rst (100%) rename {source => doc/source}/pe_parse.rst (100%) rename {source => doc/source}/rem_python.rst (100%) rename {source => doc/source}/test.rst (100%) rename {source => doc/source}/utils.rst (100%) diff --git a/make.bat b/doc/make.bat similarity index 100% rename from make.bat rename to doc/make.bat diff --git a/source/conf.py b/doc/source/conf.py similarity index 100% rename from source/conf.py rename to doc/source/conf.py diff --git a/source/generated_doc.rst b/doc/source/generated_doc.rst similarity index 100% rename from source/generated_doc.rst rename to doc/source/generated_doc.rst diff --git a/source/index.rst b/doc/source/index.rst similarity index 100% rename from source/index.rst rename to doc/source/index.rst diff --git a/source/native_exec.rst b/doc/source/native_exec.rst similarity index 100% rename from source/native_exec.rst rename to doc/source/native_exec.rst diff --git a/source/pe_parse.rst b/doc/source/pe_parse.rst similarity index 100% rename from source/pe_parse.rst rename to doc/source/pe_parse.rst diff --git a/source/rem_python.rst b/doc/source/rem_python.rst similarity index 100% rename from source/rem_python.rst rename to doc/source/rem_python.rst diff --git a/source/test.rst b/doc/source/test.rst similarity index 100% rename from source/test.rst rename to doc/source/test.rst diff --git a/source/utils.rst b/doc/source/utils.rst similarity index 100% rename from source/utils.rst rename to doc/source/utils.rst diff --git a/generated_def/winfuncs.py b/generated_def/winfuncs.py index 23aaf0a..86cda2f 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', 'GetLastError', 'GetCurrentProcess', 'CreateFileA', 'CreateFileW', 'NtQuerySystemInformation', 'VirtualAlloc', 'VirtualAllocEx', 'VirtualProtect', 'VirtualQuery', 'GetModuleFileNameA', 'GetModuleFileNameW', 'CreateThread', 'CreateRemoteThread', 'VirtualProtect', 'CreateProcessA', 'CreateProcessW', 'GetThreadContext', 'SetThreadContext', 'OpenThread', 'OpenProcess', 'CloseHandle', 'ReadProcessMemory', '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', 'GetStdHandle', 'SetStdHandle', 'SetThreadAffinityMask', 'WriteFile', 'GetExtendedTcpTable', 'GetExtendedUdpTable', 'SetTcpEntry', 'AddVectoredContinueHandler', 'AddVectoredExceptionHandler', 'TerminateThread', 'ExitThread', 'RemoveVectoredExceptionHandler', 'ResumeThread', 'SuspendThread', 'WaitForSingleObject', 'GetThreadId', 'LoadLibraryExA', 'LoadLibraryExW', 'SymInitialize', 'SymFromName', 'SymLoadModuleEx', 'SymSetOptions', 'SymGetTypeInfo', 'DeviceIoControl'] +functions = ['ExitProcess', 'GetLastError', 'GetCurrentProcess', 'CreateFileA', 'CreateFileW', 'NtQuerySystemInformation', 'VirtualAlloc', 'VirtualAllocEx', 'VirtualFree', 'VirtualFreeEx', 'VirtualProtect', 'VirtualQuery', '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', 'GetStdHandle', 'SetStdHandle', 'SetThreadAffinityMask', 'WriteFile', 'GetExtendedTcpTable', 'GetExtendedUdpTable', 'SetTcpEntry', 'AddVectoredContinueHandler', 'AddVectoredExceptionHandler', 'TerminateThread', 'ExitThread', 'RemoveVectoredExceptionHandler', 'ResumeThread', 'SuspendThread', 'WaitForSingleObject', 'GetThreadId', 'LoadLibraryExA', 'LoadLibraryExW', 'SymInitialize', 'SymFromName', 'SymLoadModuleEx', 'SymSetOptions', 'SymGetTypeInfo', 'DeviceIoControl'] # ExitProcess(uExitCode): ExitProcessPrototype = WINFUNCTYPE(VOID, UINT) @@ -37,6 +37,14 @@ VirtualAllocParams = ((1, 'lpAddress'), (1, 'dwSize'), (1, 'flAllocationType'), VirtualAllocExPrototype = WINFUNCTYPE(LPVOID, HANDLE, LPVOID, SIZE_T, DWORD, DWORD) VirtualAllocExParams = ((1, 'hProcess'), (1, 'lpAddress'), (1, 'dwSize'), (1, 'flAllocationType'), (1, 'flProtect')) +# VirtualFree(lpAddress, dwSize, dwFreeType): +VirtualFreePrototype = WINFUNCTYPE(BOOL, LPVOID, SIZE_T, DWORD) +VirtualFreeParams = ((1, 'lpAddress'), (1, 'dwSize'), (1, 'dwFreeType')) + +# VirtualFreeEx(hProcess, lpAddress, dwSize, dwFreeType): +VirtualFreeExPrototype = WINFUNCTYPE(BOOL, HANDLE, LPVOID, SIZE_T, DWORD) +VirtualFreeExParams = ((1, 'hProcess'), (1, 'lpAddress'), (1, 'dwSize'), (1, 'dwFreeType')) + # VirtualProtect(lpAddress, dwSize, flNewProtect, lpflOldProtect): VirtualProtectPrototype = WINFUNCTYPE(BOOL, LPVOID, SIZE_T, DWORD, PDWORD) VirtualProtectParams = ((1, 'lpAddress'), (1, 'dwSize'), (1, 'flNewProtect'), (1, 'lpflOldProtect')) @@ -97,6 +105,10 @@ CloseHandleParams = ((1, 'hObject'),) ReadProcessMemoryPrototype = WINFUNCTYPE(BOOL, HANDLE, LPCVOID, LPVOID, SIZE_T, POINTER(SIZE_T)) ReadProcessMemoryParams = ((1, 'hProcess'), (1, 'lpBaseAddress'), (1, 'lpBuffer'), (1, 'nSize'), (1, 'lpNumberOfBytesRead')) +# NtWow64ReadVirtualMemory64(hProcess, lpBaseAddress, lpBuffer, nSize, lpNumberOfBytesRead): +NtWow64ReadVirtualMemory64Prototype = WINFUNCTYPE(BOOL, HANDLE, ULONG64, LPVOID, ULONG64, POINTER(PULONG64)) +NtWow64ReadVirtualMemory64Params = ((1, 'hProcess'), (1, 'lpBaseAddress'), (1, 'lpBuffer'), (1, 'nSize'), (1, 'lpNumberOfBytesRead')) + # WriteProcessMemory(hProcess, lpBaseAddress, lpBuffer, nSize, lpNumberOfBytesWritten): WriteProcessMemoryPrototype = WINFUNCTYPE(BOOL, HANDLE, LPVOID, LPCVOID, SIZE_T, POINTER(SIZE_T)) WriteProcessMemoryParams = ((1, 'hProcess'), (1, 'lpBaseAddress'), (1, 'lpBuffer'), (1, 'nSize'), (1, 'lpNumberOfBytesWritten')) @@ -300,3 +312,4 @@ SymGetTypeInfoParams = ((1, 'hProcess'), (1, 'ModBase'), (1, 'TypeId'), (1, 'Get # DeviceIoControl(hDevice, dwIoControlCode, lpInBuffer, nInBufferSize, lpOutBuffer, nOutBufferSize, lpBytesReturned, lpOverlapped): DeviceIoControlPrototype = WINFUNCTYPE(BOOL, HANDLE, DWORD, LPVOID, DWORD, LPVOID, DWORD, LPDWORD, LPOVERLAPPED) DeviceIoControlParams = ((1, 'hDevice'), (1, 'dwIoControlCode'), (1, 'lpInBuffer'), (1, 'nInBufferSize'), (1, 'lpOutBuffer'), (1, 'nOutBufferSize'), (1, 'lpBytesReturned'), (1, 'lpOverlapped')) + diff --git a/k32testing.py b/k32testing.py index 722f731..f54378f 100644 --- a/k32testing.py +++ b/k32testing.py @@ -5,6 +5,7 @@ from ctypes.wintypes import * from windows.generated_def.winstructs import * from windows.generated_def.windef import * import windows.generated_def.winfuncs as winfuncs +from windows.dbgprint import dbgprint kernel32 = ctypes.windll.kernel32 @@ -46,19 +47,19 @@ class IphlpapiError(Kernel32Error): def no_error_check(func_name, result, func, args): """Nothing special""" return args - + def minus_one_error_check(func_name, result, func, args): if result == -1: raise Kernel32Error(func_name) return args - + def kernel32_error_check(func_name, result, func, args): """raise Kernel32Error if result is 0""" if not result: raise Kernel32Error(func_name) return args - + def kernel32_zero_check(func_name, result, func, args): """raise Kernel32Error if result is NOT 0""" if result: @@ -71,6 +72,12 @@ def iphlpapi_error_check(func_name, result, func, args): raise IphlpapiError(func_name, result) return args +class ExportNotFound(AttributeError): + def __init__(self, func_name, api_name): + self.func_name = func_name + self.api_name = api_name + super(ExportNotFound, self).__init__("Function {0} not found into {1}".format(func_name, api_name)) + # Design 1 class ApiProxy(object): APIDLL = None @@ -84,7 +91,10 @@ class ApiProxy(object): def __call__(self, python_proxy, ): prototype = getattr(winfuncs, self.func_name + "Prototype") params = getattr(winfuncs, self.func_name + "Params") - c_prototyped = prototype((self.func_name, self.APIDLL), params) + try: + c_prototyped = prototype((self.func_name, self.APIDLL), params) + except AttributeError: + raise ExportNotFound(self.func_name, self.APIDLL._name) c_prototyped.errcheck = self.error_check if (self.error_check.__doc__): doc = python_proxy.__doc__ @@ -115,16 +125,16 @@ class Advapi32Proxy(ApiProxy): class IphlpapiProxy(ApiProxy): APIDLL = iphlpapi default_error_check = staticmethod(iphlpapi_error_check) - + class NtdllProxy(ApiProxy): APIDLL = ntdll - default_error_check = staticmethod(kernel32_error_check) - + default_error_check = staticmethod(kernel32_zero_check) + class OptionalExport(object): """used 'around' a Proxy decorator Should be used for export that are not available everywhere (ntdll internals | 32/64 bits stuff) If the export is not found the function will be None - + Example: @OptionalExport(NtdllProxy('NtWow64ReadVirtualMemory64')) def NtWow64ReadVirtualMemory64(...) @@ -132,13 +142,12 @@ class OptionalExport(object): """ def __init__(self, subdecorator): self.subdecorator = subdecorator - + def __call__(self, f): try: return self.subdecorator(f) - except AttributeError as e: - print("NOT FOUND") - print(e) + except ExportNotFound as e: + dbgprint("Export <{e.func_name}> not found in <{e.api_name}>".format(e=e), "EXPORTNOTFOUND") return None def TransparentApiProxy(APIDLL, func_name, error_check): @@ -164,7 +173,7 @@ class NeededParameterType(object): def __repr__(self): return "NeededParameter" - + NeededParameter = NeededParameterType() @@ -198,10 +207,18 @@ def CreateFileA(lpFileName, dwDesiredAccess, dwShareMode=0, lpSecurityAttributes def VirtualAlloc(lpAddress=0, dwSize=NeededParameter, flAllocationType=MEM_COMMIT, flProtect=PAGE_EXECUTE_READWRITE): return VirtualAlloc.ctypes_function(lpAddress, dwSize, flAllocationType, flProtect) +@Kernel32Proxy("VirtualFree") +def VirtualFree(lpAddress, dwSize=0, dwFreeType=MEM_RELEASE): + return VirtualFree.ctypes_function(lpAddress, dwSize, dwFreeType) + @Kernel32Proxy("VirtualAllocEx") def VirtualAllocEx(hProcess, lpAddress=0, dwSize=NeededParameter, flAllocationType=MEM_COMMIT, flProtect=PAGE_EXECUTE_READWRITE): return VirtualAllocEx.ctypes_function(hProcess, lpAddress, dwSize, flAllocationType, flProtect) +@Kernel32Proxy("VirtualFreeEx") +def VirtualFreeEx(hProcess, lpAddress, dwSize=0, dwFreeType=MEM_RELEASE): + return VirtualFreeEx.ctypes_function(hProcess, lpAddress, dwSize, dwFreeType) + @Kernel32Proxy("CreateThread") def CreateThread(lpThreadAttributes=None, dwStackSize=0, lpStartAddress=NeededParameter, lpParameter=NeededParameter, dwCreationFlags=0, lpThreadId=None): return CreateThread.ctypes_function(lpThreadAttributes, dwStackSize, lpStartAddress, lpParameter, dwCreationFlags, lpThreadId) @@ -315,7 +332,6 @@ def Process32Next(hSnapshot, lpte): return Process32Next.ctypes_function(hSnapshot, lpte) # File stuff - @Kernel32Proxy("WriteFile") def WriteFile(hFile, lpBuffer, nNumberOfBytesToWrite=None, lpNumberOfBytesWritten=None, lpOverlapped=None): if nNumberOfBytesToWrite is None: @@ -340,8 +356,8 @@ def RemoveVectoredExceptionHandler(Handler): @Kernel32Proxy("WaitForSingleObject", kernel32_zero_check) def WaitForSingleObject(hHandle, dwMilliseconds=INFINITE): return WaitForSingleObject.ctypes_function(hHandle, dwMilliseconds) - -@Kernel32Proxy("DeviceIoControl") + +@Kernel32Proxy("DeviceIoControl") def DeviceIoControl(hDevice, dwIoControlCode, lpInBuffer, nInBufferSize=None, lpOutBuffer=NeededParameter, nOutBufferSize=None, lpBytesReturned=None, lpOverlapped=None): if nInBufferSize is None: nInBufferSize = len(lpInBuffer) @@ -352,6 +368,12 @@ def DeviceIoControl(hDevice, dwIoControlCode, lpInBuffer, nInBufferSize=None, lp lpBytesReturned = ctypes.byref(DWORD()) return DeviceIoControl.ctypes_function(hDevice, dwIoControlCode, lpInBuffer, nInBufferSize, lpOutBuffer, nOutBufferSize, lpBytesReturned, lpOverlapped) +#### NTDLL ##### + +@OptionalExport(NtdllProxy('NtWow64ReadVirtualMemory64')) +def NtWow64ReadVirtualMemory64(hProcess, lpBaseAddress, lpBuffer, nSize, lpNumberOfBytesRead=None): + return NtWow64ReadVirtualMemory64.ctypes_function(hProcess, lpBaseAddress, lpBuffer, nSize, lpNumberOfBytesRead) + ###### ADVAPI32 ######## @@ -386,7 +408,3 @@ def GetExtendedTcpTable(pTcpTable, pdwSize=None, bOrder=True, ulAf=NeededParamet if pdwSize is None: ctypes.sizeof(pTcpTable) return GetExtendedTcpTable.ctypes_function(pTcpTable, pdwSize, bOrder, ulAf, TableClass, Reserved) - -# Design 2 -# Design 2 should use the automatics args -