[+] added: dbgExtensionClass class for calling windbg extension command from python script

git-svn-id: https://pykd.svn.codeplex.com/svn@53831 9b283d60-5439-405e-af05-b73fd8c4d996
This commit is contained in:
SND\kernelnet_cp 2010-08-09 07:28:59 +00:00
parent 26b5fb69a1
commit 0f9c2e1e2c
8 changed files with 331 additions and 2 deletions

176
pykd/dbgcallback.h Normal file
View File

@ -0,0 +1,176 @@
#pragma once
#include "dbgext.h"
#include "dbgexcept.h"
#include <wdbgexts.h>
///////////////////////////////////////////////////////////////////////////////
// êëàññ äëÿ ïåðåõâàòà âûâîäà â îòëàä÷èê
class OutputReader : public IDebugOutputCallbacks {
public:
OutputReader( IDebugClient *debugClient )
{
HRESULT hres;
try {
m_debugClient = debugClient;
m_debugClient->AddRef();
hres = m_debugClient->GetOutputCallbacks( &m_previousCallback );
if ( FAILED( hres ) )
{
throw hres;
}
hres = m_debugClient->SetOutputCallbacks( this );
if ( FAILED( hres ) )
{
throw hres;
}
} catch( ... )
{
m_debugClient->Release();
m_debugClient = NULL;
}
}
~OutputReader()
{
if ( m_debugClient )
{
m_debugClient->SetOutputCallbacks( m_previousCallback );
m_debugClient->Release();
}
}
const std::string&
Line() const {
return m_readLine;
}
private:
// IUnknown.
STDMETHOD(QueryInterface)(
__in REFIID InterfaceId,
__out PVOID* Interface ) {
return E_NOINTERFACE;
}
STDMETHOD_(ULONG, AddRef)() {
return 1L;
}
STDMETHOD_(ULONG, Release)() {
return 0L;
}
STDMETHOD(Output)(
__in ULONG Mask,
__in PCSTR Text )
{
if ( Mask == DEBUG_OUTPUT_NORMAL )
{
m_readLine += std::string( Text );
}
return S_OK;
}
private:
std::string m_readLine;
IDebugClient *m_debugClient;
IDebugOutputCallbacks *m_previousCallback;
};
///////////////////////////////////////////////////////////////////////////////
class InputReader : public IDebugInputCallbacks {
public:
InputReader( IDebugClient *debugClient )
{
HRESULT hres;
try {
m_debugClient = debugClient;
m_debugClient->AddRef();
hres = m_debugClient->GetInputCallbacks( &m_previousCallback );
if ( FAILED( hres ) )
{
throw hres;
}
hres = m_debugClient->SetInputCallbacks( this );
if ( FAILED( hres ) )
{
throw hres;
}
} catch( ... )
{
m_debugClient->Release();
m_debugClient = NULL;
}
}
~InputReader()
{
if ( m_debugClient )
{
m_debugClient->SetInputCallbacks( m_previousCallback );
m_debugClient->Release();
}
}
private:
// IUnknown.
STDMETHOD(QueryInterface)(
__in REFIID InterfaceId,
__out PVOID* Interface ) {
return E_NOINTERFACE;
}
STDMETHOD_(ULONG, AddRef)() {
return 1L;
}
STDMETHOD_(ULONG, Release)() {
return 0L;
}
STDMETHOD( EndInput )() {
return S_OK;
}
STDMETHOD( StartInput )(
IN ULONG BufferSize ) {
return S_OK;
}
private:
IDebugClient *m_debugClient;
IDebugInputCallbacks *m_previousCallback;
};
///////////////////////////////////////////////////////////////////////////////

View File

@ -35,3 +35,63 @@ dbgCommand( const std::string &command )
} }
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
dbgExtensionClass::dbgExtensionClass( const char* path )
{
HRESULT hres;
try {
hres = dbgExt->control->AddExtension( path, 0, &m_handle );
if ( FAILED( hres ) )
throw DbgException( "IDebugControl::AddExtension 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" );
}
}
///////////////////////////////////////////////////////////////////////////////
dbgExtensionClass::~dbgExtensionClass()
{
if ( m_handle )
dbgExt->control->RemoveExtension( m_handle );
}
///////////////////////////////////////////////////////////////////////////////
std::string
dbgExtensionClass::call( const std::string &command, const std::string params )
{
HRESULT hres;
try {
OutputReader outReader( dbgExt->client );
hres = dbgExt->control->CallExtension( m_handle, command.c_str(), params.c_str() );
if ( FAILED( hres ) )
throw DbgException( "IDebugControl::CallExtension failed" );
return std::string( outReader.Line() );
}
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 "error";
}
///////////////////////////////////////////////////////////////////////////////

View File

