在Read eax register中給出的以下建議,我用winapi寫了一個簡單的調試器。 我的目標是每次在另一個線程中執行彙編指令後讀取eax寄存器。 它正在工作,我設法在另一個進程中放置一個硬件斷點。在另一個進程中處理斷點
當調試線程內部出現斷點時,我可以按照預期讀取eax寄存器,但仍然找不到恢復線程執行的任何方法。
我的代碼:
int _tmain(int argc, _TCHAR* argv[])
{
// Finding Window
HWND window = FindWindow(0, _T("Test"));
if(window == 0)
{
printf("Process not found!\n");
return 0;
}
DWORD_PTR pID = 0;
GetWindowThreadProcessId(window, &pID);
// Get Handle
//HANDLE _handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pID);
DWORD_PTR eax = 0;
DWORD_PTR address = 0xC31E1B; // address of the instruction after the call for hardware breakpoint
DebugActiveProcess(pID); // PID of target process
// Avoid killing app on exit
DebugSetProcessKillOnExit(false);
// get thread ID of the main thread in process
DWORD_PTR dwThreadID = GetProcessThreadID(pID);
// gain access to the thread
HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, FALSE, dwThreadID);
SetDebugPrivilege(true);
//ctx.Dr6=0; //clear debug status register (only bits 0-3 of dr6 are cleared by processor)
CONTEXT ctx = {0};
ctx.ContextFlags = CONTEXT_DEBUG_REGISTERS | CONTEXT_INTEGER;
ctx.Dr0 = address;
ctx.Dr7 = 0x00000001;
// hThread with enough permissions
SetThreadContext(hThread, &ctx);
DEBUG_EVENT dbgEvent;
while (true)
{
if (WaitForDebugEvent(&dbgEvent, INFINITE) == 0)
break;
if (dbgEvent.dwDebugEventCode == EXCEPTION_DEBUG_EVENT &&
dbgEvent.u.Exception.ExceptionRecord.ExceptionCode == EXCEPTION_SINGLE_STEP) // EXCEPTION_BREAKPOINT
{
if (dbgEvent.u.Exception.ExceptionRecord.ExceptionAddress == (LPVOID)address)
{
GetThreadContext(hThread, &ctx);
eax = ctx.Eax; // eax get
std::cout<<eax<<"\n";
// Resume execution
ctx.Eip = address + 0x3;
SetThreadContext(hThread, &ctx);
}
}
ContinueDebugEvent(dbgEvent.dwProcessId, dbgEvent.dwThreadId, DBG_CONTINUE);
}
return 0;
}
感謝您的幫助!
對於一個斷點,您通常使用int 3,其中(至少乍一看)增加3到EIP看起來只有一個字節,所以錯誤。此外,int 3通常會覆蓋現有字節,因此通常會恢復現有字節,設置單步標誌,執行一條指令,在該字節中重新設置int 3,並清除單步標誌。 – 2013-05-14 03:26:22
他使用硬件斷點,所以我認爲沒有什麼可以恢復。 – schlicht 2014-02-21 16:48:58
@alkapone你設法做到這一點嗎? – victor 2015-10-20 09:20:00