From ca6c731376a91ced49fa83898bcc700d722b1856 Mon Sep 17 00:00:00 2001 From: "SND\\kernelnet_cp" Date: Tue, 14 Dec 2010 16:14:14 +0000 Subject: [PATCH] [+] added : go, stepin, stepover routine for control execution [+] added : dbgBreakpointClass class for control breakpoints git-svn-id: https://pykd.svn.codeplex.com/svn@58740 9b283d60-5439-405e-af05-b73fd8c4d996 --- pykd/dbgcmd.cpp | 73 ++++++++++++++++++++++++++++++++++++++++++++++ pykd/dbgcmd.h | 53 +++++++++++++++++++++++++++++++++ pykd/dbgext.cpp | 11 ++++++- pykd/dbgsystem.cpp | 15 +++++----- pykd/dbgsystem.h | 2 +- snippets/reload.py | 29 ++++++++++++++++++ 6 files changed, 174 insertions(+), 9 deletions(-) create mode 100644 snippets/reload.py diff --git a/pykd/dbgcmd.cpp b/pykd/dbgcmd.cpp index b63b0a4..7024283 100644 --- a/pykd/dbgcmd.cpp +++ b/pykd/dbgcmd.cpp @@ -95,3 +95,76 @@ dbgExtensionClass::call( const std::string &command, const std::string params ) } /////////////////////////////////////////////////////////////////////////////// + + + +/////////////////////////////////////////////////////////////////////////////// + +dbgBreakpointClass::dbgBreakpointClass( ULONG64 offset ) +{ + m_offset = offset; + m_breakpoint = NULL; + + set(); +} + +/////////////////////////////////////////////////////////////////////////////// + +dbgBreakpointClass::~dbgBreakpointClass() +{ + remove(); +} + +/////////////////////////////////////////////////////////////////////////////// + +bool +dbgBreakpointClass::set() +{ + HRESULT hres; + + try { + + if ( m_breakpoint ) + return true; + + hres = dbgExt->control->AddBreakpoint( DEBUG_BREAKPOINT_CODE, DEBUG_ANY_ID, &m_breakpoint ); + if ( FAILED( hres ) ) + throw DbgException( "IDebugControl::AddBreakpoint failed" ); + + hres = m_breakpoint->SetOffset( m_offset ); + if ( FAILED( hres ) ) + throw DbgException( "IDebugBreakpoint::SetOffset failed" ); + + hres = m_breakpoint->SetFlags( DEBUG_BREAKPOINT_ENABLED ); + if ( FAILED( hres ) ) + throw DbgException( "IDebugBreakpoint::SetFlags 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" ); + } + + remove(); + + return false; +} + +/////////////////////////////////////////////////////////////////////////////// + +void +dbgBreakpointClass::remove() +{ + if ( m_breakpoint ) + { + dbgExt->control->RemoveBreakpoint( m_breakpoint ); + m_breakpoint = NULL; + } +} + +/////////////////////////////////////////////////////////////////////////////// diff --git a/pykd/dbgcmd.h b/pykd/dbgcmd.h index d6429ec..4de0f59 100644 --- a/pykd/dbgcmd.h +++ b/pykd/dbgcmd.h @@ -10,6 +10,35 @@ std::string dbgCommand( const std::string &command ); +template +void +setExecutionStatus() +{ + HRESULT hres; + + try { + + hres = dbgExt->control->SetExecutionStatus( status ); + + if ( FAILED( hres ) ) + throw DbgException( "IDebugControl::SetExecutionStatus failed" ); + + hres = dbgExt->control->WaitForEvent( 0, INFINITE ); + + if ( FAILED( hres ) ) + throw DbgException( "IDebugControl::SetExecutionStatus failed" ); + + } + 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" ); + } +} + ///////////////////////////////////////////////////////////////////////////////// class dbgExtensionClass { @@ -34,3 +63,27 @@ private: ///////////////////////////////////////////////////////////////////////////////// + +class dbgBreakpointClass { + +public: + + dbgBreakpointClass( ULONG64 offset ); + + ~dbgBreakpointClass(); + + bool + set(); + + void + remove(); + +private: + + ULONG64 m_offset; + + IDebugBreakpoint *m_breakpoint; + +}; + +///////////////////////////////////////////////////////////////////////////////// diff --git a/pykd/dbgext.cpp b/pykd/dbgext.cpp index 08ae421..358ffbb 100644 --- a/pykd/dbgext.cpp +++ b/pykd/dbgext.cpp @@ -85,6 +85,9 @@ BOOST_PYTHON_FUNCTION_OVERLOADS( compareMemoryOver, compareMemory, 3, 4 ) BOOST_PYTHON_MODULE( pykd ) { + boost::python::def( "go", &setExecutionStatus ); + boost::python::def( "stepin", &setExecutionStatus ); + boost::python::def( "stepover", &setExecutionStatus ); boost::python::def( "createSession", &dbgCreateSession ); boost::python::def( "isSessionStart", &dbgIsSessionStart ); boost::python::def( "symbolsPath", &dbgSymPath ); @@ -130,7 +133,7 @@ BOOST_PYTHON_MODULE( pykd ) boost::python::def( "ptrPtr", &loadPtrByPtr ); boost::python::def( "compareMemory", &compareMemory, compareMemoryOver( boost::python::args( "addr1", "addr2", "length", "phyAddr" ), "" ) ); boost::python::def( "getCurrentStack", &getCurrentStack ); - boost::python::def( "reloadSymbols", &reloadSymbols ); + boost::python::def( "reloadModule", &reloadModule ); boost::python::def( "getPdbFile", &getPdbFile ); boost::python::def( "getImplicitThread", &getImplicitThread ); boost::python::def( "setImplicitThread", &setImplicitThread ); @@ -162,6 +165,12 @@ BOOST_PYTHON_MODULE( pykd ) .def( "write", &dbgOut::write ); boost::python::class_( "windbgIn", "windbgIn" ) .def( "readline", &dbgIn::readline ); + boost::python::class_( + "dbgBreakpointClass", + "dbgBreakpointClass", + boost::python::init( boost::python::args("offset"), "__init__ dbgBreakpointClass" ) ) + .def( "set", &dbgBreakpointClass::set ) + .def( "remove", &dbgBreakpointClass::remove ); } diff --git a/pykd/dbgsystem.cpp b/pykd/dbgsystem.cpp index 2a66ef6..21d5267 100644 --- a/pykd/dbgsystem.cpp +++ b/pykd/dbgsystem.cpp @@ -4,6 +4,7 @@ #include "dbgext.h" #include "dbgexcept.h" #include "dbgsystem.h" +#include "dbgcallback.h" /////////////////////////////////////////////////////////////////////////////////// @@ -122,19 +123,19 @@ getPdbFile( ULONG64 moduleBase ) /////////////////////////////////////////////////////////////////////////////////// void -reloadSymbols( const char * moduleName ) +reloadModule( const char * moduleName ) { HRESULT hres; try { + + // подавить вывод сообщений об отсутствии символов + OutputReader outputReader( dbgExt->client ); - std::string reloadParam( "/f " ); - reloadParam += moduleName; - - hres = dbgExt->symbols->Reload( reloadParam.c_str() ); + hres = dbgExt->symbols->Reload( moduleName ); - if ( FAILED( hres ) ) - throw DbgException( "IDebugSymbol::Reload failed" ); + //if ( FAILED( hres ) ) + // throw DbgException( "IDebugSymbol::Reload failed" ); } catch( std::exception &e ) { diff --git a/pykd/dbgsystem.h b/pykd/dbgsystem.h index 2f0f742..75d3250 100644 --- a/pykd/dbgsystem.h +++ b/pykd/dbgsystem.h @@ -20,7 +20,7 @@ std::string getImageFile( ULONG64 moduleBase ); void -reloadSymbols( const char * moduleName ); +reloadModule( const char * moduleName ); bool isKernelDebugging(); diff --git a/snippets/reload.py b/snippets/reload.py new file mode 100644 index 0000000..2d41c45 --- /dev/null +++ b/snippets/reload.py @@ -0,0 +1,29 @@ +# +# +# + +import sys +from pykd import * + +def symreload(): + + reloadModule( "/f" ) + + PsLoadedModuleList = getOffset( "nt", "PsLoadedModuleList" ) + + loadedModulesInfo = typedVarList( PsLoadedModuleList, "nt", "_LDR_DATA_TABLE_ENTRY", "InLoadOrderLinks" ) + + for module in loadedModulesInfo: + + if "" == getPdbFile( module.DllBase ): + baseName = loadUnicodeString( module.BaseDllName.getAddress() ) + if baseName=="ntoskrnl.exe": baseName = "nt" + reloadModule( " /u " + str(baseName) ) + +if __name__ == "__main__": + + if not isSessionStart(): + dprintln( "script is launch out of windbg" ) + quit( 0 ) + + symreload() \ No newline at end of file