pykd/samples/rpcSrvIf.py

113 lines
4.1 KiB
Python
Raw Normal View History

"""
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('<exec cmd="dps 0x%x L 0x%x">Routine Table 0x%x, count %d (0x%02x)</exec>\n' %
(dspTable, dspTableSize, dspTable, dspTableSize, dspTableSize) ,True)
if __name__ == "__main__":
if len(sys.argv) == 2:
rpcSrvIf( expr(sys.argv[1]) )
else:
dprintln(rpcSrvIf.__doc__)