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()