From 17b0cf74475a71caa8c407e900c5adff366c8414 Mon Sep 17 00:00:00 2001 From: "SND\\kernelnet_cp" Date: Fri, 17 Aug 2012 07:45:07 +0000 Subject: [PATCH] [0.2.x] added : setBp routine git-svn-id: https://pykd.svn.codeplex.com/svn@78898 9b283d60-5439-405e-af05-b73fd8c4d996 --- pykd/bpoint.cpp | 318 ++++++++++++++++++++++-------------------- pykd/bpoint.h | 68 ++++----- pykd/dbgengine.h | 3 + pykd/pykd_2008.vcproj | 8 ++ pykd/pymod.cpp | 13 +- pykd/win/dbgeng.cpp | 61 ++++++++ 6 files changed, 290 insertions(+), 181 deletions(-) diff --git a/pykd/bpoint.cpp b/pykd/bpoint.cpp index 45edcc5..42eaa6b 100644 --- a/pykd/bpoint.cpp +++ b/pykd/bpoint.cpp @@ -4,170 +4,192 @@ #include "stdafx.h" #include "bpoint.h" +#include "dbgengine.h" -//////////////////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////////////////// namespace pykd { -static IDebugBreakpoint *setBreakPoint( - IDebugControl4 *control, - ULONG bpType, - ULONG64 addr -) +ULONG setSoftwareBp(ULONG64 offset, BpCallback &callback /*= BpCallback()*/) { - IDebugBreakpoint *bp; - HRESULT hres = control->AddBreakpoint(bpType, DEBUG_ANY_ID, &bp); - if (S_OK != hres) - throw DbgException("IDebugControl::AddBreakpoint", hres); + offset = addr64( offset ); - 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; + return breakPointSet( offset ); } -//////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// -static BPOINT_ID getBpId(IDebugBreakpoint *bp, IDebugControl4 *control = NULL) +ULONG setHardwareBp(ULONG64 offset, ULONG size, ULONG accessType, BpCallback &callback /*= BpCallback()*/ ) { - BPOINT_ID Id; - HRESULT hres = bp->GetId(&Id); - if (S_OK != hres) - { - if (control) - control->RemoveBreakpoint(bp); - throw DbgException("IDebugBreakpoint::GetId", hres); - } - return Id; + offset = addr64( offset ); + + return breakPointSet( offset, true, size, accessType ); } -//////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// -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; -} + + +//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); +//} //////////////////////////////////////////////////////////////////////////////// -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); -} - -//////////////////////////////////////////////////////////////////////////////// - -} // namespace pykd - - -//////////////////////////////////////////////////////////////////////////////// +} // end pykd namespace diff --git a/pykd/bpoint.h b/pykd/bpoint.h index 693ac1c..51d50c2 100644 --- a/pykd/bpoint.h +++ b/pykd/bpoint.h @@ -4,45 +4,49 @@ #pragma once -#include "dbgclient.h" - //////////////////////////////////////////////////////////////////////////////// namespace pykd { -//////////////////////////////////////////////////////////////////////////////// +typedef python::object BpCallback; -inline BPOINT_ID setSoftwareBp(ULONG64 addr, BpCallback &callback = BpCallback()) { - return g_dbgClient->setSoftwareBp(addr, callback); -} +ULONG setSoftwareBp(ULONG64 offset, BpCallback &callback = BpCallback() ); + +ULONG setHardwareBp(ULONG64 offset, ULONG size, ULONG accessType, BpCallback &callback = BpCallback()); + + +////////////////////////////////////////////////////////////////////////////////// +// +//inline BPOINT_ID setSoftwareBp(ULONG64 addr, BpCallback &callback = BpCallback()) { +// return g_dbgClient->setSoftwareBp(addr, callback); +//} +// +////////////////////////////////////////////////////////////////////////////////// +// +//inline BPOINT_ID setHardwareBp(ULONG64 addr, ULONG size, ULONG accessType, BpCallback &callback = BpCallback()) { +// return g_dbgClient->setHardwareBp(addr, size, accessType, callback); +//} +// +////////////////////////////////////////////////////////////////////////////////// +// +//inline python::list getAllBp() { +// return g_dbgClient->getAllBp(); +//} +// +////////////////////////////////////////////////////////////////////////////////// +// +//inline void removeBp(BPOINT_ID Id) { +// return g_dbgClient->removeBp(Id); +//} +// +////////////////////////////////////////////////////////////////////////////////// +// +//inline void removeAllBp() { +// return g_dbgClient->removeAllBp(); +//} //////////////////////////////////////////////////////////////////////////////// -inline BPOINT_ID setHardwareBp(ULONG64 addr, ULONG size, ULONG accessType, BpCallback &callback = BpCallback()) { - return g_dbgClient->setHardwareBp(addr, size, accessType, callback); -} +} // end pykd namespace -//////////////////////////////////////////////////////////////////////////////// - -inline python::list getAllBp() { - return g_dbgClient->getAllBp(); -} - -//////////////////////////////////////////////////////////////////////////////// - -inline void removeBp(BPOINT_ID Id) { - return g_dbgClient->removeBp(Id); -} - -//////////////////////////////////////////////////////////////////////////////// - -inline void removeAllBp() { - return g_dbgClient->removeAllBp(); -} - -//////////////////////////////////////////////////////////////////////////////// - -} // namespace pykd - -//////////////////////////////////////////////////////////////////////////////// diff --git a/pykd/dbgengine.h b/pykd/dbgengine.h index 581ffdd..76e35c2 100644 --- a/pykd/dbgengine.h +++ b/pykd/dbgengine.h @@ -62,5 +62,8 @@ struct STACK_FRAME_DESC { ULONG getStackTraceFrameCount(); void getStackTrace( STACK_FRAME_DESC* frames, ULONG frameCount, ULONG* frameReturned = NULL ); +//breakpoints +ULONG breakPointSet( ULONG64 offset, bool hardware = false, ULONG size = 0, ULONG accessType = 0 ); + }; diff --git a/pykd/pykd_2008.vcproj b/pykd/pykd_2008.vcproj index 79d6600..49ca1f4 100644 --- a/pykd/pykd_2008.vcproj +++ b/pykd/pykd_2008.vcproj @@ -349,6 +349,10 @@ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" > + + @@ -451,6 +455,10 @@ Filter="h;hpp;hxx;hm;inl;inc;xsd" UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" > + + diff --git a/pykd/pymod.cpp b/pykd/pymod.cpp index efbab75..5c72467 100644 --- a/pykd/pymod.cpp +++ b/pykd/pymod.cpp @@ -19,6 +19,7 @@ #include "disasm.h" #include "stkframe.h" #include "localvar.h" +#include "bpoint.h" #include "win/dbgio.h" #include "win/windbg.h" @@ -55,6 +56,9 @@ BOOST_PYTHON_FUNCTION_OVERLOADS( compareMemory_, compareMemory, 3, 4 ); BOOST_PYTHON_FUNCTION_OVERLOADS( getSourceLine_, getSourceLine, 0, 1 ); BOOST_PYTHON_FUNCTION_OVERLOADS( getSourceFile_, getSourceFile, 0, 1 ); +BOOST_PYTHON_FUNCTION_OVERLOADS( setSoftwareBp_, setSoftwareBp, 1, 2 ); +BOOST_PYTHON_FUNCTION_OVERLOADS( setHardwareBp_, setHardwareBp, 3, 4 ); + BOOST_PYTHON_MODULE( pykd ) { python::scope().attr("version") = pykdVersion; @@ -106,7 +110,7 @@ BOOST_PYTHON_MODULE( pykd ) "Return effective pointer size" ); python::def( "is64bitSystem", &is64bitSystem, "Check if target system has 64 address space" ); - python::def( "getPageSize", &getPageSize, + python::def( "pageSize", &getPageSize, "Get the page size for the currently executing processor context" ); // Manage target memory access @@ -217,6 +221,13 @@ BOOST_PYTHON_MODULE( pykd ) "Return a current stack as a list of stackFrame objects" ); python::def( "getLocals", &getLocals, "Get list of local variables" ); + // breakpoints + python::def( "setBp", &setSoftwareBp, setSoftwareBp_( python::args( "offset", "callback" ), + "Set software breakpoint on executiont" ) ); + python::def( "setBp", &setHardwareBp, setHardwareBp_( python::args( "offset", "size", "accsessType", "callback" ) , + "Set hardware breakpoint" ) ); + + python::class_( "intBase", "intBase", python::no_init ) .def( python::init() ) .def( "__eq__", &intBase::eq ) diff --git a/pykd/win/dbgeng.cpp b/pykd/win/dbgeng.cpp index c21a092..b39d00d 100644 --- a/pykd/win/dbgeng.cpp +++ b/pykd/win/dbgeng.cpp @@ -769,6 +769,67 @@ std::string getProcessorType() return processorToStr(processorMode); } +/////////////////////////////////////////////////////////////////////////////// + +ULONG breakPointSet( ULONG64 offset, bool hardware, ULONG size, ULONG accessType ) +{ + PyThread_StateRestore pyThreadRestore( g_dbgEng->pystate ); + + HRESULT hres; + + IDebugBreakpoint *bp; + hres = g_dbgEng->control->AddBreakpoint( + hardware ? DEBUG_BREAKPOINT_DATA : DEBUG_BREAKPOINT_CODE, + DEBUG_ANY_ID, + &bp); + if (S_OK != hres) + throw DbgException("IDebugControl::AddBreakpoint", hres); + + hres = bp->SetOffset(offset); + if (S_OK != hres) + { + g_dbgEng->control->RemoveBreakpoint(bp); + throw DbgException("IDebugBreakpoint::SetOffset", hres); + } + + ULONG bpFlags; + hres = bp->GetFlags(&bpFlags); + if (S_OK != hres) + { + g_dbgEng->control->RemoveBreakpoint(bp); + throw DbgException("IDebugBreakpoint::GetFlags", hres); + } + + bpFlags |= DEBUG_BREAKPOINT_ENABLED; + hres = bp->SetFlags(bpFlags); + if (S_OK != hres) + { + g_dbgEng->control->RemoveBreakpoint(bp); + throw DbgException("IDebugBreakpoint::SetFlags", hres); + } + + if ( hardware ) + { + HRESULT hres = bp->SetDataParameters(size, accessType); + if (S_OK != hres) + { + g_dbgEng->control->RemoveBreakpoint(bp); + throw DbgException("IDebugBreakpoint::SetDataParameters", hres); + } + } + + ULONG breakId; + hres = bp->GetId(&breakId); + if (S_OK != hres) + { + g_dbgEng->control->RemoveBreakpoint(bp); + throw DbgException("IDebugBreakpoint::GetId", hres); + } + + return breakId; +} + + /////////////////////////////////////////////////////////////////////////////// } // end pykd namespace