From 89006d96085ea048fa21026330777f8492230654 Mon Sep 17 00:00:00 2001 From: "SND\\kernelnet_cp" Date: Fri, 16 Oct 2015 09:32:07 +0000 Subject: [PATCH] [0.3.x] added : typeInfo.fieldOffset method ( get fieldOffset by field's index ) git-svn-id: https://pykd.svn.codeplex.com/svn@90847 9b283d60-5439-405e-af05-b73fd8c4d996 --- pykd-0.3-2013.sln | 7 ++ pykd/pymod.cpp | 2 + pykd/pytypeinfo.h | 6 ++ snippets/wfp.py | 174 ++++++++++++++++++++++++++++++++++ test/scripts/pykdtest.py | 6 +- test/scripts/pykdtest.pyproj | 5 +- test/scripts/targetprocess.py | 2 +- 7 files changed, 195 insertions(+), 7 deletions(-) create mode 100644 snippets/wfp.py diff --git a/pykd-0.3-2013.sln b/pykd-0.3-2013.sln index b7a894a..900819c 100644 --- a/pykd-0.3-2013.sln +++ b/pykd-0.3-2013.sln @@ -25,6 +25,13 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{D1F122 .nuget\NuGet.targets = .nuget\NuGet.targets EndProjectSection EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{D1F1222A-A12B-4FD7-91A0-0AB6393A3169}" + ProjectSection(SolutionItems) = preProject + .nuget\NuGet.Config = .nuget\NuGet.Config + .nuget\NuGet.exe = .nuget\NuGet.exe + .nuget\NuGet.targets = .nuget\NuGet.targets + EndProjectSection +EndProject Project("{888888A0-9F3D-457C-B088-3A5042F75D52}") = "pykdtest", "test\scripts\pykdtest.pyproj", "{3F0BE77E-19B0-4192-B432-44A25805BCB8}" ProjectSection(ProjectDependencies) = postProject {C4C45791-0201-4406-BC5C-A384B01E3BF5} = {C4C45791-0201-4406-BC5C-A384B01E3BF5} diff --git a/pykd/pymod.cpp b/pykd/pymod.cpp index 25fce2c..78caa01 100644 --- a/pykd/pymod.cpp +++ b/pykd/pymod.cpp @@ -682,6 +682,8 @@ BOOST_PYTHON_MODULE( pykd ) "Return offset of the static field" ) .def( "fieldOffset", TypeInfoAdapter::getElementOffset, "Return offset of the nonstatic field" ) + .def("fieldOffset", TypeInfoAdapter::getElementOffsetByIndex, + "Return offset of the nonstatic field by index") .def( "bitOffset", TypeInfoAdapter::getBitOffset, "Return bit field's offset" ) .def( "bitWidth", TypeInfoAdapter::getBitWidth, diff --git a/pykd/pytypeinfo.h b/pykd/pytypeinfo.h index 8495c28..290d5b3 100644 --- a/pykd/pytypeinfo.h +++ b/pykd/pytypeinfo.h @@ -84,6 +84,12 @@ struct TypeInfoAdapter : public kdlib::TypeInfo { return typeInfo.getElementOffset( name ); } + static kdlib::MEMOFFSET_32 getElementOffsetByIndex(kdlib::TypeInfo &typeInfo, size_t index) + { + AutoRestorePyState pystate; + return typeInfo.getElementOffset(index); + } + static std::wstring getElementName( kdlib::TypeInfo &typeInfo, size_t index ) { AutoRestorePyState pystate; diff --git a/snippets/wfp.py b/snippets/wfp.py new file mode 100644 index 0000000..d1b4d3a --- /dev/null +++ b/snippets/wfp.py @@ -0,0 +1,174 @@ + +import sys +import re + +from pykd import * + +fwpsLayer = typeInfo( "FWPS_BUILTIN_LAYERS_" ).asMap() +fwpsDataType = typeInfo( "FWP_DATA_TYPE_" ).asMap() +fwpDirection = typeInfo( "FWP_DIRECTION_" ).asMap() + +def printBlob( blob ): + bb = loadBytes( blob.data, blob.size ) + str = "\n" + + i = 0 + for b in bb: + str += " %02x" % b + i = ( i + 1 ) % 16 + if i == 0: str += "\n" + str += "\n" + + str += "As string: " + loadWStr(blob.data ) + str += "\n" + + return str + +def printArray16( array16 ): + return " ".join( [ "%02x"%v for v in array16.byteArray16 ] ) + +def printFwpsValue( value ): + return { + "FWP_UINT8" : lambda : "%#x" % value.uint8, + "FWP_UINT16" : lambda : "%#x" % value.uint16, + "FWP_UINT32" : lambda : "%#x" % value.uint32, + "FWP_UINT64" : lambda : "%#x" % value.uint64.deref(), + "FWP_INT8" : lambda : "%#x" % value.int8, + "FWP_INT16" : lambda : "%#x" % value.int16, + "FWP_INT32" : lambda : "%#x" % value.int32, + "FWP_INT64" : lambda : "%#x" % value.int64.deref(), + "FWP_BYTE_BLOB_TYPE" : lambda : printBlob( value.byteBlob.deref() ), + "FWP_BYTE_ARRAY16_TYPE" : lambda : printArray16( value.byteArray16.deref() ) + + }.get( fwpsDataType[ value.field("type") ], lambda : "---" )() + +def wfpFixedValues( addr ): + + dprintln( "FWPS_INCOMING_VALUES0:" ) + + inFixedValue = typedVar( "FWPS_INCOMING_VALUES0_", addr ) + + dprintln( " Layer: " + fwpsLayer[ inFixedValue.layerId ] ) + dprintln( " Value: %d" % inFixedValue.valueCount ) + + values = [ x.value for x in typedVarArray( int(inFixedValue.incomingValue), "FWPS_INCOMING_VALUE0_", inFixedValue.valueCount ) ] + + layerName = fwpsLayer[ inFixedValue.layerId ] + + discardRe = re.compile( '_DISCARD' ) + layerName = discardRe.sub( '', layerName, 1 ) + + layerRe = re.compile( 'LAYER' ) + fwpsFields = typeInfo( layerRe.sub( 'FIELDS', layerName, 1 ) + '_' ).asMap() + + for i in range( 0, len(values) ): + dprintln( " " + fwpsFields[ i ] ) + dprintln( " Type: " + fwpsDataType[ values[i].field("type") ] ) + dprintln( " Value: " + printFwpsValue( values[i] ) ) + +def printDiscardReason( discardReason ): + return "" + +def printBlobAsStr( blob ): + return loadWChars( blob.data, blob.size ) + +def printFwpsMetaValue( valueIndex, inMetaValues ): + + return { + 0x00000001 : lambda x: printDiscardReason( x.discardMetadata ), + 0x00000002 : lambda x: "%#x" % inMetaValues.flowHandle, + 0x00000004 : lambda x: "%#x" % inMetaValues.ipHeaderSize, + 0x00000008 : lambda x: printBlobAsStr( x.processPath.deref() ), + 0x00000010 : lambda x: "%#lx" % inMetaValues.token, + 0x00000020 : lambda x: "%#lx" % inMetaValues.processId, + 0x00000040 : lambda x: "%#x" % inMetaValues.flags, + 0x00000080 : lambda x: "%#lx" % inMetaValues.reserved, + 0x00000100 : lambda x: "%#x" % inMetaValues.sourceInterfaceIndex, + 0x00000200 : lambda x: "%#x" % inMetaValues.destinationInterfaceIndex, + 0x00000400 : lambda x: "%#x" % inMetaValues.transportHeaderSize, + 0x00000800 : lambda x: "%#x" % inMetaValues.compartmentId, + 0x00001000 : lambda x: "id: %x offset: %x length: %x" % ( x.fragmentMetadata.fragmentIdentification, x.fragmentMetadata.fragmentOffset, x.fragmentMetadata.fragmentLength ), + 0x00002000 : lambda x: "%#x" % x.pathMtu, + 0x00004000 : lambda x: "%#lx" % x.completionHandle, + 0x00008000 : lambda x: "%#lx" % x.transportEndpointHandle, + 0x00010000 : lambda x: "Data: %#lx, Length: %#x" % ( x.controlData, x.controlDataLength ), + 0x00020000 : lambda x: "Zone: %d Level: %d" % ( x.remoteScopeId.Zone, x.remoteScopeId.Level ), + 0x00040000 : lambda x: fwpDirection[ x.packetDirection ], + }.get( valueIndex, lambda x: "" )( inMetaValues ) + + +def wfpMetaValues( addr ): + + dprintln( "FWPS_INCOMING_METADATA_VALUES0:" ) + + fwpsMetadataFields = { + 0x00000001 : "FWPS_METADATA_FIELD_DISCARD_REASON", + 0x00000002 : "FWPS_METADATA_FIELD_FLOW_HANDLE", + 0x00000004 : "FWPS_METADATA_FIELD_IP_HEADER_SIZE", + 0x00000008 : "FWPS_METADATA_FIELD_PROCESS_PATH", + 0x00000010 : "FWPS_METADATA_FIELD_TOKEN", + 0x00000020 : "FWPS_METADATA_FIELD_PROCESS_ID", + 0x00000040 : "FWPS_METADATA_FIELD_SYSTEM_FLAGS", + 0x00000080 : "FWPS_METADATA_FIELD_RESERVED", + 0x00000100 : "FWPS_METADATA_FIELD_SOURCE_INTERFACE_INDEX", + 0x00000200 : "FWPS_METADATA_FIELD_DESTINATION_INTERFACE_INDEX", + 0x00000400 : "FWPS_METADATA_FIELD_TRANSPORT_HEADER_SIZE", + 0x00000800 : "FWPS_METADATA_FIELD_COMPARTMENT_ID", + 0x00001000 : "FWPS_METADATA_FIELD_FRAGMENT_DATA", + 0x00002000 : "FWPS_METADATA_FIELD_PATH_MTU", + 0x00004000 : "FWPS_METADATA_FIELD_COMPLETION_HANDLE", + 0x00008000 : "FWPS_METADATA_FIELD_TRANSPORT_ENDPOINT_HANDLE", + 0x00010000 : "FWPS_METADATA_FIELD_TRANSPORT_CONTROL_DATA", + 0x00020000 : "FWPS_METADATA_FIELD_REMOTE_SCOPE_ID", + 0x00040000 : "FWPS_METADATA_FIELD_PACKET_DIRECTION", + 0x00080000 : "FWPS_METADATA_FIELD_PACKET_SYSTEM_CRITICAL", + 0x00100000 : "FWPS_METADATA_FIELD_FORWARD_LAYER_OUTBOUND_PASS_THRU", + 0x00200000 : "FWPS_METADATA_FIELD_FORWARD_LAYER_INBOUND_PASS_THRU", + 0x00400000 : "FWPS_METADATA_FIELD_ALE_CLASSIFY_REQUIRED", + 0x00800000 : "FWPS_METADATA_FIELD_TRANSPORT_HEADER_INCLUDE_HEADER", + 0x01000000 : "FWPS_METADATA_FIELD_DESTINATION_PREFIX", + 0x02000000 : "FWPS_METADATA_FIELD_ETHER_FRAME_LENGTH", + 0x04000000 : "FWPS_METADATA_FIELD_PARENT_ENDPOINT_HANDLE", + 0x08000000 : "FWPS_METADATA_FIELD_ICMP_ID_AND_SEQUENCE", + 0x10000000 : "FWPS_METADATA_FIELD_LOCAL_REDIRECT_TARGET_PID", + 0x20000000 : "FWPS_METADATA_FIELD_ORIGINAL_DESTINATION", + 0x40000000 : "FWPS_METADATA_FIELD_REDIRECT_RECORD_HANDLE", + 0x80000000 : "FWPS_METADATA_FIELD_SUB_PROCESS_TAG" + } + + inMetaValues = typedVar( "FWPS_INCOMING_METADATA_VALUES0_", addr ) + + for i in ( 1 << i for i in range( 0, 32) ): + if inMetaValues.currentMetadataValues & i: + dprint( " " ) + dprint( fwpsMetadataFields.get( i, "Unknown filed %#010x" % i ) + ": " ) + dprint( printFwpsMetaValue( i, inMetaValues ) ) + dprintln("") + + +def usage(): + dprintln( "Usage:" ) + dprintln( "!py wfp /fixed addr") + dprintln( "!py wfp /meta addr" ) + +def main(): + + if not isKernelDebugging(): + dprintln( "This script is for kernel debugging only" ) + + if len(sys.argv) < 2: + usage() + return + + if sys.argv[1]=="/fixed": + wfpFixedValues( expr(sys.argv[2]) ) + return + + if sys.argv[1]=="/meta": + wfpMetaValues( expr(sys.argv[2]) ) + return + + usage() + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/test/scripts/pykdtest.py b/test/scripts/pykdtest.py index c8466a5..0cf016d 100644 --- a/test/scripts/pykdtest.py +++ b/test/scripts/pykdtest.py @@ -71,9 +71,9 @@ def getTestSuite( singleName = "" ): else: return unittest.TestSuite( [ - unittest.TestLoader().loadTestsFromTestCase( StartProcessWithoutParamsTest ), + #unittest.TestLoader().loadTestsFromTestCase( StartProcessWithoutParamsTest ), unittest.TestLoader().loadTestsFromName( singleName ), - unittest.TestLoader().loadTestsFromTestCase( TerminateProcessTest ) + #unittest.TestLoader().loadTestsFromTestCase( TerminateProcessTest ) ] ) if __name__ == "__main__": @@ -85,5 +85,5 @@ if __name__ == "__main__": unittest.TextTestRunner(stream=sys.stdout, verbosity=2).run( getTestSuite() ) - # raw_input("Press ...") + raw_input("Press ...") diff --git a/test/scripts/pykdtest.pyproj b/test/scripts/pykdtest.pyproj index 3d04e9b..0708c66 100644 --- a/test/scripts/pykdtest.pyproj +++ b/test/scripts/pykdtest.pyproj @@ -13,12 +13,11 @@ pykdtest pykdtest Standard Python launcher - - + C:\proj\pykd-dev\out\x64\Debug\targetapp.exe - True + False False {9a7a9026-48c1-4688-9d5d-e5699d47d074} 2.7 diff --git a/test/scripts/targetprocess.py b/test/scripts/targetprocess.py index ff8c776..98fa74e 100644 --- a/test/scripts/targetprocess.py +++ b/test/scripts/targetprocess.py @@ -30,7 +30,7 @@ class ProcessTest(unittest.TestCase): def testEnumProcesses(self): processNumber = pykd.targetProcess.getNumber() for i in xrange(processNumber): - proc = pykd.targetProcess.getProcess(i) + proc = pykd.targetProcess(i) self.assertNotEqual(0, proc.systemID) self.assertNotEqual(0, proc.peb)