From 283f911a733bff77201bfc769c5be0a9ba3453b5 Mon Sep 17 00:00:00 2001
From: "SND\\kernelnet_cp"
 <SND\kernelnet_cp@9b283d60-5439-405e-af05-b73fd8c4d996>
Date: Tue, 29 Nov 2011 16:28:23 +0000
Subject: [PATCH] [0.1.x] added : loadCStr routine [0.1.x] added : loadWStr
 routine

git-svn-id: https://pykd.svn.codeplex.com/svn@71881 9b283d60-5439-405e-af05-b73fd8c4d996
---
 pykd/dbgclient.h        |  4 +++
 pykd/dbgext.cpp         |  8 ++++++
 pykd/dbgmem.cpp         | 58 +++++++++++++++++++++++++++++++++++++++++
 pykd/dbgmem.h           |  4 +++
 pykd/dbgobj.h           |  4 +--
 snippets/export.py      | 16 ++++++------
 test/scripts/memtest.py |  4 +++
 7 files changed, 88 insertions(+), 10 deletions(-)

diff --git a/pykd/dbgclient.h b/pykd/dbgclient.h
index 23ee0c9..a2aeb9c 100644
--- a/pykd/dbgclient.h
+++ b/pykd/dbgclient.h
@@ -128,6 +128,10 @@ public:
 
     std::wstring loadWChars( ULONG64 offset, ULONG count, bool phyAddr = FALSE );
 
+    std::string loadCStr( ULONG64 offset );
+
+    std::wstring loadWStr( ULONG64 offset );
+
     ULONG ptrSize();
 
     ULONG64 ptrByte( ULONG64 offset );
diff --git a/pykd/dbgext.cpp b/pykd/dbgext.cpp
index cef6f65..2f97a68 100644
--- a/pykd/dbgext.cpp
+++ b/pykd/dbgext.cpp
@@ -183,6 +183,10 @@ BOOST_PYTHON_MODULE( pykd )
             "Load string from target memory" ) )
         .def( "loadWChars", &DebugClient::loadWChars, DebugClient_loadWChars( python::args( "offset", "count", "phyAddr" ),
             "Load string from target memory" ) )
+        .def( "loadCStr", &DebugClient::loadCStr,
+            "Load string from the target buffer containing 0-terminated ansi-string" )
+        .def( "loadWStr", &DebugClient::loadWStr,
+            "Load string from the target buffer containing 0-terminated unicode-string" )
         .def( "ptrByte", &DebugClient::ptrByte,
             "Read an unsigned 1-byte integer from the target memory" )
         .def( "ptrWord", &DebugClient::ptrWord,
@@ -288,6 +292,10 @@ BOOST_PYTHON_MODULE( pykd )
         "Load string from target memory" ) );
     python::def( "loadWChars", &loadWChars, loadWChars_( python::args( "address", "count", "phyAddr" ),
         "Load string from target memory" ) );
