From 0bfbcf23902275d6de025dc46e24e2eda855b1ff Mon Sep 17 00:00:00 2001
From: "SND\\kernelnet_cp"
 <SND\kernelnet_cp@9b283d60-5439-405e-af05-b73fd8c4d996>
Date: Fri, 20 Aug 2010 12:09:45 +0000
Subject: [PATCH] [+] added: getImplicitThread routine( get address of the
 current thread ) [+] added: setImplicitThread routine ( change current thread
 context ) [+] added: dbgStackFrameClass class ( information about stack frame
 ) [+] added: getCurrentStack routine ( get current stack as collections of
 dbgStackFrameClass object )

git-svn-id: https://pykd.svn.codeplex.com/svn@54280 9b283d60-5439-405e-af05-b73fd8c4d996
---
 pykd/dbgext.cpp   | 14 ++++++--
 pykd/dbgext.h     | 20 ++++++------
 pykd/dbgstack.cpp | 81 ++++++++++++++++++++++++++++++++++++++++++++---
 pykd/dbgstack.h   | 26 ++++++++++++++-
 pykd/dbgsym.cpp   | 21 +++++++-----
 5 files changed, 137 insertions(+), 25 deletions(-)

diff --git a/pykd/dbgext.cpp b/pykd/dbgext.cpp
index 019be5f..a8484f1 100644
--- a/pykd/dbgext.cpp
+++ b/pykd/dbgext.cpp
@@ -98,9 +98,11 @@ BOOST_PYTHON_MODULE( pykd )
     boost::python::def( "ptrSignQWord", &loadByPtr<__int64> );
     boost::python::def( "ptrPtr", &loadPtrByPtr );    
     boost::python::def( "compareMemory", &compareMemory );
-    boost::python::def( "getStack", &getStack );
+    boost::python::def( "getCurrentStack", &getCurrentStack );
     boost::python::def( "reloadSymbols", &reloadSymbols );
     boost::python::def( "getPdbFile", &getPdbFile );
+    boost::python::def( "getImplicitThread", &getImplicitThread );
+    boost::python::def( "setImplicitThread", &setImplicitThread );
     boost::python::class_<typedVarClass>( "typedVarClass" )
         .def("getAddress", &typedVarClass::getAddress );
     boost::python::class_<dbgModuleClass>( "dbgModuleClass" )
@@ -112,7 +114,13 @@ BOOST_PYTHON_MODULE( pykd )
             "dbgExtensionClass",
             "dbgExtensionClass",
              boost::python::init<const char*>( boost::python::args("path"), "__init__  dbgExtensionClass" ) ) 
-        .def("call", &dbgExtensionClass::call );       
+        .def("call", &dbgExtensionClass::call );    
+    boost::python::class_<dbgStackFrameClass>( "dbgStackFrameClass", "dbgStackFrameClass" )
+        .def_readonly( "instructionOffset", &dbgStackFrameClass::InstructionOffset )
+        .def_readonly( "returnOffset", &dbgStackFrameClass::ReturnOffset )
+        .def_readonly( "frameOffset", &dbgStackFrameClass::FrameOffset )
+        .def_readonly( "stackOffset", &dbgStackFrameClass::StackOffset )
+        .def_readonly( "frameNumber", &dbgStackFrameClass::FrameNumber );
 }    
 
 /////////////////////////////////////////////////////////////////////////////////
@@ -167,6 +175,8 @@ SetupDebugEngine( IDebugClient4 *client, DbgExt *dbgExt  )
     client->QueryInterface( __uuidof(IDebugDataSpaces), (void **)&dbgExt->dataSpaces );
     
     client->QueryInterface( __uuidof(IDebugAdvanced2), (void **)&dbgExt->advanced2 );
+    
+    client->QueryInterface( __uuidof(IDebugSystemObjects2), (void**)&dbgExt->system2 );
 }
     
 /////////////////////////////////////////////////////////////////////////////////    
