[0.2.x] added : basic debug event handling implementation

git-svn-id: https://pykd.svn.codeplex.com/svn@79635 9b283d60-5439-405e-af05-b73fd8c4d996
This commit is contained in:
SND\kernelnet_cp 2012-09-17 12:01:59 +00:00 committed by Mikhail I. Izmestev
parent 9455aa0fa5
commit e759e869c8
13 changed files with 377 additions and 685 deletions

View File

@ -6,7 +6,6 @@
#include "bpoint.h" #include "bpoint.h"
#include "dbgengine.h" #include "dbgengine.h"
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
namespace pykd { namespace pykd {
@ -29,167 +28,4 @@ ULONG setHardwareBp(ULONG64 offset, ULONG size, ULONG accessType, BpCallback &ca
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
//static IDebugBreakpoint *setBreakPoint(
// IDebugControl4 *control,
// ULONG bpType,
// ULONG64 addr
//)
//{
// IDebugBreakpoint *bp;
// HRESULT hres = control->AddBreakpoint(bpType, DEBUG_ANY_ID, &bp);
// if (S_OK != hres)
// throw DbgException("IDebugControl::AddBreakpoint", hres);
//
// hres = bp->SetOffset(addr);
// if (S_OK != hres)
// {
// control->RemoveBreakpoint(bp);
// throw DbgException("IDebugBreakpoint::SetOffset", hres);
// }
//
// ULONG bpFlags;
// hres = bp->GetFlags(&bpFlags);
// if (S_OK != hres)
// {
// control->RemoveBreakpoint(bp);
// throw DbgException("IDebugBreakpoint::GetFlags", hres);
// }
//
// bpFlags |= DEBUG_BREAKPOINT_ENABLED;
// hres = bp->SetFlags(bpFlags);
// if (S_OK != hres)
// {
// control->RemoveBreakpoint(bp);
// throw DbgException("IDebugBreakpoint::SetFlags", hres);
// }
//
// return bp;
//}
//
//////////////////////////////////////////////////////////////////////////////////
//
//static BPOINT_ID getBpId(IDebugBreakpoint *bp, IDebugControl4 *control = NULL)
//{
// BPOINT_ID Id;
// HRESULT hres = bp->GetId(&Id);
// if (S_OK != hres)
// {
// if (control)
// control->RemoveBreakpoint(bp);
// throw DbgException("IDebugBreakpoint::GetId", hres);
// }
// return Id;
//}
//
//////////////////////////////////////////////////////////////////////////////////
//
//BPOINT_ID DebugClient::setSoftwareBp(ULONG64 addr, BpCallback &callback /*= BpCallback()*/)
//{
// addr = addr64(addr);
// IDebugBreakpoint *bp = setBreakPoint(m_control, DEBUG_BREAKPOINT_CODE, addr);
//
// const BPOINT_ID Id = getBpId(bp, m_control);
//
// if (!callback.is_none())
// {
// boost::recursive_mutex::scoped_lock mapBpLock(*m_bpCallbacks.m_lock);
// m_bpCallbacks.m_map[Id] = callback;
// }
//
// return Id;
//}
//
//////////////////////////////////////////////////////////////////////////////////
//
//BPOINT_ID DebugClient::setHardwareBp(ULONG64 addr, ULONG size, ULONG accessType, BpCallback &callback /*= BpCallback()*/)
//{
// addr = addr64(addr);
// IDebugBreakpoint *bp = setBreakPoint(m_control, DEBUG_BREAKPOINT_DATA, addr);
//
// HRESULT hres = bp->SetDataParameters(size, accessType);
// if (S_OK != hres)
// {
// m_control->RemoveBreakpoint(bp);
// throw DbgException("IDebugBreakpoint::SetDataParameters", hres);
// }
//
// const BPOINT_ID Id = getBpId(bp, m_control);
//
// if (!callback.is_none())
// {
// boost::recursive_mutex::scoped_lock mapBpLock(*m_bpCallbacks.m_lock);
// m_bpCallbacks.m_map[Id] = callback;
// }
//
// return Id;
//}
//
//////////////////////////////////////////////////////////////////////////////////
//
//python::list DebugClient::getAllBp()
//{
// ULONG numberOfBps;
// HRESULT hres = m_control->GetNumberBreakpoints(&numberOfBps);
// if (S_OK != hres)
// throw DbgException("IDebugControl::GetNumberBreakpoints", hres);
//
// python::list lstIds;
//
// for (ULONG i =0; i < numberOfBps; ++i)
// {
// IDebugBreakpoint *bp;
// hres = m_control->GetBreakpointByIndex(i, &bp);
// if (S_OK != hres)
// throw DbgException("IDebugControl::GetBreakpointByIndex", hres);
// lstIds.append( getBpId(bp) );
// }
//
// return lstIds;
//}
//
//////////////////////////////////////////////////////////////////////////////////
//
//void DebugClient::removeBp(BPOINT_ID Id)
//{
// IDebugBreakpoint *bp;
// HRESULT hres = m_control->GetBreakpointById(Id, &bp);
// if (S_OK != hres)
// throw DbgException("IDebugControl::GetBreakpointById", hres);
//
// hres = m_control->RemoveBreakpoint(bp);
// if (S_OK != hres)
// throw DbgException("IDebugControl::RemoveBreakpoint", hres);
//}
//
//////////////////////////////////////////////////////////////////////////////////
//
//void DebugClient::removeAllBp()
//{
// ULONG numberOfBps;
// do {
// HRESULT hres = m_control->GetNumberBreakpoints(&numberOfBps);
// if (S_OK != hres)
// throw DbgException("IDebugControl::GetNumberBreakpoints", hres);
// if (!numberOfBps)
// break;
//
// IDebugBreakpoint *bp;
// hres = m_control->GetBreakpointByIndex(0, &bp);
// if (S_OK != hres)
// throw DbgException("IDebugControl::GetBreakpointByIndex", hres);
//
// hres = m_control->RemoveBreakpoint(bp);
// if (S_OK != hres)
// throw DbgException("IDebugControl::RemoveBreakpoint", hres);
//
// } while (numberOfBps);
//}
////////////////////////////////////////////////////////////////////////////////
} // end pykd namespace } // end pykd namespace

View File

@ -61,6 +61,25 @@ struct STACK_FRAME_DESC {
void getStackTrace(std::vector<STACK_FRAME_DESC> &frames); void getStackTrace(std::vector<STACK_FRAME_DESC> &frames);
// callback events
#define DEBUG_CALLBACK_METHODTYPE __cdecl
enum DEBUG_CALLBACK_RESULT {
DebugCallbackBreak,
DebugCallbackProceed,
DebugCallbackNoChange
};
struct DEBUG_EVENT_CALLBACK {
virtual DEBUG_CALLBACK_RESULT DEBUG_CALLBACK_METHODTYPE OnBreakpoint( ULONG bpId ) = 0;
};
void eventRegisterCallbacks( const DEBUG_EVENT_CALLBACK *callbacks );
void eventRemoveCallbacks();
//breakpoints //breakpoints
ULONG breakPointSet( ULONG64 offset, bool hardware = false, ULONG size = 0, ULONG accessType = 0 ); ULONG breakPointSet( ULONG64 offset, bool hardware = false, ULONG size = 0, ULONG accessType = 0 );
void breakPointRemove( ULONG id ); void breakPointRemove( ULONG id );

View File

@ -100,7 +100,7 @@ HRESULT
CALLBACK CALLBACK
py( PDEBUG_CLIENT4 client, PCSTR args ) py( PDEBUG_CLIENT4 client, PCSTR args )
{ {
g_dbgEng.setClient( client ); // g_dbgEng.setClient( client );
WindbgGlobalSession::RestorePyState(); WindbgGlobalSession::RestorePyState();
@ -212,7 +212,7 @@ HRESULT
CALLBACK CALLBACK
pycmd( PDEBUG_CLIENT4 client, PCSTR args ) pycmd( PDEBUG_CLIENT4 client, PCSTR args )
{ {
g_dbgEng.setClient( client ); // g_dbgEng.setClient( client );
WindbgGlobalSession::RestorePyState(); WindbgGlobalSession::RestorePyState();

203
pykd/eventhandler.cpp Normal file
View File

@ -0,0 +1,203 @@
#include "stdafx.h"
#include "eventhandler.h"
namespace pykd {
EventHandler *g_eventHandler = NULL;
///////////////////////////////////////////////////////////////////////////////
EventHandler::EventHandler()
{
eventRegisterCallbacks( this );
}
///////////////////////////////////////////////////////////////////////////////
EventHandler::~EventHandler()
{
eventRemoveCallbacks();
}
///////////////////////////////////////////////////////////////////////////////
}; // namespace pykd
///////////////////////////////////////////////////////////////////////////////
//
//InternalDbgEventHandler::InternalDbgEventHandler(
// IDebugClient4 *client,
// DebugClient *parentClient,
// SynSymbolsPtr synSymbols,
// BpCallbackMap &bpCallbacks
//) : m_parentClient(parentClient)
// , m_synSymbols(synSymbols)
// , m_bpCallbacks(bpCallbacks)
//{
// HRESULT hres = client->CreateClient(&m_client);
// if (FAILED(hres))
// throw DbgException("Call IDebugClient::CreateClient failed");
//
// hres = m_client->QueryInterface(__uuidof(IDebugControl), (void**)&m_control);
// if ( FAILED( hres ) )
// throw DbgException("QueryInterface IDebugControl failed");
//
// m_client->SetEventCallbacks(this);
//}
//
//////////////////////////////////////////////////////////////////////////////////
//
//InternalDbgEventHandler::~InternalDbgEventHandler()
//{
// m_control->Release();
// m_client->Release();
//}
//
//////////////////////////////////////////////////////////////////////////////////
//
//HRESULT InternalDbgEventHandler::GetInterestMask(
// __out PULONG Mask
//)
//{
// *Mask =
// DEBUG_EVENT_BREAKPOINT |
// DEBUG_EVENT_CHANGE_ENGINE_STATE |
// DEBUG_EVENT_CHANGE_SYMBOL_STATE;
//
// return S_OK;
//}
//
/////////////////////////////////////////////////////////////////////////////////////
//
//HRESULT InternalDbgEventHandler::ChangeSymbolState(
// __in ULONG Flags,
// __in ULONG64 Argument
//)
//{
// HRESULT hres = S_OK;
//
// if (DEBUG_CSS_LOADS & Flags)
// hres = symLoaded(Argument);
//
// return hres;
//}
//
/////////////////////////////////////////////////////////////////////////////////////
//
//HRESULT InternalDbgEventHandler::ChangeEngineState(
// __in ULONG Flags,
// __in ULONG64 Argument
//)
//{
// HRESULT hres = S_OK;
//
// if (DEBUG_CES_BREAKPOINTS & Flags)
// hres = bpChanged(static_cast<BPOINT_ID>(Argument));
//
// return hres;
//}
//
/////////////////////////////////////////////////////////////////////////////////////
//
//HRESULT InternalDbgEventHandler::Breakpoint(IDebugBreakpoint *bp)
//{
// BPOINT_ID Id;
// HRESULT hres = bp->GetId(&Id);
// if (S_OK == hres)
// {
// boost::recursive_mutex::scoped_lock mapBpLock(*m_bpCallbacks.m_lock);
// BpCallbackMapIml::iterator it = m_bpCallbacks.m_map.find(Id);
// if (it != m_bpCallbacks.m_map.end())
// {
// PyThread_StateSave pyThreadSave( m_parentClient->getThreadState() );
//
// try {
//
// python::object resObj = it->second(Id);
//
// if (resObj.is_none())
// return DEBUG_STATUS_NO_CHANGE;
//
// python::extract<HRESULT> getRetCode( resObj );
// if (getRetCode.check())
// return getRetCode();
// }
// catch (const python::error_already_set &) {
// // TODO: some logging, alerting...
// return DEBUG_STATUS_BREAK;
// }
// // TODO: python code return invalid value
// // some logging, alerting...
// return DEBUG_STATUS_BREAK;
// }
// }
// return DEBUG_STATUS_NO_CHANGE;
//}
//
/////////////////////////////////////////////////////////////////////////////////////
//
//HRESULT InternalDbgEventHandler::symLoaded(
// __in ULONG64 ModuleAddress
//)
//{
// if (!ModuleAddress)
// {
// // f.e. is case ".reload /f image.exe", if for image.exe no symbols
// m_synSymbols->restoreAll();
// return S_OK;
// }
//
// m_synSymbols->restoreForModule(ModuleAddress);
// return S_OK;
//}
//
//////////////////////////////////////////////////////////////////////////////////
//
//HRESULT InternalDbgEventHandler::bpChanged(BPOINT_ID Id)
//{
// if (DEBUG_ANY_ID == Id)
// return S_OK;
//
// IDebugBreakpoint *bp;
// HRESULT hres = m_control->GetBreakpointById(Id, &bp);
// if (E_NOINTERFACE == hres)
// {
// // breakpoint was removed
// boost::recursive_mutex::scoped_lock mapBpLock(*m_bpCallbacks.m_lock);
// m_bpCallbacks.m_map.erase(Id);
// }
//
// return S_OK;
//}
//
//////////////////////////////////////////////////////////////////////////////////

32
pykd/eventhandler.h Normal file
View File

@ -0,0 +1,32 @@
//
// Internal debug event handler
//
#pragma once
#include "dbgengine.h"
namespace pykd {
//////////////////////////////////////////////////////////////////////////////////
class EventHandler : public DEBUG_EVENT_CALLBACK {
public:
EventHandler();
virtual ~EventHandler();
private:
virtual DEBUG_CALLBACK_RESULT DEBUG_CALLBACK_METHODTYPE OnBreakpoint( ULONG bpId ) {
return DebugCallbackNoChange;
}
};
extern EventHandler *g_eventHandler;
//////////////////////////////////////////////////////////////////////////////////
}; // namespace pykd

View File

@ -1,157 +0,0 @@
#include "stdafx.h"
#include "dbgclient.h"
namespace pykd {
////////////////////////////////////////////////////////////////////////////////
InternalDbgEventHandler::InternalDbgEventHandler(
IDebugClient4 *client,
DebugClient *parentClient,
SynSymbolsPtr synSymbols,
BpCallbackMap &bpCallbacks
) : m_parentClient(parentClient)
, m_synSymbols(synSymbols)
, m_bpCallbacks(bpCallbacks)
{
HRESULT hres = client->CreateClient(&m_client);
if (FAILED(hres))
throw DbgException("Call IDebugClient::CreateClient failed");
hres = m_client->QueryInterface(__uuidof(IDebugControl), (void**)&m_control);
if ( FAILED( hres ) )
throw DbgException("QueryInterface IDebugControl failed");
m_client->SetEventCallbacks(this);
}
////////////////////////////////////////////////////////////////////////////////
InternalDbgEventHandler::~InternalDbgEventHandler()
{
m_control->Release();
m_client->Release();
}
////////////////////////////////////////////////////////////////////////////////
HRESULT InternalDbgEventHandler::GetInterestMask(
__out PULONG Mask
)
{
*Mask =
DEBUG_EVENT_BREAKPOINT |
DEBUG_EVENT_CHANGE_ENGINE_STATE |
DEBUG_EVENT_CHANGE_SYMBOL_STATE;
return S_OK;
}
///////////////////////////////////////////////////////////////////////////////////
HRESULT InternalDbgEventHandler::ChangeSymbolState(
__in ULONG Flags,
__in ULONG64 Argument
)
{
HRESULT hres = S_OK;
if (DEBUG_CSS_LOADS & Flags)
hres = symLoaded(Argument);
return hres;
}
///////////////////////////////////////////////////////////////////////////////////
HRESULT InternalDbgEventHandler::ChangeEngineState(
__in ULONG Flags,
__in ULONG64 Argument
)
{
HRESULT hres = S_OK;
if (DEBUG_CES_BREAKPOINTS & Flags)
hres = bpChanged(static_cast<BPOINT_ID>(Argument));
return hres;
}
///////////////////////////////////////////////////////////////////////////////////
HRESULT InternalDbgEventHandler::Breakpoint(IDebugBreakpoint *bp)
{
BPOINT_ID Id;
HRESULT hres = bp->GetId(&Id);
if (S_OK == hres)
{
boost::recursive_mutex::scoped_lock mapBpLock(*m_bpCallbacks.m_lock);
BpCallbackMapIml::iterator it = m_bpCallbacks.m_map.find(Id);
if (it != m_bpCallbacks.m_map.end())
{
PyThread_StateSave pyThreadSave( m_parentClient->getThreadState() );
try {
python::object resObj = it->second(Id);
if (resObj.is_none())
return DEBUG_STATUS_NO_CHANGE;
python::extract<HRESULT> getRetCode( resObj );
if (getRetCode.check())
return getRetCode();
}
catch (const python::error_already_set &) {
// TODO: some logging, alerting...
return DEBUG_STATUS_BREAK;
}
// TODO: python code return invalid value
// some logging, alerting...
return DEBUG_STATUS_BREAK;
}
}
return DEBUG_STATUS_NO_CHANGE;
}
///////////////////////////////////////////////////////////////////////////////////
HRESULT InternalDbgEventHandler::symLoaded(
__in ULONG64 ModuleAddress
)
{
if (!ModuleAddress)
{
// f.e. is case ".reload /f image.exe", if for image.exe no symbols
m_synSymbols->restoreAll();
return S_OK;
}
m_synSymbols->restoreForModule(ModuleAddress);
return S_OK;
}
////////////////////////////////////////////////////////////////////////////////
HRESULT InternalDbgEventHandler::bpChanged(BPOINT_ID Id)
{
if (DEBUG_ANY_ID == Id)
return S_OK;
IDebugBreakpoint *bp;
HRESULT hres = m_control->GetBreakpointById(Id, &bp);
if (E_NOINTERFACE == hres)
{
// breakpoint was removed
boost::recursive_mutex::scoped_lock mapBpLock(*m_bpCallbacks.m_lock);
m_bpCallbacks.m_map.erase(Id);
}
return S_OK;
}
////////////////////////////////////////////////////////////////////////////////
}; // namespace pykd

View File

@ -1,76 +0,0 @@
//
// Internal debug event handler
//
#pragma once
#include "synsymbol.h"
////////////////////////////////////////////////////////////////////////////////
namespace pykd {
////////////////////////////////////////////////////////////////////////////////
struct BpCallbackMap;
class DebugClient;
////////////////////////////////////////////////////////////////////////////////
class InternalDbgEventHandler : public DebugBaseEventCallbacks {
public:
InternalDbgEventHandler(
IDebugClient4 *client,
DebugClient *parentClient,
SynSymbolsPtr synSymbols,
BpCallbackMap &bpCallbacks
);
~InternalDbgEventHandler();
protected:
// IUnknown impls
STDMETHOD_(ULONG, AddRef)() { return 1; }
STDMETHOD_(ULONG, Release)() { return 1; }
// IDebugEventCallbacks impls
STDMETHOD(GetInterestMask)(
__out PULONG Mask
);
STDMETHOD(ChangeSymbolState)(
__in ULONG Flags,
__in ULONG64 Argument
) override;
STDMETHOD(ChangeEngineState)(
__in ULONG Flags,
__in ULONG64 Argument
) override;
STDMETHOD(Breakpoint)(
__in IDebugBreakpoint *bp
) override;
private:
HRESULT symLoaded(__in ULONG64 ModuleAddress);
HRESULT bpChanged(ULONG Id);
IDebugClient *m_client;
IDebugControl *m_control;
DebugClient *m_parentClient;
SynSymbolsPtr m_synSymbols;
BpCallbackMap &m_bpCallbacks;
};
////////////////////////////////////////////////////////////////////////////////
}; // namespace pykd
////////////////////////////////////////////////////////////////////////////////

View File

@ -1,254 +0,0 @@
#include "stdafx.h"
#include "dbgclient.h"
#include "stkframe.h"
namespace pykd {
///////////////////////////////////////////////////////////////////////////////////
ULONG64
DebugClient::getCurrentProcess()
{
HRESULT hres;
ULONG64 processAddr = 0;
hres = m_system->GetImplicitProcessDataOffset( &processAddr );
if ( FAILED( hres ) )
throw DbgException( "IDebugSystemObjects2::GetImplicitProcessDataOffset failed" );
return processAddr;
}
ULONG64
getCurrentProcess()
{
return g_dbgClient->getCurrentProcess();
}
///////////////////////////////////////////////////////////////////////////////////
ULONG64
DebugClient::getImplicitThread()
{
HRESULT hres;
ULONG64 threadOffset = -1;
hres = m_system->GetImplicitThreadDataOffset( &threadOffset );
if ( FAILED( hres ) )
throw DbgException( "IDebugSystemObjects2::GetImplicitThreadDataOffset failed" );
return threadOffset;
}
ULONG64
getImplicitThread() {
return g_dbgClient->getImplicitThread();
}
///////////////////////////////////////////////////////////////////////////////////
python::list
DebugClient::getCurrentStack()
{
HRESULT hres;
ULONG filledFrames;
std::vector<DEBUG_STACK_FRAME> frames(1000);
hres = m_control->GetStackTrace( 0, 0, 0, &frames[0], 1000, &filledFrames );
if ( FAILED( hres ) )
throw DbgException( "IDebugControl::GetStackTrace failed" );
python::list frameList;
for ( ULONG i = 0; i < filledFrames; ++i )
{
python::object frameObj( StackFrame(shared_from_this(), frames[i]) );
frameList.append( frameObj );
}
return frameList;
}
python::list
getCurrentStack()
{
return g_dbgClient->getCurrentStack();
}
///////////////////////////////////////////////////////////////////////////////////
std::string processorToStr(ULONG processorMode)
{
switch( processorMode )
{
case IMAGE_FILE_MACHINE_I386:
return "X86";
case IMAGE_FILE_MACHINE_ARM:
return "ARM";
case IMAGE_FILE_MACHINE_IA64:
return "IA64";
case IMAGE_FILE_MACHINE_AMD64:
return "X64";
}
throw DbgException( "Unknown CPU type" );
}
///////////////////////////////////////////////////////////////////////////////////
std::string DebugClient::getProcessorMode()
{
HRESULT hres;
ULONG processorMode;
hres = m_control->GetEffectiveProcessorType( &processorMode );
if ( FAILED( hres ) )
throw DbgException( "IDebugControl::GetEffectiveProcessorType failed" );
return processorToStr(processorMode);
}
std::string getProcessorMode()
{
return g_dbgClient->getProcessorMode();
}
///////////////////////////////////////////////////////////////////////////////////
std::string DebugClient::getProcessorType()
{
HRESULT hres;
ULONG processorMode;
hres = m_control->GetActualProcessorType( &processorMode );
if ( FAILED( hres ) )
throw DbgException( "IDebugControl::GetActualProcessorType failed" );
return processorToStr(processorMode);
}
std::string getProcessorType()
{
return g_dbgClient->getProcessorType();
}
///////////////////////////////////////////////////////////////////////////////////
python::list DebugClient::getThreadList()
{
HRESULT hres;
ULONG i;
ULONG oldThreadId = 0;
ULONG threadCount;
hres = m_system->GetNumberThreads( &threadCount );
if ( FAILED( hres ) )
throw DbgException( "IDebugSystemObjects::GetNumberThreads failed" );
std::vector<ULONG> threadIds(threadCount);
hres = m_system->GetThreadIdsByIndex( 0, threadCount, &threadIds[0], NULL );
if ( FAILED( hres ) )
throw DbgException( "IDebugSystemObjects::GetThreadIdsByIndex failed" );
hres = m_system->GetCurrentThreadId( &oldThreadId );
if ( FAILED( hres ) )
throw DbgException( "IDebugSystemObjects::GetCurrentThreadId failed" );
boost::python::list threadList;
for ( i = 0; i < threadCount; ++i )
{
m_system->SetCurrentThreadId( threadIds[i] );
ULONG64 threadOffset;
hres = m_system->GetCurrentThreadDataOffset( &threadOffset );
if ( FAILED( hres ) )
{
m_system->SetCurrentThreadId( oldThreadId );
throw DbgException( "IDebugSystemObjects::GetCurrentThreadDataOffset failed" );
}
threadList.append( threadOffset );
}
m_system->SetCurrentThreadId( oldThreadId );
return threadList;
}
python::list getThreadList()
{
return g_dbgClient->getThreadList();
}
///////////////////////////////////////////////////////////////////////////////////
void DebugClient::setCurrentProcess( ULONG64 processAddr )
{
HRESULT hres;
processAddr = addr64(processAddr);
hres = m_system->SetImplicitProcessDataOffset( processAddr );
if ( FAILED( hres ) )
throw DbgException( "IDebugSystemObjects2::SetImplicitProcessDataOffset failed" );
}
void setCurrentProcess( ULONG64 processAddr )
{
g_dbgClient->setCurrentProcess( processAddr );
}
///////////////////////////////////////////////////////////////////////////////////
void DebugClient::setImplicitThread( ULONG64 threadAddr )
{
HRESULT hres;
threadAddr = addr64(threadAddr);
hres = m_system->SetImplicitThreadDataOffset( threadAddr );
if ( FAILED( hres ) )
throw DbgException( "IDebugSystemObjects2::SetImplicitThreadDataOffset failed" );
}
void setImplicitThread( ULONG64 threadAddr )
{
g_dbgClient->setImplicitThread( threadAddr );
}
///////////////////////////////////////////////////////////////////////////////////
void DebugClient::setProcessorMode( const std::wstring &mode )
{
HRESULT hres;
ULONG processorMode;
if ( mode == L"X86" )
processorMode = IMAGE_FILE_MACHINE_I386;
else if ( mode == L"ARM" )
processorMode = IMAGE_FILE_MACHINE_ARM;
else if ( mode == L"IA64" )
processorMode = IMAGE_FILE_MACHINE_IA64;
else if ( mode == L"X64" )
processorMode = IMAGE_FILE_MACHINE_AMD64;
else
throw DbgException( "Unknown processor type" );
hres = m_control->SetEffectiveProcessorType( processorMode );
if ( FAILED( hres ) )
throw DbgException( "IDebugControl::SetEffectiveProcessorType failed" );
}
void setProcessorMode( const std::wstring &mode )
{
g_dbgClient->setProcessorMode( mode );
}
///////////////////////////////////////////////////////////////////////////////////
}

View File

@ -1,27 +0,0 @@
#pragma once
namespace pykd {
///////////////////////////////////////////////////////////////////////////////////
ULONG64 getCurrentProcess();
ULONG64 getImplicitThread();
python::list getCurrentStack();
std::string getProcessorMode();
std::string getProcessorType();
python::list getThreadList();
void setCurrentProcess( ULONG64 processAddr );
void setImplicitThread( ULONG64 threadAddr );
void setProcessorMode( const std::wstring &mode );
///////////////////////////////////////////////////////////////////////////////////
}

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="windows-1251"?> <?xml version="1.0" encoding="windows-1251"?>
<VisualStudioProject <VisualStudioProject
ProjectType="Visual C++" ProjectType="Visual C++"
Version="9.00" Version="9,00"
Name="pykd" Name="pykd"
ProjectGUID="{FE961905-666F-4908-A212-961465F46F13}" ProjectGUID="{FE961905-666F-4908-A212-961465F46F13}"
RootNamespace="pykd" RootNamespace="pykd"
@ -385,6 +385,10 @@
RelativePath=".\disasm.cpp" RelativePath=".\disasm.cpp"
> >
</File> </File>
<File
RelativePath=".\eventhandler.cpp"
>
</File>
<File <File
RelativePath=".\localvar.cpp" RelativePath=".\localvar.cpp"
> >
@ -499,6 +503,10 @@
RelativePath=".\disasmengine.h" RelativePath=".\disasmengine.h"
> >
</File> </File>
<File
RelativePath=".\eventhandler.h"
>
</File>
<File <File
RelativePath=".\localvar.h" RelativePath=".\localvar.h"
> >

View File

@ -852,6 +852,77 @@ void breakPointRemoveAll()
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
void eventRegisterCallbacks( const DEBUG_EVENT_CALLBACK *callbacks )
{
g_dbgEng.registerCallbacks( callbacks );
}
void DebugEngine::registerCallbacks( const DEBUG_EVENT_CALLBACK *callbacks )
{
HRESULT hres;
m_eventCallbacks = callbacks;
hres = operator->()->client->SetEventCallbacks( &m_callbacks );
if ( S_OK != hres)
throw DbgException("IDebugClient::SetEventCallbacks", hres );
}
///////////////////////////////////////////////////////////////////////////////
void eventRemoveCallbacks()
{
}
///////////////////////////////////////////////////////////////////////////////
inline
ULONG ConvertCallbackResult( DEBUG_CALLBACK_RESULT result )
{
switch( result )
{
case DebugCallbackBreak:
return DEBUG_STATUS_BREAK;
case DebugCallbackProceed:
return DEBUG_STATUS_GO_HANDLED;
default:
assert( 0 );
case DebugCallbackNoChange:
return DEBUG_STATUS_NO_CHANGE;
}
}
///////////////////////////////////////////////////////////////////////////////
HRESULT STDMETHODCALLTYPE DebugEngine::DbgEventCallbacks::Breakpoint(
__in IDebugBreakpoint *bp
)
{
DEBUG_EVENT_CALLBACK* eventCallback = const_cast<DEBUG_EVENT_CALLBACK*>( g_dbgEng.getCallbacks() );
ULONG id;
HRESULT hres;
hres = bp->GetId( &id );
if ( hres == S_OK )
{
DEBUG_CALLBACK_RESULT result = eventCallback->OnBreakpoint( id );
return ConvertCallbackResult( result );
}
return DEBUG_STATUS_NO_CHANGE;
}
///////////////////////////////////////////////////////////////////////////////
} // end pykd namespace } // end pykd namespace

View File

@ -3,6 +3,7 @@
#include "dbgengine.h" #include "dbgengine.h"
#include "dbgexcept.h" #include "dbgexcept.h"
#include "pyaux.h" #include "pyaux.h"
#include "eventhandler.h"
#include <dbgeng.h> #include <dbgeng.h>
#include <dbghelp.h> #include <dbghelp.h>
@ -39,6 +40,26 @@ public:
PyThreadStateSaver pystate; PyThreadStateSaver pystate;
}; };
class DbgEventCallbacks : public DebugBaseEventCallbacks
{
// IUnknown impls
STDMETHOD_(ULONG, AddRef)() { return 1; }
STDMETHOD_(ULONG, Release)() { return 1; }
// IDebugEventCallbacks impls
STDMETHOD(GetInterestMask)(
__out PULONG Mask
)
{
*Mask = DEBUG_EVENT_BREAKPOINT;
return S_OK;
}
STDMETHOD(Breakpoint)(
__in IDebugBreakpoint *bp
);
};
DbgEngBind* DbgEngBind*
operator->() operator->()
{ {
@ -56,15 +77,31 @@ public:
return m_bind.get(); return m_bind.get();
} }
void setClient( PDEBUG_CLIENT4 client ) void registerCallbacks( const DEBUG_EVENT_CALLBACK *callbacks );
void removeCallbacks();
const DEBUG_EVENT_CALLBACK* getCallbacks() const {
return m_eventCallbacks;
}
DebugEngine() :
m_callbacks()
{ {
m_bind.reset(new DbgEngBind(client) ); g_eventHandler = new EventHandler();
}
~DebugEngine()
{
delete g_eventHandler;
g_eventHandler = NULL;
} }
private: private:
std::auto_ptr<DbgEngBind> m_bind; std::auto_ptr<DbgEngBind> m_bind;
DbgEventCallbacks m_callbacks;
const DEBUG_EVENT_CALLBACK *m_eventCallbacks;
}; };
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////

View File

@ -13,7 +13,7 @@ def printBreakLine():
def printNdisObj(): def printNdisObj():
ndis=loadModule("ndis") ndis=module("ndis")
ndisMajorVersion = ptrByte( ndis.NdisGetVersion + 1 ) ndisMajorVersion = ptrByte( ndis.NdisGetVersion + 1 )
ndisMinorVersion = ptrByte( ndis.NdisGetVersion + 3 ) ndisMinorVersion = ptrByte( ndis.NdisGetVersion + 3 )