From 5e2ecf2af9c7947252f3f291c2ba580d6ce3b74e Mon Sep 17 00:00:00 2001 From: Clement Rouault Date: Thu, 6 Jul 2017 18:11:32 +0200 Subject: [PATCH] Still working on RPC over alpc --- windows/rpc/epmapper.py | 10 +++++--- windows/rpc/ndr.py | 54 ++++++++++++++++++++++++++++++++++++++++- 2 files changed, 59 insertions(+), 5 deletions(-) diff --git a/windows/rpc/epmapper.py b/windows/rpc/epmapper.py index ca8cf7e..85d52ab 100644 --- a/windows/rpc/epmapper.py +++ b/windows/rpc/epmapper.py @@ -118,7 +118,7 @@ def construct_alpc_tower(object, syntax, protseq, endpoint, address): towerarray = struct.pack("".format(targetiid), "RPC") + alpctowers = endpoint_map_alpc(targetiid, version, nb_response=50, sid=sid) + dbgprint("ALPC endpoints list: <{0}>".format(alpctowers), "RPC") for tower in alpctowers: dbgprint("Trying to connect to endpoint <{0}>".format(tower.endpoint), "RPC") alpc_port = r"\RPC Control\{0}".format(tower.endpoint) diff --git a/windows/rpc/ndr.py b/windows/rpc/ndr.py index 4c39c2f..d94120a 100644 --- a/windows/rpc/ndr.py +++ b/windows/rpc/ndr.py @@ -37,7 +37,15 @@ class NdrUniquePTR(object): return pack_dword(0) return pack_dword(0x02020202) + subpack + def unpack(self, stream): + ptr = NdrLong.unpack(stream) + if not ptr: + return None + return self.subcls.unpack(stream) + def pack_in_struct(self, data, id): + if data is None: + return pack_dword(0), None subpack = self.subcls.pack(data) if subpack is None: return pack_dword(0), None @@ -55,6 +63,16 @@ class NdrUniquePTR(object): return None return self.subcls.parse(stream) +class NdrFixedArray(object): + def __init__(self, subcls, size): + self.subcls = subcls + self.size = size + + def pack(self, data): + data = list(data) + assert len(data) == self.size + return dword_pad("".join([self.subcls.pack(elt) for elt in data])) + class NdrSID(object): @classmethod @@ -64,6 +82,11 @@ class NdrSID(object): sid_data = windows.current_process.read_memory(psid.value, size) return pack_dword(subcount[0]) + dword_pad(sid_data) + @classmethod + def unpack(cls, stream): + subcount = NdrLong.unpack(stream) + return stream.read(8 + (subcount * 4)) + class NdrWString(object): @classmethod def pack(cls, data): @@ -75,6 +98,15 @@ class NdrWString(object): result += data return dword_pad(result) + @classmethod + def unpack(cls, stream): + stream.align(4) + size1, zero, size2 = stream.partial_unpack("<3I") + assert size1 == size2 + assert zero == 0 + s = stream.read(size1 * 2) + return s.decode("utf-16-le") + class NdrCString(object): @classmethod def pack(cls, data): @@ -97,8 +129,28 @@ class NdrLong(object): @classmethod def unpack(self, stream): + stream.align(4) return stream.partial_unpack("