Clean some rpc/alpc code + add ndr.NdrCString

This commit is contained in:
Clement Rouault
2017-06-07 11:45:11 +02:00
parent 4c8747b628
commit a13b287202
4 changed files with 30 additions and 19 deletions
+8 -7
View File
@@ -6,29 +6,30 @@ from windows.generated_def import LPC_CONNECTION_REQUEST, LPC_REQUEST
PORT_NAME = r"\RPC Control\YOLOPORT"
def alpc_server():
server = windows.alpc.AlpcServer(PORT_NAME)
server = windows.alpc.AlpcServer(PORT_NAME) # NtAlpcCreatePort
print("[SERV] PORT CREATED")
attrs, msg = server.wait_data()
attrs, msg = server.wait_data() # NtAlpcSendWaitReceivePort (send_msg = None)
print("[SERV] Message type = {0:#x}".format(msg.u2.s2.Type))
print("[SERV] Received data: <{0}>".format(msg.data))
if msg.u2.s2.Type & LPC_CONNECTION_REQUEST:
print("[SERV] Connection request")
msg.data = "WOKAY"
server.accept_connection(msg)
attrs, msg = server.wait_data()
server.accept_connection(msg) # NtAlpcAcceptConnectPort
attrs, msg = server.wait_data() # NtAlpcSendWaitReceivePort (send_msg = None)
print("[SERV] Received message")
print("[SERV] Message type = {0:#x}".format(msg.u2.s2.Type))
if msg.u2.s2.Type & LPC_REQUEST:
print("[SERV] ALPC request: <{0}>".format(msg.data))
server.reply(msg, "REQUEST '{0}' DONE".format(msg.data))
# Copy MessageId + NtAlpcSendWaitReceivePort
server.reply(msg, "REQUEST '{0}' DONE".format(msg.data))
def alpc_client():
client = windows.alpc.AlpcClient()
connect_response = client.connect_to_port(PORT_NAME, "COUCOU")
connect_response = client.connect_to_port(PORT_NAME, "COUCOU") # NtAlpcConnectPort
print("[CLIENT] Connected: {0}".format(connect_response.data))
print("[CLIENT] Send Message <POUET>")
attr, response = client.send_receive("POUET")
attr, response = client.send_receive("POUET") # NtAlpcSendWaitReceivePort
print("[CLIENT] Server response: <{0}>".format(response.data))
+9 -7
View File
@@ -143,13 +143,15 @@ class AlpcClient(object):
port_name = gn.UNICODE_STRING(utf16_len, utf16_len, raw_name)
obj_attr = gn.OBJECT_ATTRIBUTES()
obj_attr.Length = ctypes.sizeof(obj_attr)
obj_attr.RootDirectory = None
obj_attr.ObjectName = None
obj_attr.Attributes = 0
obj_attr.SecurityDescriptor = None
obj_attr.SecurityQualityOfService = None
# obj_attr = gn.OBJECT_ATTRIBUTES()
# obj_attr.Length = ctypes.sizeof(obj_attr)
# obj_attr.RootDirectory = None
# obj_attr.ObjectName = None
# obj_attr.Attributes = 0
# obj_attr.SecurityDescriptor = None
# obj_attr.SecurityQualityOfService = None
obj_attr = None
port_attr = gn.ALPC_PORT_ATTRIBUTES()
+3 -5
View File
@@ -48,8 +48,6 @@ KNOWN_RPC_ERROR_CODE = {
NOT_USED = 0xBAADF00D
# def dword_pack(*args):
# return "".join(struct.pack("<I", x) for x in args)
class RPCClient(object):
REQUEST_IDENTIFIER = 0x11223344
@@ -93,13 +91,13 @@ class RPCClient(object):
def _forge_bind_request(self, rawuuid, syntaxversion, requested_if_nb):
version_major, version_minor = syntaxversion
# TODO: flags
data = struct.pack("III16sHHIIIIIIIIII", REQUEST_TYPE_BIND, NOT_USED, NOT_USED, rawuuid, version_major, version_minor, NOT_USED, requested_if_nb, NOT_USED, NOT_USED ,NOT_USED, NOT_USED, NOT_USED, NOT_USED, NOT_USED, NOT_USED) # Fonctionne pour le BIND :D
data = struct.pack("III16sHHII8I", REQUEST_TYPE_BIND, NOT_USED, NOT_USED, rawuuid, version_major, version_minor, NOT_USED, requested_if_nb, *[NOT_USED] * 8)
return data
def _forge_call_request(self, interface_nb, method_offset, params):
# TODO: differents REQUEST_IDENTIFIER for each req ?
request = struct.pack("<16I", REQUEST_TYPE_CALL, NOT_USED, 0, self.REQUEST_IDENTIFIER, interface_nb, method_offset, NOT_USED, NOT_USED, NOT_USED, NOT_USED, NOT_USED, NOT_USED, NOT_USED, NOT_USED, NOT_USED, NOT_USED)
# TODO: what is this '0' ? (1 is also accepted) (flags ?)
request = struct.pack("<16I", REQUEST_TYPE_CALL, NOT_USED, 0, self.REQUEST_IDENTIFIER, interface_nb, method_offset, *[NOT_USED] * 10)
request += params
return request
+10
View File
@@ -75,6 +75,16 @@ class NdrWString(object):
result += data
return dword_pad(result)
class NdrCString(object):
@classmethod
def pack(cls, data):
if data is None:
return None
l = len(data)
result = struct.pack("<3I", l, 0, l)
result += data
return dword_pad(result)
# @classmethod
# def unpack(self, stream):
# maxcount, offset, count = stream.partial_unpack("<3I")