""" Prase first param RpcServerRegisterIf[Xxx] """ import sys from pykd import * def rpcSrvIf(ifSpec): """ Prase RPC server interface specification Usage example: kd> ba e 1 rpcrt4!RPC_SERVER::RegisterInterface kd> gc And analyze first parameter for x86: kd> !py rpcSrvIf poi(@esp+@$ptrsize) or for x64: kd> !py rpcSrvIf @rdx P.S. RPC_SERVER::RegisterInterface called from: RpcServerRegisterIf, RpcServerRegisterIf2 and RpcServerRegisterIfEx """ def formatSintaxId(synId): def formatGuid(guid): part1 = "%08x-%04x-%04x" % (guid.data1, guid.data2, guid.data3) part2 = "".join( ["%02x" % _byte for _byte in guid.data4] ) part3 = "".join( ["%02x" % _byte for _byte in guid.data5] ) return part1 + "-" + part2 + "-" + part3 def formatRpcVer(prcVer): return "v.%d.%d" % (prcVer.MajorVersion, prcVer.MinorVersion) return formatGuid(synId.SyntaxGUID) + " " + formatRpcVer(synId.SyntaxVersion) # WOW64 workaround: !!! workitem/9499 !!!! dynPtr = typeInfo("", "rpcSrvIf *") # prepare structures for parsing commGuid = typeInfo("rpcSrvIf~_GUID") commGuid.append(ulong_t, "data1") commGuid.append(ushort_t, "data2") commGuid.append(ushort_t, "data3") commGuid.append(uchar_t, "data4", 2) commGuid.append(uchar_t, "data5", 6) # print commGuid rpcVersion = typeInfo("rpcSrvIf~_RPC_VERSION") rpcVersion.append(ushort_t, "MajorVersion") rpcVersion.append(ushort_t, "MinorVersion") # print rpcVersion rpcSintaxIdentifier = typeInfo("rpcSrvIf~_RPC_SYNTAX_IDENTIFIER") rpcSintaxIdentifier.append(commGuid, "SyntaxGUID") rpcSintaxIdentifier.append(rpcVersion, "SyntaxVersion") # print rpcSintaxIdentifier prcDispatchTable = typeInfo("rpcSrvIf~_RPC_DISPATCH_TABLE") prcDispatchTable.append(uint_t, "DispatchTableCount") prcDispatchTable.append(dynPtr, "DispatchTable") prcDispatchTable.append(dynPtr, "Reserved") # print prcDispatchTable midlServerInfoHeader = typeInfo("rpcSrvIf~_MIDL_SERVER_INFO_hdr") midlServerInfoHeader.append(dynPtr, "pStubDesc") midlServerInfoHeader.append(dynPtr, "DispatchTable") # print midlServerInfoHeader rpcServerInterface = typeInfo("rpcSrvIf~_RPC_SERVER_INTERFACE") rpcServerInterface.append(uint_t, "Length") rpcServerInterface.append(rpcSintaxIdentifier, "InterfaceId") rpcServerInterface.append(rpcSintaxIdentifier, "TransferSyntax") rpcServerInterface.append(dynPtr, "DispatchTable") # -> prcDispatchTable rpcServerInterface.append(uint_t, "RpcProtseqEndpointCount") rpcServerInterface.append(dynPtr, "RpcProtseqEndpoint") rpcServerInterface.append(dynPtr, "DefaultManagerEpv") rpcServerInterface.append(dynPtr, "InterpreterInfo") # -> midlServerInfoHeader rpcServerInterface.append(uint_t, "Flags") # print rpcServerInterface # get and print interface header srvIf = rpcServerInterface.load( ifSpec ) dprintln("Interface ID : " + formatSintaxId(srvIf.InterfaceId) ) dprintln("Transfer Syntax : " + formatSintaxId(srvIf.TransferSyntax) ) dprintln("Endpoint count : %d" % srvIf.RpcProtseqEndpointCount ) if srvIf.RpcProtseqEndpointCount: protoseqEndp = srvIf.RpcProtseqEndpoint for i in range(0, srvIf.RpcProtseqEndpointCount): dprintln("\t[%02d] protocol is `" % i + loadCStr( ptrPtr(protoseqEndp) ) + "'" ) protoseqEndp += ptrSize() dprintln("\t[%02d] endpoint is `" % i + loadCStr( ptrPtr(protoseqEndp) ) + "'" ) protoseqEndp += ptrSize() dprintln("") # query dispatch routines table dspTableSize = prcDispatchTable.load(srvIf.DispatchTable).DispatchTableCount dspTable = midlServerInfoHeader.load(srvIf.InterpreterInfo).DispatchTable dprintln('Routine Table 0x%x, count %d (0x%02x)\n' % (dspTable, dspTableSize, dspTable, dspTableSize, dspTableSize) ,True) if __name__ == "__main__": if len(sys.argv) == 2: rpcSrvIf( expr(sys.argv[1]) ) else: dprintln(rpcSrvIf.__doc__)