diff --git a/pykd/dbgext.h b/pykd/dbgext.h
index 16a6fdb..f3798a2 100644
--- a/pykd/dbgext.h
+++ b/pykd/dbgext.h
@@ -5,20 +5,22 @@
 
 struct DbgExt {
 
-    IDebugClient        *client;
-    IDebugClient4       *client4;
+    IDebugClient            *client;
+    IDebugClient4           *client4;
     
-    IDebugControl       *control;
+    IDebugControl           *control;
     
-    IDebugRegisters     *registers;
+    IDebugRegisters         *registers;
     
-    IDebugSymbols       *symbols;
-    IDebugSymbols2      *symbols2;   
-    IDebugSymbols3      *symbols3;   
+    IDebugSymbols           *symbols;
+    IDebugSymbols2          *symbols2;   
+    IDebugSymbols3          *symbols3;   
     
-    IDebugDataSpaces    *dataSpaces;
+    IDebugDataSpaces        *dataSpaces;
     
-    IDebugAdvanced2     *advanced2;
+    IDebugAdvanced2         *advanced2;
+    
+    IDebugSystemObjects2    *system2;
 };
 
 extern DbgExt    *dbgExt;
diff --git a/pykd/dbgstack.cpp b/pykd/dbgstack.cpp
index 4b93562..496f574 100644
--- a/pykd/dbgstack.cpp
+++ b/pykd/dbgstack.cpp
@@ -6,8 +6,73 @@
 
 /////////////////////////////////////////////////////////////////////////////////
 
+bool
+setImplicitThread( 
+    ULONG64  newThreadAddr,
+    PULONG64  oldThreadAddr )
+{
+    HRESULT                 hres;  
+
+    try {
+    
+        *oldThreadAddr = getImplicitThread();
+        if ( *oldThreadAddr == -1 )
+            return false;
+    
+        hres = dbgExt->system2->SetImplicitThreadDataOffset( newThreadAddr );
+        if ( FAILED( hres ) )
+            throw DbgException( "IDebugSystemObjects2::SetImplicitThreadDataOffset  failed" ); 
+            
+        return true;            
+        
+    }
+  	catch( std::exception  &e )
+	{
+		dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd error: %s\n", e.what() );
+	}
+	catch(...)
+	{
+		dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd unexpected error\n" );
+	}
+	
+	return false;	
+}  
+
+
+/////////////////////////////////////////////////////////////////////////////////  
+    
+ULONG64
+getImplicitThread()
+{
+    HRESULT                 hres;  
+
+    try {
+        
+        ULONG64   threadOffset = -1;    
+  
+        hres = dbgExt->system2->GetImplicitThreadDataOffset( &threadOffset );
+        if ( FAILED( hres ) )
+            throw DbgException( "IDebugSystemObjects2::GetImplicitThreadDataOffset  failed" ); 
+            
+        return threadOffset;            
+        
+    }
+  	catch( std::exception  &e )
+	{
+		dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd error: %s\n", e.what() );
+	}
+	catch(...)
+	{
+		dbgExt->control->Output( DEBUG_OUTPUT_ERROR, "pykd unexpected error\n" );
+	}
+	
+	return -1;	
+}     
+
+/////////////////////////////////////////////////////////////////////////////////  
+
 boost::python::object
-getStack( ULONG64 stackPtr )
+getCurrentStack()
 {
     HRESULT                 hres;  
     PDEBUG_STACK_FRAME      frames = NULL;
@@ -17,14 +82,19 @@ getStack( ULONG64 stackPtr )
         frames = new DEBUG_STACK_FRAME [ 1000 ];
     
         ULONG   filledFrames;
-        hres = dbgExt->control->GetStackTrace( stackPtr, stackPtr, stackPtr, frames, 1000, &filledFrames );
+        hres = dbgExt->control->GetStackTrace( 0, 0, 0, frames, 1000, &filledFrames );
         
-        dbgExt->control->OutputStackTrace( DEBUG_OUTCTL_THIS_CLIENT, frames, filledFrames, DEBUG_STACK_FUNCTION_INFO | DEBUG_STACK_FRAME_ADDRESSES );
+        boost::python::list    frameList;
+        
+        for ( ULONG i = 0; i < filledFrames; ++i )
+        {
+            frameList.append( boost::python::object( dbgStackFrameClass( frames[i] ) ) );
+        }         
         
     	if ( frames )
 	        delete[] frames;
 
-        return boost::python::object();        
+        return frameList;       
     
     }
   	catch( std::exception  &e )