@ -10,8 +10,27 @@
std::string std::string
dbgCommand( const std::string &command ); dbgCommand( const std::string &command );
void /////////////////////////////////////////////////////////////////////////////////
dbgGoCommand();
class dbgExtensionClass {
public:
dbgExtensionClass() :
m_handle( NULL )
{}
dbgExtensionClass( const char* path );
~dbgExtensionClass();
std::string
call( const std::string &command, const std::string param );
private:
ULONG64 m_handle;
};
///////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////

View File

@ -24,6 +24,7 @@
#include "dbgexcept.h" #include "dbgexcept.h"
#include "dbgsession.h" #include "dbgsession.h"
#include "dbgcallback.h" #include "dbgcallback.h"
#include "dbgstack.h"
///////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////
@ -96,6 +97,7 @@ BOOST_PYTHON_MODULE( pykd )
boost::python::def( "ptrSignQWord", &loadByPtr<__int64> ); boost::python::def( "ptrSignQWord", &loadByPtr<__int64> );
boost::python::def( "ptrPtr", &loadPtrByPtr ); boost::python::def( "ptrPtr", &loadPtrByPtr );
boost::python::def( "compareMemory", &compareMemory ); boost::python::def( "compareMemory", &compareMemory );
boost::python::def( "getStack", &getStack );
boost::python::class_<typedVarClass>( "typedVarClass" ) boost::python::class_<typedVarClass>( "typedVarClass" )
.def("getAddress", &typedVarClass::getAddress ); .def("getAddress", &typedVarClass::getAddress );
boost::python::class_<dbgModuleClass>( "dbgModuleClass" ) boost::python::class_<dbgModuleClass>( "dbgModuleClass" )
@ -103,6 +105,11 @@ BOOST_PYTHON_MODULE( pykd )
.def("end", &dbgModuleClass::getEnd ) .def("end", &dbgModuleClass::getEnd )
.def("name", &dbgModuleClass::getName ) .def("name", &dbgModuleClass::getName )
.def("contain", &dbgModuleClass::contain ); .def("contain", &dbgModuleClass::contain );
boost::python::class_<dbgExtensionClass>(
"dbgExtensionClass",
"dbgExtensionClass",
boost::python::init<const char*>( boost::python::args("path"), "__init__ dbgExtensionClass" ) )
.def("call", &dbgExtensionClass::call );
} }
///////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////

45
pykd/dbgstack.cpp Normal file
View File

@ -0,0 +1,45 @@
#include "stdafx.h"
#include "dbgext.h"
#include "dbgstack.h"
#include "dbgexcept.h"
/////////////////////////////////////////////////////////////////////////////////
boost::python::object
getStack( ULONG64 stackPtr )
{
HRESULT hres;
PDEBUG_STACK_FRAME frames = NULL;
try {
frames = new DEBUG_STACK_FRAME [ 1000 ];
ULONG filledFrames;
hres = dbgExt->control->GetStackTrace( stackPtr, stackPtr, stackPtr, frames, 1000, &filledFrames );
dbgExt->control->OutputStackTrace( DEBUG_OUTCTL_THIS_CLIENT, frames, filledFrames, DEBUG_STACK_FUNCTION_INFO | DEBUG_STACK_FRAME_ADDRESSES );
if ( frames )
delete[] frames;
return boost::python::object();
}
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" );
}
if ( frames )
delete[] frames;
return boost::python::object();
}
/////////////////////////////////////////////////////////////////////////////////

11
pykd/dbgstack.h Normal file
View File

@ -0,0 +1,11 @@
#pragma once
#include <boost/python.hpp>
#include <boost/python/object.hpp>
/////////////////////////////////////////////////////////////////////////////////
boost::python::object
getStack( ULONG64 stackPtr );
/////////////////////////////////////////////////////////////////////////////////

View File

@ -81,6 +81,9 @@ loadTypedVar( const std::string &moduleName, const std::string &typeName, ULONG6
try { try {
if ( address == 0 )
return boost::python::object();
ULONG64 moduleBase; ULONG64 moduleBase;
hres = dbgExt->symbols->GetModuleByModuleName( moduleName.c_str(), 0, NULL, &moduleBase ); hres = dbgExt->symbols->GetModuleByModuleName( moduleName.c_str(), 0, NULL, &moduleBase );

View File

@ -387,6 +387,10 @@
RelativePath=".\dbgsession.cpp" RelativePath=".\dbgsession.cpp"
> >
</File> </File>
<File
RelativePath=".\dbgstack.cpp"
>
</File>
<File <File
RelativePath=".\dbgsym.cpp" RelativePath=".\dbgsym.cpp"
> >
@ -485,6 +489,10 @@
RelativePath=".\dbgsession.h" RelativePath=".\dbgsession.h"
> >
</File> </File>
<File
RelativePath=".\dbgstack.h"
>
</File>
<File <File
RelativePath=".\dbgsym.h" RelativePath=".\dbgsym.h"
> >