import struct from collections import namedtuple import windows import windows.generated_def as gdef from windows.rpc import ndr from windows.dbgprint import dbgprint from windows.pycompat import basestring class NdrTower(ndr.NdrStructure): MEMBERS = [ndr.NdrLong, ndr.NdrByteConformantArray] @classmethod def post_unpack(cls, data): size = data[0] tower = data[1] return bytearray(struct.pack(" len(unpacked[2]) # Parse towers return [explode_alpc_tower(obj) for obj in unpacked[2]] def find_alpc_endpoint_and_connect(targetiid, version=(1,0), sid=gdef.WinLocalSystemSid): """Ask the EPMapper for ALPC endpoints of ``targetiid:version`` and connect to one of them. :param str targetiid: The IID of the requested interface :param (int,int) version: The version requested interface :param WELL_KNOWN_SID_TYPE sid: The SID used to request the EPMapper :returns: A connected :class:`~windows.rpc.RPCClient` """ dbgprint("Finding ALPC endpoints for <{0}>".format(targetiid), "RPC") alpctowers = find_alpc_endpoints(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.decode()) try: client = windows.rpc.RPCClient(alpc_port) except Exception as e: dbgprint("Could not connect to endpoint <{0}>: {1}".format(tower.endpoint, e), "RPC") continue break else: raise ValueError("Could not find a valid endpoint for target <{0}> version <{1}>".format(targetiid, version)) dbgprint('Connected to ALPC port "{0}"'.format(alpc_port), "RPC") return client