另一个进程中的断点处理
Breakpoint handling in another process
根据在读取eax寄存器中给出的建议,我使用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;
}
谢谢你的帮助!
由此得出:硬件断点EXCEPTION_SINGLE_STEP一直
整个逻辑应该如下:
- 添加断点。
- 触发它后,您删除断点并在EFLAGS (0x100) 中设置单个步骤标志。
- 下次调用循环时,重新启用硬件断点。
那么你的while-loop应该是这样的:
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);
}
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);
std::cout << ctx.Eax << "n";
ctx.Dr7 = 0;
SetThreadContext(hThread, &ctx);
}
}
在ctx中禁用Dr7中的Dr0应该可以完成这项工作。其他注释不能解决这个问题)
ContinueDebugEvent(dwProcessId, dwThreadId, dwContinueStatus)
这个应该可以了!您不需要更改eip。如果您想了解更多信息,请阅读写调试器的主循环
相关文章:
- 警告处理为错误这里有什么问题
- 在C#中处理C++指针而不使用unsafe的最佳方法
- 处理多个异常集合的C++方法
- 找不到成员对象:没有名为get_event()的成员,也处理多态性和向量
- 使用流处理接收到的数据
- 获取日期异步信号安全吗?如果在信号处理程序中使用,它会导致死锁吗
- 处理小于cpu数据总线的数据类型.(c++转换为机器代码)
- 基于多个条件处理地图中的所有元素
- 如何用数字处理log(0)
- SSL上的`curl_easy_send`和`curl_asy_recv`:如何处理`CURLE_AGAIN`
- 错误处理.将系统错误代码映射到泛型
- 从文本文件中读取时钟时间和事件时间并进行处理
- 在运行时处理类型擦除的数据-如何不重新发明轮子
- 在for循环中使用auto vs decltype(vec.size())来处理字符串的向量
- 用于矢量处理的多个线程
- 对字符串进行排序时,在c++中处理sort()
- 如何处理linux终端中带有负号(-)的C++中的命令行参数
- 处理除以零会导致<csignal>意外行为
- 无法删除指针,已触发断点
- 另一个进程中的断点处理