diff --git a/samples/portmsg.py b/samples/portmsg.py new file mode 100644 index 0000000..c1addc8 --- /dev/null +++ b/samples/portmsg.py @@ -0,0 +1,92 @@ +""" +Print nt!_PORT_MESSAGE header and message dump +""" + +import sys +from pykd import * + +# LPC message type +LpcMessageType = { + 1 : "LPC_REQUEST", + 2 : "LPC_REPLY", + 3 : "LPC_DATAGRAM", + 4 : "LPC_LOST_REPLY", + 5 : "LPC_PORT_CLOSED", + 6 : "LPC_CLIENT_DIED", + 7 : "LPC_EXCEPTION", + 8 : "LPC_DEBUG_EVENT", + 9 : "LPC_ERROR_EVENT", + 10 : "LPC_CONNECTION_REQUEST" +} + +# diplay format type +DispFormatsLength = { + "a" : 1, "b" : 1, "yb": 1, + "w" : 2, "W" : 2, "u" : 2, + "d" : 4, "dc": 4, "yd": 4, "f" : 4, + "q" : 8, "D" : 8, + "p" : ptrSize(), "ps": ptrSize() +} + + +def PrintPortMesage(messageAddr, printFormat="b", use32=False, moduleName="nt"): + """ + Print _PORT_MESSAGE header and dump of message dump + + Usage: portmsg messageAddr, printFormat[=b], use32[=False], moduleName[=nt] + When: + messageAddr - address of port message + printFormat - string of display format ("d+printFormat"). + May be: a, b, yb, w, W, u, d, dc, yd, f, q, D, p, ps + Display formats overview: + <link cmd=\".shell -x rundll32 url.dll,FileProtocolHandler http://msdn.microsoft.com/en-us/library/ff542790(VS.85).aspx\">http://msdn.microsoft.com/en-us/library/ff542790(VS.85).aspx</link> + + use32 - use _PORT_MESSAGE32 (instead of _PORT_MESSAGE) structure (True or False) + moduleName - module name with _PORT_MESSAGE structure in symbols + """ + + messageTypeName = "_PORT_MESSAGE" + if (use32): + messageTypeName = "_PORT_MESSAGE32" + + messageHeader = typedVar(moduleName, messageTypeName, messageAddr) + if (None == messageHeader): + dprintln("ERROR: Getting (" + moduleName + "!" + messageTypeName + " *)(0x%x) failed" % messageAddr ) + return + + dprintln( "Data length : %3d (0x%02x)" % (messageHeader.u1.s1.DataLength, messageHeader.u1.s1.DataLength) ) + dprintln( "Total length : %3d (0x%02x)" % (messageHeader.u1.s1.TotalLength, messageHeader.u1.s1.TotalLength) ) + calcHeaderLen = messageHeader.u1.s1.TotalLength - messageHeader.u1.s1.DataLength + headerLen = sizeof(moduleName, messageTypeName) + if (calcHeaderLen != headerLen): + dprintln( "WARRING: calculated size (%2d (0x%02x)) of LPC-header does not match with symbols information (%2d (0x%02x))" % (calcHeaderLen, calcHeaderLen, headerLen, headerLen) ) + if (messageHeader.u2.s2.Type in LpcMessageType): + dprintln( "Message type : " + LpcMessageType[messageHeader.u2.s2.Type] ) + else: + dprintln( "Message type : %3d (0x%x)" % (messageHeader.u2.s2.Type, messageHeader.u2.s2.Type) ) + procFindStr = "<link cmd=\"!process 0x%x\">%d(0x%x)</link>" % (messageHeader.ClientId.UniqueProcess, messageHeader.ClientId.UniqueProcess, messageHeader.ClientId.UniqueProcess) + dprintln( "Client ID : process= " + procFindStr + ", thread= %d(0x%x)" % (messageHeader.ClientId.UniqueThread, messageHeader.ClientId.UniqueThread), True) + dprintln( "View/Callback : %d (0x%x)" % (messageHeader.ClientViewSize, messageHeader.ClientViewSize) ) + if (printFormat not in DispFormatsLength): + dprintln( "WARRING: Unknown (" + printFormat + ") diplay fromat. Use \"b\"" ) + printFormat = "b" + dataAddr = messageHeader.getAddress() + headerLen + printCommand = "d" + printFormat + " 0x%x" % dataAddr + dataCount = messageHeader.u1.s1.DataLength / DispFormatsLength[printFormat] + printCommand += " L 0x%x " % dataCount + dprintln( "<link cmd=\"" + printCommand + "\">Dump of message data:</link>", True ) + dprintln( dbgCommand(printCommand) ) + + +if __name__ == "__main__": + argc = len(sys.argv) + if (2 == argc): + PrintPortMesage(expr(sys.argv[1])) + elif (3 == argc): + PrintPortMesage(expr(sys.argv[1]), sys.argv[2]) + elif (4 == argc): + PrintPortMesage(expr(sys.argv[1]), sys.argv[2], sys.argv[3] == "True") + elif (5 == argc): + PrintPortMesage(expr(sys.argv[1]), sys.argv[2], sys.argv[3] == "True", sys.argv[4]) + else: + dprintln(PrintPortMesage.__doc__, True)