From f682fbd8c196e865b16a9d0197f75cd6f950e62f Mon Sep 17 00:00:00 2001 From: hakril Date: Fri, 26 Jan 2018 11:05:53 +0100 Subject: [PATCH] Add transaction + window APIs to winproxy + get_mapped_filename raise on non-standard error (like aborted transaction) --- windows/winobject/process.py | 2 + windows/winobject/wmi.py | 2 +- windows/winproxy.py | 71 ++++++++++++++++++++++++++++++++++++ 3 files changed, 74 insertions(+), 1 deletion(-) diff --git a/windows/winobject/process.py b/windows/winobject/process.py index 2b5400c..0df85c7 100644 --- a/windows/winobject/process.py +++ b/windows/winobject/process.py @@ -571,6 +571,8 @@ class Process(AutoHandle): try: size = winproxy.GetMappedFileNameA(self.handle, addr, buffer, buffer_size) except winproxy.Kernel32Error as e: + if e.winerror != gdef.ERROR_UNEXP_NET_ERR: + raise # Raise if error type is not expected: detect mapped aborted transaction return None return buffer[:size] diff --git a/windows/winobject/wmi.py b/windows/winobject/wmi.py index b4dd9a0..1164c9e 100644 --- a/windows/winobject/wmi.py +++ b/windows/winobject/wmi.py @@ -93,7 +93,7 @@ class WmiRequester(object): result = enumerator.Next(timeout, 1, ctypes.byref(processor), ctypes.byref(count)) except WindowsError as e: if (e.winerror & 0xffffffff) == WBEM_E_INVALID_CLASS: - raise WindowsError(e.winerror, 'WBEM_E_INVALID_CLASS '.format(query)) + raise WindowsError(e.winerror, 'WBEM_E_INVALID_CLASS ') if (e.winerror & 0xffffffff) in WBEMSTATUS.values: raise WindowsError(e.winerror, WBEMSTATUS(e.winerror & 0xffffffff).value) raise diff --git a/windows/winproxy.py b/windows/winproxy.py index 0b2d62a..c6870ab 100644 --- a/windows/winproxy.py +++ b/windows/winproxy.py @@ -114,6 +114,11 @@ def error_ntstatus(func_name, result, func, args): raise NtStatusException(result & 0xffffffff) return args +def valid_handle_check(func_name, result, func, args): + if result == INVALID_HANDLE_VALUE: + raise Kernel32Error(func_name) + return args + class ExportNotFound(RuntimeError): def __init__(self, func_name, api_name): @@ -226,6 +231,10 @@ class Shell32Proxy(ApiProxy): APIDLL = "shell32" default_error_check = staticmethod(zero_is_fail_error_check) +class Ktmw32Proxy(ApiProxy): + APIDLL = "Ktmw32" + default_error_check = staticmethod(zero_is_fail_error_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) @@ -627,6 +636,7 @@ def QueryWorkingSetExWrapper(hProcess, pv, cb): QueryWorkingSetEx = Kernel32Proxy("QueryWorkingSetEx")(QueryWorkingSetExWrapper) + if not is_implemented(GetMappedFileNameA): GetMappedFileNameW = PsapiProxy("GetMappedFileNameW")(GetMappedFileNameWWrapper) GetMappedFileNameA = PsapiProxy("GetMappedFileNameA")(GetMappedFileNameAWrapper) @@ -1556,11 +1566,16 @@ def CryptUIDlgViewContext(dwContextType, pvContext, hwnd, pwszTitle, dwFlags, pv # ## User32 stuff ## # EnumWindows = TransparentUser32Proxy('EnumWindows') +EnumChildWindows = TransparentUser32Proxy('EnumChildWindows') +GetParent = TransparentUser32Proxy('GetParent') +GetClassInfoExA = TransparentUser32Proxy('GetClassInfoExA') +GetClassInfoExW = TransparentUser32Proxy('GetClassInfoExW') GetWindowTextA = TransparentUser32Proxy('GetWindowTextA', no_error_check) GetWindowTextW = TransparentUser32Proxy('GetWindowTextW', no_error_check) GetWindowModuleFileNameA = TransparentUser32Proxy('GetWindowModuleFileNameA', no_error_check) GetWindowModuleFileNameW = TransparentUser32Proxy('GetWindowModuleFileNameW', no_error_check) GetSystemMetrics = TransparentUser32Proxy('GetSystemMetrics', no_error_check) +GetWindowThreadProcessId = TransparentUser32Proxy('GetWindowThreadProcessId') @User32Proxy("GetCursorPos") def GetCursorPos(lpPoint): @@ -1583,6 +1598,30 @@ def MessageBoxA(hWnd=0, lpText=NeededParameter, lpCaption=None, uType=0): def MessageBoxW(hWnd=0, lpText=NeededParameter, lpCaption=None, uType=0): return MessageBoxW.ctypes_function(hWnd, lpText, lpCaption, uType) +@User32Proxy("RealGetWindowClassA") +def RealGetWindowClassA(hwnd, pszType, cchType=None): + if cchType is None: + cchType = len(pszType) + return RealGetWindowClassA.ctypes_function(hwnd, pszType, cchType) + +@User32Proxy("RealGetWindowClassW") +def RealGetWindowClassW(hwnd, pszType, cchType=None): + if cchType is None: + cchType = len(pszType) + return RealGetWindowClassW.ctypes_function(hwnd, pszType, cchType) + +@User32Proxy("GetClassNameA") +def GetClassNameA (hwnd, pszType, cchType=None): + if cchType is None: + cchType = len(pszType) + return GetClassNameA .ctypes_function(hwnd, pszType, cchType) + +@User32Proxy("GetClassNameW") +def GetClassNameW (hwnd, pszType, cchType=None): + if cchType is None: + cchType = len(pszType) + return GetClassNameW .ctypes_function(hwnd, pszType, cchType) + # ## Version stuff ## # @VersionProxy("GetFileVersionInfoA") @@ -1648,3 +1687,35 @@ def ShellExecuteA(hwnd, lpOperation, lpFile, lpParameters, lpDirectory, nShowCmd @Shell32Proxy('ShellExecuteW') def ShellExecuteW(hwnd, lpOperation, lpFile, lpParameters, lpDirectory, nShowCmd): return ShellExecuteW.ctypes_function(hwnd, lpOperation, lpFile, lpParameters, lpDirectory, nShowCmd) + + +# Transactions # + +@Kernel32Proxy("CreateFileTransactedA", error_check=valid_handle_check) +def CreateFileTransactedA(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile, hTransaction, pusMiniVersion, pExtendedParameter): + return CreateFileTransactedA.ctypes_function(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile, hTransaction, pusMiniVersion, pExtendedParameter) + +@Kernel32Proxy("CreateFileTransactedW", error_check=valid_handle_check) +def CreateFileTransactedW(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile, hTransaction, pusMiniVersion, pExtendedParameter): + return CreateFileTransactedW.ctypes_function(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile, hTransaction, pusMiniVersion, pExtendedParameter) + + +@Ktmw32Proxy("CommitTransaction") +def CommitTransaction(TransactionHandle): + return CommitTransaction.ctypes_function(TransactionHandle) + + +@Ktmw32Proxy("CreateTransaction") +def CreateTransaction(lpTransactionAttributes, UOW, CreateOptions, IsolationLevel, IsolationFlags, Timeout, Description): + return CreateTransaction.ctypes_function(lpTransactionAttributes, UOW, CreateOptions, IsolationLevel, IsolationFlags, Timeout, Description) + + +@Ktmw32Proxy("RollbackTransaction") +def RollbackTransaction(TransactionHandle): + return RollbackTransaction.ctypes_function(TransactionHandle) + + +@Ktmw32Proxy("OpenTransaction") +def OpenTransaction(dwDesiredAccess, TransactionId): + return OpenTransaction.ctypes_function(dwDesiredAccess, TransactionId) +