From 4b034fc0fe0996b770de939f8247718059e746a3 Mon Sep 17 00:00:00 2001 From: hakril Date: Mon, 6 Jan 2025 16:28:07 +0100 Subject: [PATCH] Add RpcClient with DCOM capabilities handling multiple versions (localthis/localthat) --- .../definitions/defines/combase.txt | 6 +- .../definitions/structures/combase.txt | 33 +++- .../combase_localthisthat_versions.txt | 132 +++++++++++-- tests/test_generated_def.py | 12 +- windows/generated_def/meta.py | 15 ++ windows/generated_def/windef.py | 3 + windows/generated_def/winstructs.py | 67 +++++-- windows/rpc/client.py | 178 ++++++++++++++++-- 8 files changed, 399 insertions(+), 47 deletions(-) diff --git a/ctypes_generation/definitions/defines/combase.txt b/ctypes_generation/definitions/defines/combase.txt index aa7d955..fba59b7 100644 --- a/ctypes_generation/definitions/defines/combase.txt +++ b/ctypes_generation/definitions/defines/combase.txt @@ -26,4 +26,8 @@ #define SORF_OXRES7 ( 0x400 ) #define SORF_OXRES8 ( 0x800 ) #define SORF_NULL ( 0 ) -#define SORF_NOPING ( 0x1000 ) \ No newline at end of file +#define SORF_NOPING ( 0x1000 ) + +#define UNIQUE_FLAG_PADDING 2 +#define MAINHDRSIG 0x414E554B +#define ENTRYHDRSIG 0x494E414E \ No newline at end of file diff --git a/ctypes_generation/definitions/structures/combase.txt b/ctypes_generation/definitions/structures/combase.txt index d3ebb4a..8bc099a 100644 --- a/ctypes_generation/definitions/structures/combase.txt +++ b/ctypes_generation/definitions/structures/combase.txt @@ -405,4 +405,35 @@ typedef struct tagORPCTHAT { typedef struct ORPCTHAT32 { ULONG flags; PVOID32 extensions; // tagORPC_EXTENT_ARRAY tagORPC_EXTENT_ARRAY -} ORPCTHAT32; \ No newline at end of file +} ORPCTHAT32; + +// From: com\ole32\com\dcomrem\chock.hxx +typedef struct +{ + ULONG size; // Number of extents. + ULONG reserved; // Must be zero. + ULONG unique; // Flag to indicate presence of unique_flag array. + ULONG rounded_size; // Actual number of extents. + ULONG unique_flag[UNIQUE_FLAG_PADDING]; // Flags to indicate presense of ORPC_EXTENTs +} WireExtentArray; + +typedef struct +{ + ULONG rounded_size; // Actual number of extents. + GUID id; // Extension identifier. + ULONG size; // Extension size. + + // byte data[]; // Extension data. +} WireExtent; + +typedef struct tagMainHeader +{ + ULONG Signature; + ULONG Version; + ULONG cPolicies; + ULONG cbBuffer; + ULONG cbSize; + LONG hr; + LONG hrServer; + LONG reserved; +} MainHeader; \ No newline at end of file diff --git a/ctypes_generation/definitions/structures/combase_localthisthat_versions.txt b/ctypes_generation/definitions/structures/combase_localthisthat_versions.txt index efadb7f..c784fc6 100644 --- a/ctypes_generation/definitions/structures/combase_localthisthat_versions.txt +++ b/ctypes_generation/definitions/structures/combase_localthisthat_versions.txt @@ -1,3 +1,94 @@ +/* Summary of seen version on combase symbols for LOCALTHIS: + +Nb fields: 2 +6.1.7601.17514 -> 6.2.9200.22376 + * 6.1.7601.17514 + * 6.1.7601.17514 + * 6.2.9200.22376 +Nb fields: 4 +6.3.9600.17031 -> 6.3.9600.20772 + * 6.3.9600.17031 + * 6.3.9600.20772 +Nb fields: 5 +10.0.10240.16384 -> 10.0.15063.2679 + * 10.0.10240.16384 + * 10.0.10240.20747 + * 10.0.10586.0 + * 10.0.14393.576 + * 10.0.14393.6451 + * 10.0.14393.7426 + * 10.0.15063.251 + * 10.0.15063.1563 + * 10.0.15063.2500 + * 10.0.15063.2679 +Nb fields: 7 +10.0.16299.1 -> 10.0.26100.2454 + * 10.0.16299.1 + * 10.0.16299.15 + * 10.0.17134.1 + * 10.0.17134.48 + * 10.0.17134.2145 + * 10.0.17134.2145 + * 10.0.17763.1 + * 10.0.17763.2931 + * 10.0.22621.2792 + * 10.0.22621.3958 + * 10.0.22621.4111 + * 10.0.22621.4541 + * 10.0.26100.2454 +*/ + +/* Summary of seen version on combase symbols for LOCALTHAT: + +Nb fields: 2 +6.3.9600.17031 -> 6.3.9600.20772 + * 6.3.9600.17031 + * 6.3.9600.17031 + * 6.3.9600.17031 + * 6.3.9600.20772 +Nb fields: 3 +10.0.18362.900 -> 10.0.18362.1916 + * 10.0.18362.900 + * 10.0.18362.900 + * 10.0.18362.1016 + * 10.0.18362.1916 +Nb fields: 4 +10.0.10240.16384 -> 10.0.17763.6040 + * 10.0.10240.16384 + * 10.0.10240.16384 + * 10.0.10240.20747 + * 10.0.10586.0 + * 10.0.14393.576 + * 10.0.14393.6451 + * 10.0.14393.7426 + * 10.0.15063.251 + * 10.0.15063.1563 + * 10.0.15063.2500 + * 10.0.15063.2679 + * 10.0.16299.1 + * 10.0.16299.15 + * 10.0.17134.1 + * 10.0.17134.48 + * 10.0.17134.2145 + * 10.0.17134.2145 + * 10.0.17763.1 + * 10.0.17763.2931 + * 10.0.17763.6040 +Nb fields: 5 +10.0.19039.1 -> 10.0.26100.2454 + * 10.0.19039.1 + * 10.0.19041.84 + * 10.0.19041.4894 + * 10.0.22000.65 + * 10.0.22621.2792 + * 10.0.22621.3958 + * 10.0.22621.4111 + * 10.0.22621.4541 + * 10.0.26100.2454 + * 10.0.26100.2454 +*/ + + /* Seen on 6.2.9200.22376 (win8_ldr_escrow.180222-0941) */ /* also seen on previous version : XP / Win7 / Server 2012 */ @@ -6,7 +97,7 @@ typedef struct LOCALTHIS32_NT_62 { ULONG dwClientThread; }; -// NO LOCALTHAT for these previous version as far as 1 now +// NO LOCALTHAT for these previous version as far as I now /* Seen on 6.3.9600.17031 (winblue_gdr.140221-1952) */ @@ -39,18 +130,18 @@ typedef struct __MIDL_XmitDefs_0002_NT_1607 { typedef struct __MIDL_XmitDefs_0001_NT_1607 { _GUID asyncOperationId; - UINT32 oxidClientProcessNA; + UINT64 oxidClientProcessNA; _GUID originalClientLogicalThreadId; - UINT uClientCausalityTraceId; -}; + UINT64 uClientCausalityTraceId; +} MIDL_XmitDefs_0001_NT_1607; -typedef struct LOCALTHIS32_NT_1607 { +typedef struct _LOCALTHIS32_NT_1607 { ULONG dwFlags; ULONG dwClientThread; - __MIDL_XmitDefs_0001_NT_1607 asyncRequestBlock; + MIDL_XmitDefs_0001_NT_1607 asyncRequestBlock; ULONG reserved; - PVOID32 *pTouchedAstaArray; -}; + PVOID32 pTouchedAstaArray; +} LOCALTHIS32_NT_1607; typedef struct __MIDL_XmitDefs_0007 { INT pointOfFailure; @@ -58,19 +149,19 @@ typedef struct __MIDL_XmitDefs_0007 { ULONG sizeOfMarshaledErrorInfo; ULONG reserved; BYTE *pMarshaledErrorInfo; -}; +} MIDL_XmitDefs_0007; typedef struct __MIDL_XmitDefs_0005 { ULONG sizeOfMarshaledResults; ULONG reserved; BYTE *pMarshaledResults; -}; +} MIDL_XmitDefs_0005; typedef struct __MIDL_XmitDefs_0008 { INT outcome; - __MIDL_XmitDefs_0005 successDetails; - __MIDL_XmitDefs_0007 failureDetails; -}; + MIDL_XmitDefs_0005 successDetails; + MIDL_XmitDefs_0007 failureDetails; +} MIDL_XmitDefs_0008; typedef struct __MIDL_XmitDefs_0010 { ULONG asyncStatus; @@ -78,17 +169,28 @@ typedef struct __MIDL_XmitDefs_0010 { UINT64 uServerCausalityTraceId; ULONG reserved2; PVOID32 *pOutcomeDetails; //__MIDL_XmitDefs_0008 -}; +} MIDL_XmitDefs_0010; typedef struct LOCALTHAT32_NT_1607 { UINT64 marshalingSetAcknowledgmentOxid; UINT64 marshalingSetId; ULONG reserved; - PVOID32 *pAsyncResponseBlock; + PVOID32 pAsyncResponseBlock; }; /* ! NT_1607: combase 10.0.14393.576 */ + +/* */ + +/* Seen only in 10.0.18362 versions of combase */ + +typedef struct _LOCALTHAT32_10_1903 { + UINT64 marshalingSetId; + PVOID32 pAsyncResponseBlock; + PVOID32 containerPassthroughData; +} LOCALTHAT32_10_1903; + /* NT 10.22 ? seen on 10.0.22621.1 */ typedef struct _LOCALTHIS32 { diff --git a/tests/test_generated_def.py b/tests/test_generated_def.py index a522b9a..eb82906 100644 --- a/tests/test_generated_def.py +++ b/tests/test_generated_def.py @@ -156,4 +156,14 @@ def test_psid_from_to_string(): initial_str = "S-1-5-12345" sid = gdef.PSID.from_string(initial_str) assert str(sid) == initial_str - assert gdef.PSID.from_string(str(sid)) == sid \ No newline at end of file + assert gdef.PSID.from_string(str(sid)) == sid + +def test_MIDL_XmitDefs_0001_NT_1607(): + # First definition was broken + # 0:000> dt combase_32!__MIDL_XmitDefs_0001 + # +0x000 asyncOperationId : _GUID + # +0x010 oxidClientProcessNA : Uint8B + # +0x018 originalClientLogicalThreadId : _GUID + # +0x028 uClientCausalityTraceId : Uint8B + assert gdef.MIDL_XmitDefs_0001_NT_1607.originalClientLogicalThreadId.offset == 0x018 + assert gdef.MIDL_XmitDefs_0001_NT_1607.uClientCausalityTraceId.offset == 0x028 \ No newline at end of file diff --git a/windows/generated_def/meta.py b/windows/generated_def/meta.py index 90b2229..d107f4a 100644 --- a/windows/generated_def/meta.py +++ b/windows/generated_def/meta.py @@ -943,6 +943,7 @@ windef = {'ABOVE_NORMAL_PRIORITY_CLASS', 'DUPLICATE_SAME_ACCESS', 'DWORDLONG_MAX', 'DWORD_MAX', +'ENTRYHDRSIG', 'ERROR_AUTHENTICODE_DISALLOWED', 'ERROR_AUTHENTICODE_PUBLISHER_NOT_TRUSTED', 'ERROR_AUTHENTICODE_TRUSTED_PUBLISHER', @@ -1868,6 +1869,7 @@ windef = {'ABOVE_NORMAL_PRIORITY_CLASS', 'LPC_REQUEST', 'MAILSLOT_NO_MESSAGE', 'MAILSLOT_WAIT_FOREVER', +'MAINHDRSIG', 'MAXIMUM_ALLOWED', 'MAXIMUM_XSTATE_FEATURES', 'MAXLEN_IFDESCR', @@ -3164,6 +3166,7 @@ windef = {'ABOVE_NORMAL_PRIORITY_CLASS', 'TXFS_MINIVERSION_COMMITTED_VIEW', 'TXFS_MINIVERSION_DEFAULT_VIEW', 'TXFS_MINIVERSION_DIRTY_VIEW', +'UNIQUE_FLAG_PADDING', 'UNLOAD_DLL_DEBUG_EVENT', 'UNPROTECTED_DACL_SECURITY_INFORMATION', 'UNPROTECTED_SACL_SECURITY_INFORMATION', @@ -12544,6 +12547,7 @@ structs = {'ACCESS_ALLOWED_ACE', 'LOCALGROUP_MEMBERS_INFO_3', 'LOCALTHAT', 'LOCALTHAT32', +'LOCALTHAT32_10_1903', 'LOCALTHAT32_NT_1607', 'LOCALTHAT32_NT_63', 'LOCALTHIS', @@ -12694,9 +12698,15 @@ structs = {'ACCESS_ALLOWED_ACE', 'MIB_UDPTABLE_OWNER_PID', 'MIDL_ILocalObjectExporter_0007', 'MIDL_XmitDefs_0001', +'MIDL_XmitDefs_0001_NT_1607', +'MIDL_XmitDefs_0005', +'MIDL_XmitDefs_0007', +'MIDL_XmitDefs_0008', +'MIDL_XmitDefs_0010', 'MInterfacePointer', 'MODLOAD_DATA', 'MULTI_QI', +'MainHeader', 'Mem_Des_s', 'Mem_Large_Des_s', 'Mem_Large_Range_s', @@ -13542,6 +13552,8 @@ structs = {'ACCESS_ALLOWED_ACE', 'WSAPROTOCOLCHAIN', 'WSAPROTOCOL_INFOA', 'WSAPROTOCOL_INFOW', +'WireExtent', +'WireExtentArray', 'XSAVE_FORMAT_32', 'XSAVE_FORMAT_64', 'XSTATE_CONFIGURATION', @@ -13850,8 +13862,10 @@ structs = {'ACCESS_ALLOWED_ACE', '_LOCALGROUP_MEMBERS_INFO_3', '_LOCALTHAT', '_LOCALTHAT32', +'_LOCALTHAT32_10_1903', '_LOCALTHIS', '_LOCALTHIS32', +'_LOCALTHIS32_NT_1607', '_LSA_OBJECT_ATTRIBUTES', '_LSA_REFERENCED_DOMAIN_LIST', '_LSA_TRANSLATED_NAME', @@ -14135,6 +14149,7 @@ structs = {'ACCESS_ALLOWED_ACE', 'tagIDLDESC', 'tagMInterfacePointer', 'tagMULTI_QI', +'tagMainHeader', 'tagOBJREF', 'tagOBJREFDATA', 'tagORPCTHAT', diff --git a/windows/generated_def/windef.py b/windows/generated_def/windef.py index 6e197d1..561500e 100644 --- a/windows/generated_def/windef.py +++ b/windows/generated_def/windef.py @@ -169,6 +169,9 @@ SORF_OXRES7 = make_flag("SORF_OXRES7", ( 0x400 )) SORF_OXRES8 = make_flag("SORF_OXRES8", ( 0x800 )) SORF_NULL = make_flag("SORF_NULL", ( 0 )) SORF_NOPING = make_flag("SORF_NOPING", ( 0x1000 )) +UNIQUE_FLAG_PADDING = make_flag("UNIQUE_FLAG_PADDING", 2) +MAINHDRSIG = make_flag("MAINHDRSIG", 0x414E554B) +ENTRYHDRSIG = make_flag("ENTRYHDRSIG", 0x494E414E) CWCSTORAGENAME = make_flag("CWCSTORAGENAME", 32) STGM_DIRECT = make_flag("STGM_DIRECT", 0x00000000) STGM_TRANSACTED = make_flag("STGM_TRANSACTED", 0x00010000) diff --git a/windows/generated_def/winstructs.py b/windows/generated_def/winstructs.py index 67ab54f..109a94d 100644 --- a/windows/generated_def/winstructs.py +++ b/windows/generated_def/winstructs.py @@ -1563,6 +1563,37 @@ class ORPCTHAT32(Structure): ] +class WireExtentArray(Structure): + _fields_ = [ + ("size", ULONG), + ("reserved", ULONG), + ("unique", ULONG), + ("rounded_size", ULONG), + ("unique_flag", ULONG * (UNIQUE_FLAG_PADDING)), + ] + + +class WireExtent(Structure): + _fields_ = [ + ("rounded_size", ULONG), + ("id", GUID), + ("size", ULONG), + ] + + +class tagMainHeader(Structure): + _fields_ = [ + ("Signature", ULONG), + ("Version", ULONG), + ("cPolicies", ULONG), + ("cbBuffer", ULONG), + ("cbSize", ULONG), + ("hr", LONG), + ("hrServer", LONG), + ("reserved", LONG), + ] +MainHeader = tagMainHeader + class LOCALTHIS32_NT_62(Structure): _fields_ = [ ("dwFlags", ULONG), @@ -1605,21 +1636,21 @@ class __MIDL_XmitDefs_0002_NT_1607(Structure): class __MIDL_XmitDefs_0001_NT_1607(Structure): _fields_ = [ ("asyncOperationId", _GUID), - ("oxidClientProcessNA", UINT32), + ("oxidClientProcessNA", UINT64), ("originalClientLogicalThreadId", _GUID), - ("uClientCausalityTraceId", UINT), + ("uClientCausalityTraceId", UINT64), ] +MIDL_XmitDefs_0001_NT_1607 = __MIDL_XmitDefs_0001_NT_1607 - -class LOCALTHIS32_NT_1607(Structure): +class _LOCALTHIS32_NT_1607(Structure): _fields_ = [ ("dwFlags", ULONG), ("dwClientThread", ULONG), - ("asyncRequestBlock", __MIDL_XmitDefs_0001_NT_1607), + ("asyncRequestBlock", MIDL_XmitDefs_0001_NT_1607), ("reserved", ULONG), - ("pTouchedAstaArray", POINTER(PVOID32)), + ("pTouchedAstaArray", PVOID32), ] - +LOCALTHIS32_NT_1607 = _LOCALTHIS32_NT_1607 class __MIDL_XmitDefs_0007(Structure): _fields_ = [ @@ -1629,7 +1660,7 @@ class __MIDL_XmitDefs_0007(Structure): ("reserved", ULONG), ("pMarshaledErrorInfo", POINTER(BYTE)), ] - +MIDL_XmitDefs_0007 = __MIDL_XmitDefs_0007 class __MIDL_XmitDefs_0005(Structure): _fields_ = [ @@ -1637,15 +1668,15 @@ class __MIDL_XmitDefs_0005(Structure): ("reserved", ULONG), ("pMarshaledResults", POINTER(BYTE)), ] - +MIDL_XmitDefs_0005 = __MIDL_XmitDefs_0005 class __MIDL_XmitDefs_0008(Structure): _fields_ = [ ("outcome", INT), - ("successDetails", __MIDL_XmitDefs_0005), - ("failureDetails", __MIDL_XmitDefs_0007), + ("successDetails", MIDL_XmitDefs_0005), + ("failureDetails", MIDL_XmitDefs_0007), ] - +MIDL_XmitDefs_0008 = __MIDL_XmitDefs_0008 class __MIDL_XmitDefs_0010(Structure): _fields_ = [ @@ -1655,17 +1686,25 @@ class __MIDL_XmitDefs_0010(Structure): ("reserved2", ULONG), ("pOutcomeDetails", POINTER(PVOID32)), ] - +MIDL_XmitDefs_0010 = __MIDL_XmitDefs_0010 class LOCALTHAT32_NT_1607(Structure): _fields_ = [ ("marshalingSetAcknowledgmentOxid", UINT64), ("marshalingSetId", UINT64), ("reserved", ULONG), - ("pAsyncResponseBlock", POINTER(PVOID32)), + ("pAsyncResponseBlock", PVOID32), ] +class _LOCALTHAT32_10_1903(Structure): + _fields_ = [ + ("marshalingSetId", UINT64), + ("pAsyncResponseBlock", PVOID32), + ("containerPassthroughData", PVOID32), + ] +LOCALTHAT32_10_1903 = _LOCALTHAT32_10_1903 + class _LOCALTHIS32(Structure): _fields_ = [ ("dwFlags", DWORD), diff --git a/windows/rpc/client.py b/windows/rpc/client.py index c78324b..7016ab1 100644 --- a/windows/rpc/client.py +++ b/windows/rpc/client.py @@ -62,9 +62,26 @@ class ALPC_RPC_CALL(ctypes.Structure): ("orpc_ipid", gdef.GUID) ] +# Was an array of 6 DWORD, new class inspired by : +# https://github.com/googleprojectzero/sandbox-attacksurface-analysis-tools/blob/main/NtCoreLib/Win32/Rpc/Transport/Alpc/LRPC_IMMEDIATE_RESPONSE_MESSAGE.cs#L22 + +class ALPC_RPC_RESPONSE(ctypes.Structure): + _pack_ = 1 + _fields_ = [ + ("request_type", gdef.DWORD), + ("UNK1", gdef.DWORD), + ("flags",gdef.DWORD), + ("request_id", gdef.DWORD), + ("UNK2", gdef.DWORD), + ("UNK3", gdef.DWORD), + ] + class RPCClient(object): """A client for RPC-over-ALPC able to bind to interface and perform calls using NDR32 marshalling""" - REQUEST_IDENTIFIER = 0x11223344 + REQUEST_IDENTIFIER = 0x42424242 + # Used to recognize ORPC call we made + # thus we know the response contains a orpcthat & localthat + REQUEST_IDENTIFIER_ORPC = 0x43434343 def __init__(self, port): self.alpc_client = alpc.AlpcClient(port) #: The :class:`windows.alpc.AlpcClient` used to communicate with the server @@ -138,17 +155,15 @@ class RPCClient(object): req.if_nb = interface_nb req.method_offset = method_offset if ipid: + req.request_id = self.REQUEST_IDENTIFIER_ORPC req.flags = 1 # We have a IPID req.orpc_ipid = ipid this = gdef.ORPCTHIS32() # we use NDR32 this.version = (5,7) this.flags = gdef.ORPCF_LOCAL - # Not mandatory - # this.cid = gdef.GUID.from_string("42424242-4242-4242-4242-424242424242") - lthis = gdef.LOCALTHIS32() # we use NDR32 - # RPC_E_INVALID_HEADER is NULL - lthis.callTraceActivity = gdef.GUID.from_string("42424242-4242-4242-4242-424242424242") - lthis.dwClientThread = windows.current_thread.tid + # Returned correct type with mandatory fields filed + lthis = find_correct_localthis_for_version() + print("lthis is : {0}".format(lthis)) return buffer(req)[:] + buffer(this)[:] + buffer(lthis)[:] + params return buffer(req)[:] + params @@ -188,17 +203,150 @@ class RPCClient(object): request_type = struct.unpack("= 0x48 # At least 0x20 of data - rpcdatasize = struct.unpack("= rpcdatasize - return windows.current_process.read_memory(viewattr.ViewBase, rpcdatasize) \ No newline at end of file + data = response.data[ctypes.sizeof(ALPC_RPC_RESPONSE):] + else: + # Response in view M extract size from PORT_MESSAGE & read data from view + assert response.port_message.u1.s1.TotalLength >= 0x48 # At least 0x20 of data + rpcdatasize = struct.unpack("= rpcdatasize + data = windows.current_process.read_memory(viewattr.ViewBase, rpcdatasize) + if response_header.request_id == self.REQUEST_IDENTIFIER_ORPC: + # Parse & remove ORPC headers (orpcthat + LocalThat) + orpcthat = gdef.ORPCTHAT32.from_buffer_copy(data) + data = data[ctypes.sizeof(orpcthat):] + if orpcthat.extensions != 0: + print("Parsing extension !") + # Parse extension : code have not been tested a lot + write_array_extend = gdef.WireExtentArray.from_buffer_copy(data) + data = data[ctypes.sizeof(gdef.WireExtentArray):] + if write_array_extend.rounded_size != 2: + raise NotImplementedError("orpcthat.extensions: WireExtentArray.rounded_size != 2") + for value in write_array_extend.unique_flag: + if value != 0: + data = self._pass_wire_extend(data) + localthat_type = find_correct_localthat_for_version() + if localthat_type is not None: + localthat = localthat_type.from_buffer_copy(data) + # Check localthat pointers are empty + for field in ("pAsyncResponseBlock", "containerErrorInformation", "containerPassthroughData"): + if getattr(localthat, field, 0) != 0: + raise NotImplementedError("ORPC Response with localthat.{0} != 0".format(field)) + data = data[ctypes.sizeof(localthat):] + return data + + def _pass_wire_extend(self, data): + wire_extend = gdef.WireExtent.from_buffer_copy(data) + # We don't care -> jump over the size only + return data[ctypes.sizeof(gdef.WireExtent) + wire_extend.rounded_size:] + +# Based on combase.dll analysis + +# LOCALTHIS +# Nb fields: 2 +# 6.1.7601.17514 -> 6.2.9200.22376 +# * 6.1.7601.17514 +# * 6.1.7601.17514 +# * 6.2.9200.22376 +# Nb fields: 4 +# 6.3.9600.17031 -> 6.3.9600.20772 +# * 6.3.9600.17031 +# * 6.3.9600.20772 +# Nb fields: 5 +# 10.0.10240.16384 -> 10.0.15063.2679 +# Nb fields: 7 +# 10.0.16299.1 -> 10.0.26100.2454 + +def find_correct_localthis_for_version(): + vmaj, vmin = windows.system.version + if (vmaj, vmin) < (6, 1): + return None + if (vmaj, vmin) in ((6, 1), (6, 2)): + return gdef.LOCALTHIS32_NT_62(dwClientThread = windows.current_thread.tid) + elif (vmaj, vmin) == (6,3): + return gdef.LOCALTHIS32_NT_63(dwClientThread = windows.current_thread.tid) + assert vmaj == 10 + vnumber = windows.system.get_file_version(r"C:\windows\system32\combase.dll") + # Extract version number from combase + # as it was used to find the struct per version + build_number = int(vnumber.split(".")[2]) + if build_number <= 15063: + return gdef.LOCALTHIS32_NT_1607(dwClientThread = windows.current_thread.tid) + return gdef.LOCALTHIS32(callTraceActivity=gdef.GUID.from_string("42424242-4242-4242-4242-424242424242"), + dwClientThread = windows.current_thread.tid) + + +# LOCALTHAT +# Nb fields: 2 +# 6.3.9600.17031 -> 6.3.9600.20772 +# * 6.3.9600.17031 +# * 6.3.9600.17031 +# * 6.3.9600.17031 +# * 6.3.9600.20772 +# Nb fields: 3 +# 10.0.18362.900 -> 10.0.18362.1916 +# * 10.0.18362.900 +# * 10.0.18362.900 +# * 10.0.18362.1016 +# * 10.0.18362.1916 +# Nb fields: 4 +# 10.0.10240.16384 -> 10.0.17763.6040 +# * 10.0.10240.16384 +# * 10.0.10240.16384 +# * 10.0.10240.20747 +# * 10.0.10586.0 +# * 10.0.14393.576 +# * 10.0.14393.6451 +# * 10.0.14393.7426 +# * 10.0.15063.251 +# * 10.0.15063.1563 +# * 10.0.15063.2500 +# * 10.0.15063.2679 +# * 10.0.16299.1 +# * 10.0.16299.15 +# * 10.0.17134.1 +# * 10.0.17134.48 +# * 10.0.17134.2145 +# * 10.0.17134.2145 +# * 10.0.17763.1 +# * 10.0.17763.2931 +# * 10.0.17763.6040 +# Nb fields: 5 +# 10.0.19039.1 -> 10.0.26100.2454 +# * 10.0.19039.1 +# * 10.0.19041.84 +# * 10.0.19041.4894 +# * 10.0.22000.65 +# * 10.0.22621.2792 +# * 10.0.22621.3958 +# * 10.0.22621.4111 +# * 10.0.22621.4541 +# * 10.0.26100.2454 +# * 10.0.26100.2454 + +def find_correct_localthat_for_version(): + vmaj, vmin = windows.system.version + if (vmaj, vmin) < (6, 3): + return None + elif (vmaj, vmin) == (6,3): + return gdef.LOCALTHAT32_NT_63 + assert vmaj == 10 + vnumber = windows.system.get_file_version(r"C:\windows\system32\combase.dll") + # Extract version number from combase + # as it was used to find the struct per version + build_number = int(vnumber.split(".")[2]) + if build_number <= 17763: + return gdef.LOCALTHAT32_NT_1607 + elif build_number == 18362: + return gdef.LOCALTHAT32_10_1903 + elif build_number >= 19039: + return gdef.LOCALTHAT32 + raise NotImplementedError("Unknown LOCALTHAT32 structure for version {0}, please share me your combase.dll file".format(windows.system.versionstr)) \ No newline at end of file