From 967dee7c12ec06b7cc131143c09b371a3b4b47c0 Mon Sep 17 00:00:00 2001 From: "SND\\kernelnet_cp" Date: Wed, 11 Sep 2013 08:09:27 +0000 Subject: [PATCH] [0.3.x] branch : km/samples git-svn-id: https://pykd.svn.codeplex.com/svn@85158 9b283d60-5439-405e-af05-b73fd8c4d996 --- pykd/memaccess.cpp | 45 ++++++++++++++++ pykd/memaccess.h | 4 ++ pykd/pykd.vcxproj | 1 + pykd/pykd.vcxproj.filters | 3 ++ pykd/pymod.cpp | 10 ++-- pykd/stladaptor.h | 2 + samples/km/__init__.py | 0 samples/km/drvobj.py | 110 ++++++++++++++++++++++++++++++++++++++ samples/km/proclist.py | 30 +++++++++++ samples/km/ssdt.py | 67 +++++++++++++++++++++++ 10 files changed, 267 insertions(+), 5 deletions(-) create mode 100644 pykd/memaccess.cpp create mode 100644 samples/km/__init__.py create mode 100644 samples/km/drvobj.py create mode 100644 samples/km/proclist.py create mode 100644 samples/km/ssdt.py diff --git a/pykd/memaccess.cpp b/pykd/memaccess.cpp new file mode 100644 index 0000000..02f3753 --- /dev/null +++ b/pykd/memaccess.cpp @@ -0,0 +1,45 @@ +#include "stdafx.h" + +#include "kdlib\exceptions.h" + +#include "memaccess.h" + +namespace pykd { + +/////////////////////////////////////////////////////////////////////////////// + +std::wstring loadUnicodeStr(kdlib::MEMOFFSET_64 offset) +{ + unsigned short length = kdlib::ptrWord( offset ); + unsigned short maximumLength = kdlib::ptrWord( offset + 2 ); + kdlib::MEMOFFSET_64 buffer = kdlib::ptrPtr( offset + kdlib::ptrSize() ); + + if ( maximumLength < length ) + throw kdlib::DbgException("Corrupted UNICODE_STRING structure"); + + if ( length == 0 ) + return std::wstring(); + + return kdlib::loadWChars( buffer, length/2 ); +} + +/////////////////////////////////////////////////////////////////////////////// + +std::string loadAnsiStr(kdlib::MEMOFFSET_64 offset) +{ + unsigned short length = kdlib::ptrWord( offset ); + unsigned short maximumLength = kdlib::ptrWord( offset + 2 ); + kdlib::MEMOFFSET_64 buffer = kdlib::ptrPtr( offset + kdlib::ptrSize() ); + + if ( maximumLength < length ) + throw kdlib::DbgException("Corrupted UNICODE_STRING structure"); + + if ( length == 0 ) + return std::string(); + + return kdlib::loadChars( buffer, length ); +} + +/////////////////////////////////////////////////////////////////////////////// + +}; // end pykd namespace diff --git a/pykd/memaccess.h b/pykd/memaccess.h index e246bf2..026615d 100644 --- a/pykd/memaccess.h +++ b/pykd/memaccess.h @@ -79,5 +79,9 @@ inline python::list loadPtrArray( kdlib::MEMOFFSET_64 offset, unsigned long cou return vectorToList( kdlib::loadPtrs(offset, count) ); } +std::wstring loadUnicodeStr(kdlib::MEMOFFSET_64 offset); + +std::string loadAnsiStr(kdlib::MEMOFFSET_64 offset); + } // end namespace pykd diff --git a/pykd/pykd.vcxproj b/pykd/pykd.vcxproj index 0486815..6d860c1 100644 --- a/pykd/pykd.vcxproj +++ b/pykd/pykd.vcxproj @@ -272,6 +272,7 @@ + Create diff --git a/pykd/pykd.vcxproj.filters b/pykd/pykd.vcxproj.filters index 8d44606..874c683 100644 --- a/pykd/pykd.vcxproj.filters +++ b/pykd/pykd.vcxproj.filters @@ -80,6 +80,9 @@ Source Files + + Source Files + diff --git a/pykd/pymod.cpp b/pykd/pymod.cpp index 877137e..9949bab 100644 --- a/pykd/pymod.cpp +++ b/pykd/pymod.cpp @@ -210,10 +210,10 @@ BOOST_PYTHON_MODULE( pykd ) "Load string from the target buffer containing 0-terminated ansi-string" ); python::def( "loadWStr", &kdlib::loadWStr, "Load string from the target buffer containing 0-terminated unicode-string" ); - //python::def( "loadUnicodeString", &loadUnicodeStr, - // "Return string represention of windows UNICODE_STRING type" ); - //python::def( "loadAnsiString", &loadAnsiStr, - // "Return string represention of windows ANSI_STRING type" ); + python::def( "loadUnicodeString", &loadUnicodeStr, + "Return string represention of windows UNICODE_STRING type" ); + python::def( "loadAnsiString", &loadAnsiStr, + "Return string represention of windows ANSI_STRING type" ); python::def( "loadFloats", &loadFloats, loadFloats_( python::args( "offset", "count", "phyAddr" ), "Read the block of the target's memory and return it as list of floats" ) ); python::def( "loadDoubles", &loadDoubles, loadDoubles_( python::args( "offset", "count", "phyAddr" ), @@ -738,4 +738,4 @@ BOOST_PYTHON_MODULE( pykd ) pykd::exception( "TypeException", "type exception" ); } -////////////////////////////////////////////////////////////////////////////////// \ No newline at end of file +////////////////////////////////////////////////////////////////////////////////// diff --git a/pykd/stladaptor.h b/pykd/stladaptor.h index b1b2158..887bc8b 100644 --- a/pykd/stladaptor.h +++ b/pykd/stladaptor.h @@ -8,6 +8,7 @@ namespace python = boost::python; namespace pykd { template +inline python::list vectorToList( const std::vector &v ) { python::list lst; for ( std::vector::const_iterator it = v.begin(); it != v.end(); ++it ) @@ -16,6 +17,7 @@ python::list vectorToList( const std::vector &v ) { } template<> +inline python::list vectorToList( const std::vector &v ) { python::list lst; for ( std::vector::const_iterator it = v.begin(); it != v.end(); ++it ) diff --git a/samples/km/__init__.py b/samples/km/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/samples/km/drvobj.py b/samples/km/drvobj.py new file mode 100644 index 0000000..f0e40d5 --- /dev/null +++ b/samples/km/drvobj.py @@ -0,0 +1,110 @@ +from pykd import * +import sys + + +def loadSymbols(): + global nt + nt = module( "nt" ) + +def getObjNameFromObjHeader( objHeader ): + + if hasattr( objHeader, "NameInfoOffset"): + objName = typedVar( "nt!_OBJECT_HEADER_NAME_INFO", objHeader.getAddress() - objHeader.NameInfoOffset ) + else: + if (0 == (objHeader.InfoMask & 2)): + return "" + + offsetNameInfo = ptrByte( nt.ObpInfoMaskToOffset + (objHeader.InfoMask & 3) ) + + if (0 == offsetNameInfo): + return "" + + objName = nt.typedVar("_OBJECT_HEADER_NAME_INFO", objHeader.getAddress() - offsetNameInfo) + + return loadUnicodeString( objName.Name.getAddress() ) + +def getObjTypeFromObjHeader( objHeader ): + + if hasattr( objHeader, "Type"): + return objHeader.Type + + return ptrPtr( nt.ObTypeIndexTable + ptrSize() * objHeader.TypeIndex ) + +def getObjectInDir( dirObj, objName ): + + if objName.find( "\\" ) != -1: + ( dirSubName, objSubName ) = objName.split("\\", 1) + else: + dirSubName = objName + + for i in range( 0, 37 ): + + if dirObj.HashBuckets[i] != 0: + dirEntry = typedVar( "nt!_OBJECT_DIRECTORY_ENTRY", dirObj.HashBuckets[i] ) + + while dirEntry != 0: + + objHeader = containingRecord( dirEntry.Object, "nt!_OBJECT_HEADER", "Body" ) + + objName = getObjNameFromObjHeader( objHeader ) + + if objName.lower() == dirSubName.lower(): + + if getObjTypeFromObjHeader( objHeader ) == ptrPtr( nt.ObpDirectoryObjectType ): + return getObjectInDir( typedVar( "nt!_OBJECT_DIRECTORY", dirEntry.Object), objSubName ) + else: + return dirEntry.Object + + if dirEntry.ChainLink != 0: + dirEntry = typedVar( "nt!_OBJECT_DIRECTORY_ENTRY", dirEntry.ChainLink ) + else: + dirEntry = 0 + + +def getObjectByName( objName ): + + if len(objName)==0: + return + + if objName[0] != '\\': + return + + rootDir = typedVar( "nt!_OBJECT_DIRECTORY", ptrPtr( nt.ObpRootDirectoryObject ) ) + + return getObjectInDir( rootDir, objName[1:] ) + + + +def printDrvMajorTable( drvName ): + + objName = "\\Driver\\" + drvName + drvObjPtr = getObjectByName( objName ) + + if drvObjPtr == None: + dprintln( "object not found" ) + return + + drvObj = typedVar( "nt!_DRIVER_OBJECT", drvObjPtr ) + + for i in range( len(drvObj.MajorFunction) ): + dprintln( "MajorFunction[%d] = %s" % ( i, findSymbol( drvObj.MajorFunction[i] ) ) ) + +def run(): + + if not isWindbgExt(): + if not loadDump( sys.argv[1] ): + dprintln( sys.argv[1] + " - load failed" ) + return + + if not isKernelDebugging(): + dprintln( "not a kernel debugging" ) + return + + loadSymbols(); + + printDrvMajorTable( "afd" ) + +if __name__ == "__main__": + run() + + diff --git a/samples/km/proclist.py b/samples/km/proclist.py new file mode 100644 index 0000000..9c55cc0 --- /dev/null +++ b/samples/km/proclist.py @@ -0,0 +1,30 @@ + +import sys +from pykd import * + +def processInfo(): + + nt = module( "nt" ) + + processList = typedVarList( nt.PsActiveProcessHead, "nt!_EPROCESS", "ActiveProcessLinks" ) + + for process in processList: + print "".join( [chr(i) for i in process.ImageFileName if i != 0] ) + +def run(): + + if not isWindbgExt(): + if not loadDump( sys.argv[1] ): + dprintln( sys.argv[1] + " - load failed" ) + return + + if not isKernelDebugging(): + dprintln( "not a kernel debugging" ) + return + + processInfo() + +if __name__ == "__main__": + run() + + diff --git a/samples/km/ssdt.py b/samples/km/ssdt.py new file mode 100644 index 0000000..32edd97 --- /dev/null +++ b/samples/km/ssdt.py @@ -0,0 +1,67 @@ +from pykd import * +import sys + +def checkSSDT(): + + nt = module( "nt" ) + + if is64bitSystem(): + + def getServiceAddrWlh(Start, Offset): + return Start + (Offset / 16) + + def getServiceAddr2k3(Start, Offset): + return Start + (Offset & ~0xf) + + if (ptrWord(nt.NtBuildNumber) == 3790): + getServiceAddr = getServiceAddr2k3 + else: + getServiceAddr = getServiceAddrWlh + + serviceTableHeader = loadQWords( nt.KeServiceDescriptorTable, 4 ) + serviceTableStart = serviceTableHeader[0] + serviceCount = serviceTableHeader[2] + + dprintln( "ServiceTable start: %(1)x count: %(2)x" % { "1" : serviceTableStart, "2" : serviceCount } ) + + serviceTable = loadSignDWords( serviceTableStart, serviceCount ) + + for i in range( 0, serviceCount ): + routineAddress = getServiceAddr(serviceTableStart, serviceTable[i]); + dprintln( "[%u] " % i + findSymbol( routineAddress ) ) + + else: + + serviceTableHeader = loadDWords( nt.KeServiceDescriptorTable, 4 ) + serviceTableStart = serviceTableHeader[0] + serviceCount = serviceTableHeader[2] + + dprintln( "ServiceTable start: %(1)x count: %(2)x" % { "1" : serviceTableStart, "2" : serviceCount } ) + + serviceTable = loadPtrs( serviceTableStart, serviceCount ) + + for i in range( 0, serviceCount ): + dprintln( "[%u] " % i + findSymbol( serviceTable[i] ) ) + +def run(): + + while True: + + if not isWindbgExt(): + if not loadDump( sys.argv[1] ): + dprintln( sys.argv[1] + " - load failed" ) + break + + if not isKernelDebugging(): + dprintln( "not a kernel debugging" ) + break + + checkSSDT() + + break + + + +if __name__ == "__main__": + + run()