另一个过程中的断点处理 [英] Breakpoint handling in another process
问题描述
按照读取eax寄存器中给出的建议,我使用winapi编写了一个简单的调试器. 我的目标是每次在另一个线程中执行汇编指令后,都要读取eax寄存器. 它正在运行,我设法在另一个过程中放置了一个硬件断点.
Following advices given in Read eax register , I wrote a simple debugger using winapi. My objective is to read the eax register each time after an assembly instruction is executed in another thread. It is working and I managed to put an hardware breakpoint in another process.
当断点到达调试对象线程内部时,就会出现问题,我可以按预期读取eax寄存器,但是我仍然找不到任何方法来恢复线程的执行.
The problem arise when the breakpoint is reach inside the debuggee thread, I can read the eax register as intended, but I still couldn't find any way to resume the thread's execution.
我的代码:
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;
}
感谢帮助!
推荐答案
由此而来:整个逻辑应该如下:
- 添加断点.
- 触发它后,您将删除断点并在EFLAGS(0x100)中设置一个单步"标志
- 下次调用循环时,您将重新启用硬件断点.
因此,您的while循环应如下所示:
So your while-loop should be 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);
}
这篇关于另一个过程中的断点处理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!