+    python::def( "loadCStr", &loadCStr,
+        "Load string from the target buffer containing 0-terminated ansi-string" );
+    python::def( "loadWStr", &loadWStr,
+        "Load string from the target buffer containing 0-terminated unicode-string" );
     python::def( "ptrByte", &ptrByte,
         "Read an unsigned 1-byte integer from the target memory" );
     python::def( "ptrWord", &ptrWord,
diff --git a/pykd/dbgmem.cpp b/pykd/dbgmem.cpp
index 59c7402..f0641a7 100644
--- a/pykd/dbgmem.cpp
+++ b/pykd/dbgmem.cpp
@@ -158,6 +158,64 @@ std::wstring loadWChars( ULONG64 address, ULONG  number, bool phyAddr )
 
 /////////////////////////////////////////////////////////////////////////////////////
 
+std::string DebugClient::loadCStr( ULONG64 address )
+{
+    const   size_t              maxLength = 0x1000;
+ 
+    address = addr64( address );
+
+    std::vector<char>   buffer(maxLength);
+        
+    HRESULT     hres = 
+        m_dataSpaces->ReadMultiByteStringVirtual(
+            address,
+            maxLength,
+            &buffer[0],
+            maxLength,
+            NULL );
+    
+    if ( FAILED( hres ) )
+        throw MemoryException( address );
+                           
+    return std::string( &buffer[0] );
+}
+
+std::string loadCStr( ULONG64 offset )
+{
+    return g_dbgClient->loadCStr( offset );
+}
+
+/////////////////////////////////////////////////////////////////////////////////////
+
+std::wstring DebugClient::loadWStr( ULONG64 address )
+{
+    const   size_t              maxLength = 0x2000;
+ 
+    address = addr64( address );
+
+    std::vector<char>   buffer(maxLength);
+        
+    HRESULT     hres = 
+        m_dataSpaces->ReadMultiByteStringVirtual(
+            address,
+            maxLength,
+            &buffer[0],
+            maxLength,
+            NULL );
+    
+    if ( FAILED( hres ) )
+        throw MemoryException( address );
+                           
+    return std::wstring( (wchar_t*)&buffer[0] );
+}
+
+std::wstring loadWStr( ULONG64 offset )
+{
+    return g_dbgClient->loadWStr( offset );
+}
+
+/////////////////////////////////////////////////////////////////////////////////////
+
 python::list DebugClient::loadBytes( ULONG64 offset, ULONG count, bool phyAddr )
 {
     return loadArray<unsigned char>( offset, count, phyAddr );
diff --git a/pykd/dbgmem.h b/pykd/dbgmem.h
index a2ce649..afffe0c 100644
--- a/pykd/dbgmem.h
+++ b/pykd/dbgmem.h
@@ -24,6 +24,10 @@ std::string loadChars( ULONG64 address, ULONG  number, bool phyAddr = FALSE );
 
 std::wstring loadWChars( ULONG64 address, ULONG  number, bool phyAddr = FALSE );
 
+std::string loadCStr( ULONG64 offset );
+
+std::wstring loadWStr( ULONG64 offset );
+
 python::list loadBytes( ULONG64 offset, ULONG count, bool phyAddr = FALSE );
 
 python::list loadWords( ULONG64 offset, ULONG count, bool phyAddr = FALSE );
diff --git a/pykd/dbgobj.h b/pykd/dbgobj.h
index 76d44b7..cdeebbc 100644
--- a/pykd/dbgobj.h
+++ b/pykd/dbgobj.h
@@ -32,7 +32,7 @@ protected:
         if ( FAILED( hres ) )
             throw DbgException("QueryInterface IDebugAdvanced2  failed");  
 
-        hres = client->QueryInterface( __uuidof(IDebugDataSpaces), (void**)&m_dataSpaces );
+        hres = client->QueryInterface( __uuidof(IDebugDataSpaces4), (void**)&m_dataSpaces );
         if ( FAILED( hres ) )
             throw DbgException("QueryInterface IDebugDataSpaces  failed"); 
 
@@ -48,7 +48,7 @@ protected:
     CComPtr<IDebugControl4>     m_control;
     CComPtr<IDebugSymbols3>     m_symbols;
     CComPtr<IDebugAdvanced2>    m_advanced;
-    CComPtr<IDebugDataSpaces>   m_dataSpaces;
+    CComPtr<IDebugDataSpaces4>  m_dataSpaces;
     CComPtr<IDebugRegisters2>   m_registers;
 
 };
diff --git a/snippets/export.py b/snippets/export.py
index 34320ac..c49ccff 100644
--- a/snippets/export.py
+++ b/snippets/export.py
@@ -9,8 +9,8 @@ from pykd import *
 
 def export( moduleName, mask = "*" ):
 
-    module = loadModule( moduleName )
-    dprintln( "Module: " + moduleName + " base: %x" % module.begin() + " end: %x" % module.end() )
+    modObj = loadModule( moduleName )
+    dprintln( "Module: " + moduleName + " base: %x" % modObj.begin() + " end: %x" % modObj.end() )
 
     if isKernelDebugging():
         systemModule = loadModule( "nt" )
@@ -19,12 +19,12 @@ def export( moduleName, mask = "*" ):
    
 
     if is64bitSystem():
-        ntHeader = typedVar( systemModule.name(), "_IMAGE_NT_HEADERS64", module.begin() + ptrDWord( module.begin() + 0x3c ) )
+        ntHeader = systemModule.typedVar( "_IMAGE_NT_HEADERS64", modObj.begin() + ptrDWord( modObj.begin() + 0x3c ) )
         if ntHeader.OptionalHeader.Magic == 0x10b:
             systemModule = loadModule( "ntdll32" ) 
-            ntHeader = typedVar( systemModule.name(), "_IMAGE_NT_HEADERS", module.begin() + ptrDWord( module.begin() + 0x3c ) )
+            ntHeader = systemModule.typedVar( "_IMAGE_NT_HEADERS", modObj.begin() + ptrDWord( modObj.begin() + 0x3c ) )
     else:
-        ntHeader = typedVar( systemModule.name(), "_IMAGE_NT_HEADERS", module.begin() + ptrDWord( module.begin() + 0x3c ) )
+        ntHeader = systemModule.typedVar("_IMAGE_NT_HEADERS", modObj.begin() + ptrDWord( modObj.begin() + 0x3c ) )
 
 
     dprintln( "Export RVA: %x  Size: %x" % ( ntHeader.OptionalHeader.DataDirectory[0].VirtualAddress, ntHeader.OptionalHeader.DataDirectory[0].Size  ) )
@@ -33,14 +33,14 @@ def export( moduleName, mask = "*" ):
     if ntHeader.OptionalHeader.DataDirectory[0].Size == 0:
         return
     
-    exportDirAddr = module.begin() + ntHeader.OptionalHeader.DataDirectory[0].VirtualAddress;
+    exportDirAddr = modObj.begin() + ntHeader.OptionalHeader.DataDirectory[0].VirtualAddress;
 
     namesCount = ptrDWord( exportDirAddr + 0x18 )
    
-    namesRva = module.begin() + ptrDWord( exportDirAddr + 0x20 ) 
+    namesRva = modObj.begin() + ptrDWord( exportDirAddr + 0x20 ) 
 
     for i in range( 0, namesCount ):
-        exportName = loadCStr( module.begin() + ptrDWord( namesRva + 4 * i ) )
+        exportName = loadCStr( modObj.begin() + ptrDWord( namesRva + 4 * i ) )
         if fnmatch.fnmatch( exportName, mask ): 
             dprintln( exportName )    
 
diff --git a/test/scripts/memtest.py b/test/scripts/memtest.py
index 5caa77d..4251775 100644
--- a/test/scripts/memtest.py
+++ b/test/scripts/memtest.py
@@ -77,3 +77,7 @@ class MemoryTest( unittest.TestCase ):
     def testCompare( self ):
         self.assertTrue( pykd.compareMemory( target.module.helloStr, pykd.ptrPtr(target.module.strArray), 5 ) )
         self.assertFalse( pykd.compareMemory( target.module.helloStr, target.module.helloWStr, 5 ) )
+        
+    def testCStr( self ):        
+        self.assertEqual( 'Hello', pykd.loadCStr( target.module.helloStr ) )
+        self.assertEqual( u'Hello', pykd.loadWStr( target.module.helloWStr ) )