我有一个充当调试器的程序。我为线程设置dr0设置了一个hw bp到我想要bp的地址,dr7设置为1,因为我希望每次执行该地址时bp都会生成一个事件。
它有效,但问题是我不会一直停止接收EXCEPTION_SINGLE_STEP。我正常使用WaitForDebugEvent创建一个循环:
DebugActiveProcess(pid);
while (flag == 0)
{
WaitForDebugEvent(&DBEvent, INFINITE);
if (first_time){
setHWBPInCurrentThreads(pid, breakpoint_address);
first_time = 0;
}
switch (DBEvent.dwDebugEventCode)
{
// Here we check if a new thread is created and we set a BP for all of them
case CREATE_THREAD_DEBUG_EVENT:
{
HANDLE thread_handle = DBEvent.u.CreateProcessInfo.hProcess;
HANDLE hX3 = SetHardwareBreakpoint(thread_handle, HWBRK_TYPE_CODE, HWBRK_SIZE_1, breakpoint_address);
}break;
case EXCEPTION_DEBUG_EVENT:
{
switch (DBEvent.u.Exception.ExceptionRecord.ExceptionCode)
{
case EXCEPTION_SINGLE_STEP:
{
printf("%d\n", DBEvent.dwThreadId);
///MessageBoxA(0, "yesssssssss", "", 0);
}break;
case EXCEPTION_BREAKPOINT:
{
//MessageBoxA(0, "Found break point", "", 0);
}break;
}
}break;
}
ContinueDebugEvent(DBEvent.dwProcessId, DBEvent.dwThreadId, DBG_CONTINUE);
}
这里有什么问题?我该怎么办才能让异常继续下去,只有在下次执行地址时才能获得控件?
答案 0 :(得分:5)
您的实现只是在命中断点后继续调试事件,这将在无限循环中再次触发断点。
根据您使用的环境,需要以不同方式处理正确的实现。如果您在比Windows XP更新的环境中进行调试,则处理断点的方式是:
如果您在Windows XP环境中工作,则需要将您的实施更改为:
很抱歉打破这个旧线程,但这些是正确的实现。
答案 1 :(得分:3)
我终于知道发生了什么:
hw bp的工作方式与软件bp不同。使用软件断点,您只需调用ContinueDebugEvent
并等待下一个事件发生(达到bp)。
使用HW bp,您需要首先重置Dr0-Dr3,Dr6和Dr7寄存器,然后调用ContinueDebugEvent
,然后再次设置寄存器,就像生成事件时那样。这令人困惑,因为ContinueDebugEvent
的行为与软件断点的行为方式不同。
我希望这可以帮助其他人解决同样的问题。
干杯