飞扬的Blog
主页
登录
父进程调试子进程无法挂VEH和调试的解决方案
"date"
:
"2022-11-06 21:50:17"
"classfiy"
:
"c++"
"author"
:
"飞扬"
"viewTimes"
:
177
返回
## 前言 最近遇到一款游戏是利用父进程调用`CreateProcess`将`dwCreationFlags`参数包含`DEBUG_PROCESS`创建的子进程, 导致VEH断点无法生效。原因就是父进程内的`WaitForDebugEvent`函数没有处理或者没有正确的给`ContinueDebugEvent`附加正确的参数导致。 ###解决方案如下: 一般此种方式代码如下: ```c++ DEBUG_EVENT debug_event; if (DebugActiveProcess(pid)) { while (WaitForDebugEvent(&debug_event, -1)) { ... ContinueDebugEvent(debug_event.dwProcessId, debug_event.dwThreadId, DBG_EXCEPTION_NOT_HANDLED); } } ``` 反汇编代码: ``` 0x00001 push -01 0x00002 lea eax,[ebp-74] //debug_event地址 0x00003 push eax 0x00004 call WaitForDebugEvent 0x00005 test eax,eax 0x00006 je xxxx 0x00007 mov xxxxx //在while内部找个地方hook就行。例如hook这里,进入循环的第一条语句 0x00008 push xxxx 0x00009 call ContinueDebugEvent ``` ```c++ static LPDEBUG_EVENT pdbg_event; _declspec(naked) void hooker() { _asm { //获取DEBUG_EVENT地址 lea eax, [ebp - 0x74] mov pdbg_event, eax pushad //调用处理函数 call processer //如果处理函数返回1则经过了anywhere_build VEH断点 cmp eax, 1 //跳到WaitDebugEvent je _BACK //否则跳到原有异常处理位置 popad //调用hook掉的代码 mov xxxxx push xxxx //调到继续执行 jmp 0x00009 } _BACK: _asm { popad jmp 0x00001 //跳到调用WaitForDebugEvent的头部 push -01 的地址 } } BOOL WINAPI processer() { DWORD exAddr = (DWORD)pdbg_event->u.Exception.ExceptionRecord.ExceptionAddress; //判断是否是veh_hook_address if (exAddr == veh_hook_address) { ContinueDebugEvent(pdbg_event->dwProcessId, pdbg_event->dwThreadId, DBG_EXCEPTION_NOT_HANDLED); return TRUE; } else { auto ex = pdbg_event->u.Exception.ExceptionRecord; //判断是否为调试器断点 switch (ex.ExceptionCode) { case EXCEPTION_BREAKPOINT: case EXCEPTION_SINGLE_STEP: { printf(">> 处理调试Exception,dwDebugEventCode:%d", pdbg_event->dwDebugEventCode); ContinueDebugEvent(pdbg_event->dwProcessId, pdbg_event->dwThreadId, DBG_EXCEPTION_NOT_HANDLED); return TRUE; } default: break; } } printf("处理原有Exception,dwDebugEventCode:%d", pdbg_event->dwDebugEventCode); return FALSE; } ```