13. windows.rpc – ALPC-based Windows RPC — PythonForWindows 1.0.4 documentation
The windows.rpc allows to perform the basic for MS-RPC:
find interface endpoints
connect to it
bind to interfaces
perform call
Marshall/Unmarshall NDR
13.1. RPCClient¶
- class windows.rpc.RPCClient(port)[source]¶
A client for RPC-over-ALPC able to bind to interface and perform calls using NDR32 marshalling
- alpc_client¶
The
windows.alpc.AlpcClientused to communicate with the server
- bind(iid, version=(1, 0))[source]¶
Bind to the
IIDwith the givenversion- Returns:
windows.generated_def.IID
- call(IID, method_offset, params, ipid=None)[source]¶
Call method number
method_offsetof interfaceIIDwith mashalledparams. Handle ORPC calls via the ipid parameter.- param IID IID:
An IID previously returned by
bind()- param int method_offset:
- param str params:
The mashalled parameters (NDR32)
- param GUID ipid:
The IPID for ORPC calls
- returns:
str
Note
Since 1.0.3 if the call is an ORPC call, the ORPCTHAT & LOCALTHAT present in the response are parsed and striped from the result.
13.2. Epmapper¶
- class windows.rpc.epmapper.UnpackTower(protseq, endpoint, address, object, syntax)¶
- address¶
Alias for field number 2
- endpoint¶
Alias for field number 1
- object¶
Alias for field number 3
- protseq¶
Alias for field number 0
- syntax¶
Alias for field number 4
13.2.1. find_alpc_endpoints()¶
- windows.rpc.find_alpc_endpoints(targetiid, version=(1, 0), nb_response=1, sid=_WELL_KNOWN_SID_TYPE.WinLocalSystemSid(0x16))[source]¶
Ask the EPMapper for ALPC endpoints of
targetiid:version(maximum ofnb_response)- Parameters:
targetiid (str) – The IID of the requested interface
version ((int,int)) – The version requested interface
nb_response (int) – The maximum number of response
sid (WELL_KNOWN_SID_TYPE) – The SID used to request the EPMapper
- Returns:
[
UnpackTower] – A list ofUnpackTower
Example:
>>> import windows.rpc >>> UAC_UIID = "201ef99a-7fa0-444c-9399-19ba84f12a1a" >>> windows.rpc.find_alpc_endpoints(UAC_UIID) [UnpackTower(protseq='ncalrpc', endpoint=bytearray(b'LRPC-c30c67fef2afa1612b'), address=None, object=<RPC_IF_ID "201EF99A-7FA0-444C-9399-19BA84F12A1A" (1, 0)>, syntax=<RPC_IF_ID "8A885D04-1CEB-11C9-9FE8-08002B104860" (2, 0)>)]
13.2.2. find_alpc_endpoint_and_connect()¶
- windows.rpc.find_alpc_endpoint_and_connect(targetiid, version=(1, 0), sid=_WELL_KNOWN_SID_TYPE.WinLocalSystemSid(0x16))[source]¶
Ask the EPMapper for ALPC endpoints of
targetiid:versionand connect to one of them.- Parameters:
targetiid (str) – The IID of the requested interface
version ((int,int)) – The version requested interface
sid (WELL_KNOWN_SID_TYPE) – The SID used to request the EPMapper
- Returns:
A connected
RPCClient
Example:
>>> import windows.rpc >>> UAC_UIID = "201ef99a-7fa0-444c-9399-19ba84f12a1a" >>> client = windows.rpc.find_alpc_endpoint_and_connect(UAC_UIID) >>> client <windows.rpc.client.RPCClient object at 0x046A1470> >>> client.alpc_client.port_name '\\RPC Control\\LRPC-c30c67fef2afa1612b' >>> iid = client.bind(UAC_UIID) >>> iid <IID "201EF99A-7FA0-444C-9399-19BA84F12A1A">
13.3. Ndr¶
The windows.rpc.ndr module offers some construction to help marshalling types and structures to NDR.
Note
The NDR supported for now is 8a885d04-1ceb-11c9-9fe8-08002b104860 version 2.0
Each NDR class has a function pack().
>>> import windows.generated_def as gdef >>> sid = windows.utils.get_known_sid(gdef.WinLocalSystemSid) >>> sid c_void_p(78304040) >>> psidstr = windows.rpc.ndr.NdrSID.pack(sid) >>> psidstr '\x01\x00\x00\x00\x01\x01\x00\x00\x00\x00\x00\x05\x12\x00\x00\x00' >>> windows.rpc.ndr.NdrSID.unpack(windows.rpc.ndr.NdrStream(psidstr)) # Implementation is partial for now and does not return a PSID but a string '\x01\x01\x00\x00\x00\x00\x00\x05\x12\x00\x00\x00'
>>> from windows.rpc import ndr >>> x = ndr.NdrWString.pack("Test-String\x00") >>> x '\x0c\x00\x00\x00\x00\x00\x00\x00\x0c\x00\x00\x00T\x00e\x00s\x00t\x00-\x00S\x00t\x00r\x00i\x00n\x00g\x00\x00\x00' >>> ndr.NdrWString.unpack(ndr.NdrStream(x)) u'Test-String\x00'
>>> from windows.rpc import ndr >>> x = ndr.NdrCString.pack("Test-String\x00") >>> x '\x0c\x00\x00\x00\x00\x00\x00\x00\x0c\x00\x00\x00Test-String\x00' # TODO: implem unpack
>>> from windows.rpc import ndr >>> x = ndr.NdrLong.pack(0x01020304) >>> x '\x04\x03\x02\x01' >>> hex(ndr.NdrLong.unpack(ndr.NdrStream(x))) '0x1020304'
>>> from windows.rpc import ndr >>> x = ndr.NdrHyper.pack(0x0102030405060708) >>> x '\x08\x07\x06\x05\x04\x03\x02\x01' >>> hex(ndr.NdrHyper.unpack(ndr.NdrStream(x))) '0x102030405060708L'
- class windows.rpc.ndr.NdrShort[source]¶
>>> from windows.rpc import ndr >>> x = ndr.NdrShort.pack(0x0102) >>> x '\x02\x01' >>> hex(ndr.NdrShort.unpack(ndr.NdrStream(x))) '0x102'
>>> from windows.rpc import ndr >>> x = ndr.NdrByte.pack(0x42) >>> x 'B' >>> hex(ndr.NdrByte.unpack(ndr.NdrStream(x))) '0x42'
>>> from windows.rpc import ndr >>> ndr.NdrLong.pack(0x11111111) '\x11\x11\x11\x11' >>> ndr.NdrUniquePTR(ndr.NdrLong).pack(0x11111111) '\x02\x02\x02\x02\x11\x11\x11\x11'
>>> windows.rpc.ndr.NdrLongConformantArray.pack([1,2,3,4]) '\x04\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x04\x00\x00\x00'
>>> windows.rpc.ndr.NdrByteConformantArray.pack([1,2,3,4]) '\x04\x00\x00\x00\x01\x02\x03\x04'
- class windows.rpc.ndr.NdrStructure[source]¶
a NDR structure that tries to respect the rules of pointer packing, this class should be subclassed with an attribute
MEMBERSdescribing the members of the class
>>> from windows.rpc import ndr >>> class NDRTest(ndr.NdrStructure): ... MEMBERS = [ndr.NdrLong, ndr.NdrLong, ndr.NdrWString] ... >>> x = NDRTest.pack([1, 2, "Test\x00"]) >>> x '\x01\x00\x00\x00\x02\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x05\x00\x00\x00T\x00e\x00s\x00t\x00\x00\x00PP' >>> NDRTest.unpack(ndr.NdrStream(x)) [1, 2, u'Test\x00']
- class windows.rpc.ndr.NdrParameters[source]¶
a class to pack NDR parameters together to performs RPC call, this class should be subclassed with an attribute
MEMBERSdescribing the members of the class
13.3.1. NDR STREAM¶
- class windows.rpc.ndr.NdrStream(data, use_memoryview=False)[source]¶
A stream of bytes used for NDR unpacking
>>> from windows.rpc import ndr >>> x = ndr.NdrStream("AAAABBBBCCCC") >>> hex(ndr.NdrLong.unpack(x)) '0x41414141' >>> x.data 'BBBBCCCC' >>> hex(ndr.NdrShort.unpack(x)) '0x4242' >>> x.data 'BBCCCC' >>> x.align(4) >>> x.data 'CCCC' >>> hex(ndr.NdrLong.unpack(x)) '0x43434343'