mirror of
https://github.com/hakril/PythonForWindows
synced 2026-06-08 14:31:45 +00:00
Add RpcClient with DCOM capabilities handling multiple versions (localthis/localthat)
This commit is contained in:
@@ -26,4 +26,8 @@
|
||||
#define SORF_OXRES7 ( 0x400 )
|
||||
#define SORF_OXRES8 ( 0x800 )
|
||||
#define SORF_NULL ( 0 )
|
||||
#define SORF_NOPING ( 0x1000 )
|
||||
#define SORF_NOPING ( 0x1000 )
|
||||
|
||||
#define UNIQUE_FLAG_PADDING 2
|
||||
#define MAINHDRSIG 0x414E554B
|
||||
#define ENTRYHDRSIG 0x494E414E
|
||||
@@ -405,4 +405,35 @@ typedef struct tagORPCTHAT {
|
||||
typedef struct ORPCTHAT32 {
|
||||
ULONG flags;
|
||||
PVOID32 extensions; // tagORPC_EXTENT_ARRAY tagORPC_EXTENT_ARRAY
|
||||
} ORPCTHAT32;
|
||||
} 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;
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
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
|
||||
@@ -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',
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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),
|
||||
|
||||
+163
-15
@@ -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("<I", response.data[:4])[0]
|
||||
if request_type == gdef.RPC_RESPONSE_TYPE_FAIL:
|
||||
error_code = struct.unpack("<5I", response.data)[2]
|
||||
raise ValueError("RPC Response error {0} ({1})".format(error_code, KNOWN_RPC_ERROR_CODE.get(error_code, error_code)))
|
||||
raise ValueError("RPC Response error {0} ({1!r})".format(error_code, KNOWN_RPC_ERROR_CODE.get(error_code, error_code)))
|
||||
return request_type
|
||||
|
||||
def _get_response_effective_data(self, response):
|
||||
"""Response is a `AlpcMessage` needed to handle response in message vs response in view"""
|
||||
response_header = ALPC_RPC_RESPONSE.from_buffer_copy(response.data)
|
||||
if not response.view_is_valid:
|
||||
# Reponse directly in PORT_MESSAGE
|
||||
return response.data[0x18:] # 4 * 6
|
||||
# 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("<I", response.data[0x18:0x1c])[0]
|
||||
viewattr = response.view_attribute
|
||||
assert viewattr.ViewSize >= rpcdatasize
|
||||
return windows.current_process.read_memory(viewattr.ViewBase, rpcdatasize)
|
||||
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("<I", response.data[0x18:0x1c])[0] # ctypes.sizeof(ALPC_RPC_RESPONSE)
|
||||
viewattr = response.view_attribute
|
||||
assert viewattr.ViewSize >= 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))
|
||||
Reference in New Issue
Block a user