Processing a breakpoint in another process

Following the tips in Read eax register , I wrote a simple debugger using winapi. My goal is to read the eax register every time after the build instruction is executed in another thread. It works, and I managed to set a hardware breakpoint in another process.

The problem occurs when the breakpoint reaches inside the debuggee thread, I can read the eax register as expected, but I still could not find a way to resume the thread.

My code is:

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; } 

Thanks for the help!

+4
source share
2 answers

ContinueDebugEvent (dwProcessId, dwThreadId, dwContinueStatus)


That should work! you do not need to change eip. if you want more information, read Writing the main debugger loop

+1
source

Taken from this: Hardware breakpoints EXCEPTION_SINGLE_STEP all the time

All logic should be as follows:

  • Add a breakpoint.
  • After it starts, you remove the breakpoint and set the Single Step flag to EFLAGS (0x100)
  • The next time the loop is called, you turn on the hardware breakpoint again.

So your while loop should look like this:

 while (true) { if (WaitForDebugEvent(&dbgEvent, INFINITE) == 0) break; if (dbgEvent.dwDebugEventCode == EXCEPTION_DEBUG_EVENT && dbgEvent.u.Exception.ExceptionRecord.ExceptionCode == EXCEPTION_SINGLE_STEP) // EXCEPTION_BREAKPOINT { CONTEXT newCtx = {0}; newCtx.ContextFlags = CONTEXT_ALL; GetThreadContext(hThread, &newCtx); if (dbgEvent.u.Exception.ExceptionRecord.ExceptionAddress == (LPVOID)address) { newCtx.Dr0 = newCtx.Dr6 = newCtx.Dr7 = 0; newCtx.EFlags |= (1 << 8); }else{ newCtx.Dr0 = address; newCtx.Dr7 = 0x00000001; newCtx.EFlags &= ~(1 << 8); } SetThreadContext(hThread, &newCtx); } ContinueDebugEvent(dbgEvent.dwProcessId, dbgEvent.dwThreadId, DBG_CONTINUE); } 
+1
source

Source: https://habr.com/ru/post/1480621/


All Articles