我在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它,我要你忽略,因爲這是一個完全有效的問題。如果你繼續問這樣的問題,你將有一個美好的時光在這裏。) –