我在C++中做了一个非常简单的调试器,除非我调用WaitForDebugEvent
以及dwMilliseconds
之外的任何值,它不会立即暂停调试器。调试器不会暂停异常C++
我有一个if
语句,它检查异常地址是否与我设置的断点地址if(ExceptionDebugInfo.ExceptionRecord.ExceptionAddress == lpBreakpoint)
相匹配。
值减eip
(wow64cntxt.Eip --;
),替换原有的指令(WriteProcessMemory
)断点(int3
)字节,刷新指令缓存(FlushInstructionCache
),然后设置eip
指向我与原来的指令替换断点(Wow64SetThreadContext
)。
然后它返回到主调试循环(break
)并继续调试(ContinueDebugEvent
)。
case EXCEPTION_BREAKPOINT:
{
WOW64_CONTEXT wow64cntxt = {0};
wow64cntxt.ContextFlags = WOW64_CONTEXT_ALL;
if(!Wow64GetThreadContext(hThread, &wow64cntxt))
{
printf("Error getting thread context: %lu\n", GetLastError());
}
//lpFunction is the address of a mov instruction I set a breakpoint on
if(excDbgInfo.ExceptionRecord.ExceptionAddress == lpBreakpoint)
{
printf("EIP-Before: 0x%X\n", wow64cntxt.Eip);
//Decrement eip value to point back to the opcode I wrote over with int3
wow64cntxt.Eip --;
printf("EIP-After: 0x%X\n", wow64cntxt.Eip);
//original opcode I replaced with int3(0xCC)
instr = 0x89;
//replace the breakpoint with the original instruction
if(!WriteProcessMemory(hProcess, lpBreakpoint, &instr, sizeof(CHAR), NULL))
{
printf("Error reversing breakpoint: %lu\n", GetLastError());
}
//Flush the instruction cache
FlushInstructionCache(hProcess, lpBreakpoint, 1);
//Set eip to previous instruction
if(!Wow64SetThreadContext(hThread, &wow64cntxt))
{
printf("Error setting thread context: %lu\n", GetLastError());
}
}
system("pause");
//Return to main debug loop, ContinueDebugEvent...
break;
}
如果我用比INFINITE
与WaitForDebugEvent
然后eip
设置为执行我设置的断点一段时间后的地址以外的任何其他。
问题是,如果我不使用WaitForDebugEvent
和INFINITE
,则当调试器捕获到异常时,eip
已经超过了断点。即使我有WaitForDebugEvent
等待0毫秒,立即返回,这位移动者仍然跑过断点。
这会导致访问冲突,我猜测是因为用断点替换的指令的另一半变成了修改内存的新操作码,所以不允许。
这是我的主要调试循环:
while(1)
{
WaitForDebugEvent(&dbgEvent, INFINITE);
ProcessDebugEvent(&dbgEvent);
ContinueDebugEvent(dbgEvent.dwProcessId, dbgEvent.dwThreadId, DBG_CONTINUE);
}
的任何信息,洞察力,技巧,讲解等将不胜感激。谢谢。
难说你的代码出了什么问题,但是当断点异常处于wow64代码调试器视图STATUS_WX86_BREAKPOINT(0x4000001F)而不是STATUS_BREAKPOINT(0x80000003)时,你可以使用“普通”上下文Get [Set] ThreadContext即使WOW64代码 – RbMm
但是(STATUS_WX86_BREAKPOINT或STATUS_BREAKPOINT依赖是你的调试器64位或32位) – RbMm
顺便说一句,我upvoted这个时候我做了压痕编辑。究其原因是因为,即使这是一个简单的面部掌样的问题,你问得很好,并提出所有必要的信息,以允许其他人来回答。感谢您这样做,并阅读我们的帮助。欢迎来到堆栈溢出! (我想这样说是因为我看到有人downvoted它,我要你忽略,因为这是一个完全有效的问题。如果你继续问这样的问题,你将有一个美好的时光在这里。) –