@@ -39,7 +109,8 @@ getStack( ULONG64 stackPtr )
 	if ( frames )
 	    delete[] frames;
 
-    return boost::python::object();
+    return boost::python::object(); 
 }
 
+
 /////////////////////////////////////////////////////////////////////////////////
\ No newline at end of file
diff --git a/pykd/dbgstack.h b/pykd/dbgstack.h
index 05096b9..fc28ca4 100644
--- a/pykd/dbgstack.h
+++ b/pykd/dbgstack.h
@@ -5,7 +5,31 @@
 
 /////////////////////////////////////////////////////////////////////////////////
 
+bool
+setImplicitThread( 
+    ULONG64  newThreadAddr,
+    PULONG64  oldThreadAddr );
+    
+ULONG64
+getImplicitThread();        
+
+
 boost::python::object
-getStack( ULONG64 stackPtr );
+getCurrentStack();
+
+class dbgStackFrameClass : public DEBUG_STACK_FRAME {
+
+public:
+
+    dbgStackFrameClass()
+    {
+        memset( static_cast<DEBUG_STACK_FRAME*>( this ), 0, sizeof(DEBUG_STACK_FRAME) );
+    }       
+    
+    dbgStackFrameClass( const DEBUG_STACK_FRAME &stackFrame )
+    {
+        memcpy( static_cast<DEBUG_STACK_FRAME*>( this ), &stackFrame, sizeof(DEBUG_STACK_FRAME) );   
+    }
+};
 
 /////////////////////////////////////////////////////////////////////////////////
\ No newline at end of file
diff --git a/pykd/dbgsym.cpp b/pykd/dbgsym.cpp
index 7d9b02d..f0c73d8 100644
--- a/pykd/dbgsym.cpp
+++ b/pykd/dbgsym.cpp
@@ -13,9 +13,6 @@ findSymbolForAddress( ULONG64 addr )
     HRESULT         hres;  
     
     try {
-    
-        DEBUG_MODULE_AND_ID     debugId;
-        ULONG64                 displace = 0;
         
         if ( *( (ULONG*)&addr + 1 ) == 0 )
             *( (ULONG*)&addr + 1 ) = 0xFFFFFFFF;        
@@ -36,11 +33,19 @@ findSymbolForAddress( ULONG64 addr )
         if ( FAILED( hres ) )
              throw DbgException( "IDebugSymbol2::GetModuleNameString  failed" );           
     
-        ULONG   entries = 0;
-        hres =  dbgExt->symbols3->GetSymbolEntriesByOffset( addr, 0, &debugId, &displace, 1, &entries );
+        char        symbolName[0x100];
+        ULONG64     displace = 0;
+        hres = dbgExt->symbols->GetNameByOffset( addr, symbolName, sizeof(symbolName), NULL, &displace );
         if ( FAILED( hres ) )
-             throw DbgException( "IDebugSymbol3::GetSymbolEntriesByOffset  failed" );
-             
+            throw DbgException( "IDebugSymbol::GetNameByOffset  failed" );    
+        
+        std::stringstream      ss;
+        displace == 0 ?  ss << symbolName : ss << symbolName << '+' << std::hex << displace;
+        
+        return boost::python::object( ss.str() );
+        
+        
+/*             
         std::stringstream      ss;             
              
         if ( entries == 0 )
@@ -55,7 +60,7 @@ findSymbolForAddress( ULONG64 addr )
              throw DbgException( "IDebugSymbol3::GetSymbolEntryString  failed" );  
              
         ss << moduleName << "!" << symbolName;
-        return boost::python::object( ss.str() );                                
+        return boost::python::object( ss.str() ); */                               
             
     }
 	catch( std::exception  &e )