From e759e869c8a5b2663743143f4409228cbc575a17 Mon Sep 17 00:00:00 2001 From: "SND\\kernelnet_cp" Date: Mon, 17 Sep 2012 12:01:59 +0000 Subject: [PATCH] [0.2.x] added : basic debug event handling implementation git-svn-id: https://pykd.svn.codeplex.com/svn@79635 9b283d60-5439-405e-af05-b73fd8c4d996 --- pykd/bpoint.cpp | 164 ------------------------- pykd/dbgengine.h | 19 +++ pykd/dbgext.cpp | 4 +- pykd/eventhandler.cpp | 203 +++++++++++++++++++++++++++++++ pykd/eventhandler.h | 32 +++++ pykd/inteventhandler.cpp | 157 ------------------------ pykd/inteventhandler.h | 76 ------------ pykd/process.cpp | 254 --------------------------------------- pykd/process.h | 27 ----- pykd/pykd_2008.vcproj | 10 +- pykd/win/dbgeng.cpp | 71 +++++++++++ pykd/win/dbgeng.h | 43 ++++++- snippets/ndis.py | 2 +- 13 files changed, 377 insertions(+), 685 deletions(-) create mode 100644 pykd/eventhandler.cpp create mode 100644 pykd/eventhandler.h delete mode 100644 pykd/inteventhandler.cpp delete mode 100644 pykd/inteventhandler.h delete mode 100644 pykd/process.cpp delete mode 100644 pykd/process.h diff --git a/pykd/bpoint.cpp b/pykd/bpoint.cpp index 42eaa6b..7978d9e 100644 --- a/pykd/bpoint.cpp +++ b/pykd/bpoint.cpp @@ -6,7 +6,6 @@ #include "bpoint.h" #include "dbgengine.h" - /////////////////////////////////////////////////////////////////////////////// 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 diff --git a/pykd/dbgengine.h b/pykd/dbgengine.h index 7d1dde3..61f4813 100644 --- a/pykd/dbgengine.h +++ b/pykd/dbgengine.h @@ -61,6 +61,25 @@ struct STACK_FRAME_DESC { void getStackTrace(std::vector &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 ULONG breakPointSet( ULONG64 offset, bool hardware = false, ULONG size = 0, ULONG accessType = 0 ); void breakPointRemove( ULONG id ); diff --git a/pykd/dbgext.cpp b/pykd/dbgext.cpp index 8d48925..c31bf70 100644 --- a/pykd/dbgext.cpp +++ b/pykd/dbgext.cpp @@ -100,7 +100,7 @@ HRESULT CALLBACK py( PDEBUG_CLIENT4 client, PCSTR args ) { - g_dbgEng.setClient( client ); +// g_dbgEng.setClient( client ); WindbgGlobalSession::RestorePyState(); @@ -212,7 +212,7 @@ HRESULT CALLBACK pycmd( PDEBUG_CLIENT4 client, PCSTR args ) { - g_dbgEng.setClient( client ); +// g_dbgEng.setClient( client ); WindbgGlobalSession::RestorePyState(); diff --git a/pykd/eventhandler.cpp b/pykd/eventhandler.cpp new file mode 100644 index 0000000..6b6189c --- /dev/null +++ b/pykd/eventhandler.cpp @@ -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(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 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; +//} +// +////////////////////////////////////////////////////////////////////////////////// + diff --git a/pykd/eventhandler.h b/pykd/eventhandler.h new file mode 100644 index 0000000..ef664f9 --- /dev/null +++ b/pykd/eventhandler.h @@ -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 diff --git a/pykd/inteventhandler.cpp b/pykd/inteventhandler.cpp deleted file mode 100644 index f8688df..0000000 --- a/pykd/inteventhandler.cpp +++ /dev/null @@ -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(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 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 diff --git a/pykd/inteventhandler.h b/pykd/inteventhandler.h deleted file mode 100644 index b9dfcb7..0000000 --- a/pykd/inteventhandler.h +++ /dev/null @@ -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 - -//////////////////////////////////////////////////////////////////////////////// \ No newline at end of file diff --git a/pykd/process.cpp b/pykd/process.cpp deleted file mode 100644 index 1a9115a..0000000 --- a/pykd/process.cpp +++ /dev/null @@ -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 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 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 ); -} - -/////////////////////////////////////////////////////////////////////////////////// - -} \ No newline at end of file diff --git a/pykd/process.h b/pykd/process.h deleted file mode 100644 index 459a3f7..0000000 --- a/pykd/process.h +++ /dev/null @@ -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 ); - -/////////////////////////////////////////////////////////////////////////////////// - -} diff --git a/pykd/pykd_2008.vcproj b/pykd/pykd_2008.vcproj index b9f14b2..5ccd555 100644 --- a/pykd/pykd_2008.vcproj +++ b/pykd/pykd_2008.vcproj @@ -1,7 +1,7 @@ + + @@ -499,6 +503,10 @@ RelativePath=".\disasmengine.h" > + + diff --git a/pykd/win/dbgeng.cpp b/pykd/win/dbgeng.cpp index 6185322..d0cfca0 100644 --- a/pykd/win/dbgeng.cpp +++ b/pykd/win/dbgeng.cpp @@ -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( 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 diff --git a/pykd/win/dbgeng.h b/pykd/win/dbgeng.h index 02c3117..ccb2330 100644 --- a/pykd/win/dbgeng.h +++ b/pykd/win/dbgeng.h @@ -3,6 +3,7 @@ #include "dbgengine.h" #include "dbgexcept.h" #include "pyaux.h" +#include "eventhandler.h" #include #include @@ -39,6 +40,26 @@ public: 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* operator->() { @@ -56,20 +77,36 @@ public: 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: std::auto_ptr m_bind; + DbgEventCallbacks m_callbacks; + + const DEBUG_EVENT_CALLBACK *m_eventCallbacks; }; /////////////////////////////////////////////////////////////////////////////////// -extern DebugEngine g_dbgEng; +extern DebugEngine g_dbgEng; ///////////////////////////////////////////////////////////////////////////////// diff --git a/snippets/ndis.py b/snippets/ndis.py index 35d70a5..9116bb6 100644 --- a/snippets/ndis.py +++ b/snippets/ndis.py @@ -13,7 +13,7 @@ def printBreakLine(): def printNdisObj(): - ndis=loadModule("ndis") + ndis=module("ndis") ndisMajorVersion = ptrByte( ndis.NdisGetVersion + 1 ) ndisMinorVersion = ptrByte( ndis.NdisGetVersion + 3 )