mirror of
https://github.com/ivellioscolin/pykd.git
synced 2025-04-21 12:53:23 +08:00
[+] 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:
parent
26b5fb69a1
commit
0f9c2e1e2c
176
pykd/dbgcallback.h
Normal file
176
pykd/dbgcallback.h
Normal 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;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
@ -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";
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -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;
|
||||||
|
};
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
@ -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
45
pykd/dbgstack.cpp
Normal 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
11
pykd/dbgstack.h
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <boost/python.hpp>
|
||||||
|
#include <boost/python/object.hpp>
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
boost::python::object
|
||||||
|
getStack( ULONG64 stackPtr );
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
@ -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 );
|
||||||
|
@ -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"
|
||||||
>
|
>
|
||||||
|
Loading…
Reference in New Issue
Block a user