mirror of
https://github.com/ivellioscolin/pykd.git
synced 2025-04-21 04:13:22 +08:00
[0.1.x] + breakpoints, working by ID
git-svn-id: https://pykd.svn.codeplex.com/svn@73565 9b283d60-5439-405e-af05-b73fd8c4d996
This commit is contained in:
parent
3902000ae8
commit
ebc6910cd6
157
pykd/bpoint.cpp
Normal file
157
pykd/bpoint.cpp
Normal file
@ -0,0 +1,157 @@
|
||||
//
|
||||
// Breakpoints management
|
||||
//
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "bpoint.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace pykd {
|
||||
|
||||
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 ULONG getBpId(IDebugBreakpoint *bp, IDebugControl4 *control = NULL)
|
||||
{
|
||||
ULONG Id;
|
||||
HRESULT hres = bp->GetId(&Id);
|
||||
if (S_OK != hres)
|
||||
{
|
||||
if (control)
|
||||
control->RemoveBreakpoint(bp);
|
||||
throw DbgException("IDebugBreakpoint::GetId", hres);
|
||||
}
|
||||
return Id;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ULONG DebugClient::setSoftwareBp(ULONG64 addr)
|
||||
{
|
||||
addr = addr64(addr);
|
||||
IDebugBreakpoint *bp = setBreakPoint(m_control, DEBUG_BREAKPOINT_CODE, addr);
|
||||
|
||||
return getBpId(bp, m_control);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ULONG DebugClient::setHardwareBp(ULONG64 addr, ULONG size, ULONG accessType)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
return getBpId(bp, m_control);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
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(ULONG 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
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
46
pykd/bpoint.h
Normal file
46
pykd/bpoint.h
Normal file
@ -0,0 +1,46 @@
|
||||
//
|
||||
// Breakpoints management
|
||||
//
|
||||
|
||||
#include "dbgclient.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace pykd {
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline ULONG setSoftwareBp(ULONG64 addr) {
|
||||
return g_dbgClient->setSoftwareBp(addr);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline ULONG setHardwareBp(ULONG64 addr, ULONG size, ULONG accessType) {
|
||||
return g_dbgClient->setHardwareBp(addr, size, accessType);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline python::list getAllBp() {
|
||||
return g_dbgClient->getAllBp();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline void removeBp(ULONG Id) {
|
||||
return g_dbgClient->removeBp(Id);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline void removeAllBp() {
|
||||
return g_dbgClient->removeAllBp();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
} // namespace pykd
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -297,6 +297,15 @@ public:
|
||||
return m_symSymbols;
|
||||
}
|
||||
|
||||
// breakpoints management
|
||||
ULONG setSoftwareBp(ULONG64 addr);
|
||||
ULONG setHardwareBp(ULONG64 addr, ULONG size, ULONG accessType);
|
||||
|
||||
python::list getAllBp();
|
||||
|
||||
void removeBp(ULONG Id);
|
||||
void removeAllBp();
|
||||
|
||||
private:
|
||||
template<typename T>
|
||||
python::list
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "dbgmem.h"
|
||||
#include "intbase.h"
|
||||
#include "process.h"
|
||||
#include "bpoint.h"
|
||||
#include "pykdver.h"
|
||||
|
||||
using namespace pykd;
|
||||
@ -299,6 +300,16 @@ BOOST_PYTHON_MODULE( pykd )
|
||||
"Get context of current thread (register values)" )
|
||||
.def( "getLocals", &DebugClient::getLocals, DebugClient_getLocals( python::args( "ctx" ),
|
||||
"Get list of local variables" ) )
|
||||
.def( "setBp", &DebugClient::setSoftwareBp,
|
||||
"Set software breakpoint on executiont" )
|
||||
.def( "setBp", &DebugClient::setHardwareBp,
|
||||
"Set hardware breakpoint" )
|
||||
.def( "getAllBp", &DebugClient::getAllBp,
|
||||
"Get all breapoint IDs" )
|
||||
.def( "removeBp", &DebugClient::removeBp,
|
||||
"Remove breapoint by IDs" )
|
||||
.def( "removeBp", &DebugClient::removeAllBp,
|
||||
"Remove all breapoints" )
|
||||
.def( "addSynSymbol", &DebugClient::addSyntheticSymbol,
|
||||
"Add new synthetic symbol for virtual address" )
|
||||
.def( "delAllSynSymbols", &DebugClient::delAllSyntheticSymbols,
|
||||
@ -474,6 +485,16 @@ BOOST_PYTHON_MODULE( pykd )
|
||||
"Get context of current thread (register values)" );
|
||||
python::def( "getLocals", &getLocals, getLocals_( python::args( "ctx" ),
|
||||
"Get list of local variables" ) );
|
||||
python::def( "setBp", &setSoftwareBp,
|
||||
"Set software breakpoint on executiont" );
|
||||
python::def( "setBp", &setHardwareBp,
|
||||
"Set hardware breakpoint" );
|
||||
python::def( "getAllBp", &getAllBp,
|
||||
"Get all breapoint IDs" );
|
||||
python::def( "removeBp", &removeBp,
|
||||
"Remove breapoint by IDs" );
|
||||
python::def( "removeBp", &removeAllBp,
|
||||
"Remove all breapoints" );
|
||||
|
||||
python::class_<TypeInfo, TypeInfoPtr, python::bases<intBase>, boost::noncopyable >("typeInfo", "Class representing typeInfo", python::no_init )
|
||||
.def( "name", &TypeInfo::getName )
|
||||
@ -872,6 +893,15 @@ BOOST_PYTHON_MODULE( pykd )
|
||||
DEF_PY_CONST_ULONG(DEBUG_STATUS_REVERSE_STEP_BRANCH);
|
||||
DEF_PY_CONST_ULONG(DEBUG_STATUS_REVERSE_STEP_OVER);
|
||||
DEF_PY_CONST_ULONG(DEBUG_STATUS_REVERSE_STEP_INTO);
|
||||
|
||||
// breakpoints constatns
|
||||
DEF_PY_CONST_ULONG(DEBUG_BREAKPOINT_CODE);
|
||||
DEF_PY_CONST_ULONG(DEBUG_BREAKPOINT_DATA);
|
||||
|
||||
DEF_PY_CONST_ULONG(DEBUG_BREAK_READ);
|
||||
DEF_PY_CONST_ULONG(DEBUG_BREAK_WRITE);
|
||||
DEF_PY_CONST_ULONG(DEBUG_BREAK_EXECUTE);
|
||||
DEF_PY_CONST_ULONG(DEBUG_BREAK_IO);
|
||||
}
|
||||
|
||||
#undef DEF_PY_CONST_ULONG
|
||||
|
@ -349,6 +349,10 @@
|
||||
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\bpoint.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\context.cpp"
|
||||
>
|
||||
@ -483,6 +487,10 @@
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\bpoint.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\context.h"
|
||||
>
|
||||
|
@ -14,6 +14,7 @@ class BreakExceptionHandler(pykd.eventHandler):
|
||||
self.wasSecondChance = False
|
||||
|
||||
self.wasBreakpoint = False
|
||||
self.wasBreakpointIds = []
|
||||
|
||||
self.bpLastModuleName = ""
|
||||
self.bpCount = 0
|
||||
@ -24,6 +25,7 @@ class BreakExceptionHandler(pykd.eventHandler):
|
||||
def onBreakpoint(self, bpId):
|
||||
"""Breakpoint handler"""
|
||||
self.wasBreakpoint = True
|
||||
self.wasBreakpointIds.append( bpId )
|
||||
return pykd.DEBUG_STATUS_NO_CHANGE
|
||||
|
||||
def onException(self, exceptParams):
|
||||
@ -33,7 +35,6 @@ class BreakExceptionHandler(pykd.eventHandler):
|
||||
|
||||
if exceptParams["Code"] == pykd.EXCEPTION_ACCESS_VIOLATION:
|
||||
if self.wasSecondChance:
|
||||
print exceptParams["Parameters"]
|
||||
self.secondChanceAccessAddresses.append( exceptParams["Parameters"][1] )
|
||||
else:
|
||||
self.firstChanceAccessAddresses.append( exceptParams["Parameters"][1] )
|
||||
@ -50,7 +51,23 @@ class EhExceptionBreakpointTest(unittest.TestCase):
|
||||
testClient = pykd.createDbgClient()
|
||||
testClient.startProcess( target.appPath + " -testExceptions" )
|
||||
|
||||
testClient.dbgCommand( ".reload /f; bp targetapp!doExeptions" )
|
||||
targetMod = testClient.loadModule( "targetapp" )
|
||||
|
||||
bpIdSoftware = testClient.setBp( targetMod.offset("changeValueForAccessTesting") )
|
||||
|
||||
bpIdHwExecute = testClient.setBp( targetMod.offset("readValueForAccessTesting"),
|
||||
1,
|
||||
pykd.DEBUG_BREAK_EXECUTE )
|
||||
|
||||
bpIdHwWrite = testClient.setBp( targetMod.offset("g_valueForAccessTesting1"),
|
||||
1,
|
||||
pykd.DEBUG_BREAK_WRITE )
|
||||
|
||||
bpIdHwRead = testClient.setBp( targetMod.offset("g_valueForAccessTesting2"),
|
||||
1,
|
||||
pykd.DEBUG_BREAK_READ )
|
||||
|
||||
self.assertEqual( 4, len( testClient.getAllBp() ) )
|
||||
|
||||
breakExceptionHandler = BreakExceptionHandler( testClient )
|
||||
while not breakExceptionHandler.wasSecondChance:
|
||||
@ -63,3 +80,11 @@ class EhExceptionBreakpointTest(unittest.TestCase):
|
||||
self.assertEqual( 2, breakExceptionHandler.bpCount ) # main and doExeptions
|
||||
|
||||
self.assertEqual( [3, ], breakExceptionHandler.secondChanceAccessAddresses )
|
||||
|
||||
self.assertTrue( bpIdSoftware in breakExceptionHandler.wasBreakpointIds )
|
||||
|
||||
testClient.removeBp(bpIdHwRead)
|
||||
self.assertEqual( 3, len( testClient.getAllBp() ) )
|
||||
|
||||
testClient.removeBp()
|
||||
self.assertEqual( 0, len( testClient.getAllBp() ) )
|
||||
|
@ -343,10 +343,34 @@ int doLoadUnload()
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int g_valueForAccessTesting1 = 4;
|
||||
int g_valueForAccessTesting2 = 5;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma optimize("g", off)
|
||||
void changeValueForAccessTesting()
|
||||
{
|
||||
g_valueForAccessTesting1 = 5;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void readValueForAccessTesting()
|
||||
{
|
||||
std::cout << g_valueForAccessTesting1 << g_valueForAccessTesting2;
|
||||
}
|
||||
#pragma optimize("g", on)
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int doExeptions()
|
||||
{
|
||||
changeValueForAccessTesting();
|
||||
|
||||
readValueForAccessTesting();
|
||||
|
||||
__debugbreak();
|
||||
|
||||
PUCHAR _ptr = reinterpret_cast<UCHAR *>(2);
|
||||
|
Loading…
Reference in New Issue
Block a user