windows中如何检测自己的程序被下了硬件断点
写了调试器A(好吧这是个外挂)和测试程序B
用A给B下硬件断点,hook了
Wow64GetThreadContext
,处理断点异常时,先取ESP+8(最先进栈的最右参,寄存器的缓存结构体),对着*(*(ESP+8)+4)WriteProcessMemory了24位0(**(ESP)是寄存器结构体的第一个字节,从4至28是DR0,DR1,DR2,DR3,DR6,DR7)。在B中用
Wow64GetThreadContext
和
GetThreadContext
都读不出DR0-DR7了。测了无数遍调试器A和程序B都没bug。
但是在11对战平台还是被检测了,log上
Wow64GetThreadContext
都没被执行。。。
所以想问除了
Wow64GetThreadContext
和
GetThreadContext
之外有其他的获取硬件断点的方法吗?11又是用了哪种?
调试器A处理异常的代码如下
#define Wow64GetThreadContext_ADDRESS 0x279BC #define Wow64GetThreadContext_ADDRESS_END 0x279CF #define BREAK_OPEN 0x405 //hopen是B进程句柄,FindKernel32是自己写的暴力搜索Kernel32基址的方法,保证没bug,11也没隐藏Kernel32 FindKernel32(hopen,&kernel32Handle); DWORD wow64GetThreadContextBreakBegin = kernel32Handle + Wow64GetThreadContext_ADDRESS; DWORD wow64GetThreadContextBreakEnd = kernel32Handle + Wow64GetThreadContext_ADDRESS_END; if(exceptionAddress == wow64GetThreadContextBreakBegin) { HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, FALSE, DebugEv.dwThreadId); SuspendThread(hThread); CONTEXT Regs = {0}; Regs.ContextFlags = CONTEXT_DEBUG_REGISTERS|CONTEXT_INTEGER|CONTEXT_CONTROL; ::GetThreadContext(hThread, &Regs); Regs.Dr1=wow64GetThreadContextBreakEnd; Regs.Dr7=BREAK_OPEN; DWORD contextPointer = Regs.Esp + 0x8; bret=ReadProcessMemory(hopen,(LPVOID)(contextPointer),&wow64GetContextEAX,4,0); ::SetThreadContext(hThread, &Regs); ResumeThread(hThread); CloseHandle(hThread); } if(exceptionAddress == wow64GetThreadContextBreakEnd) { HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, FALSE, DebugEv.dwThreadId); SuspendThread(hThread); CONTEXT Regs = {0}; Regs.ContextFlags = CONTEXT_ALL;//CONTEXT_DEBUG_REGISTERS|CONTEXT_INTEGER; ::GetThreadContext(hThread, &Regs); Regs.Dr1=wow64GetThreadContextBreakBegin; Regs.Dr7=BREAK_OPEN; if(wow64GetContextEAX) { DWORD buffer[24] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; SIZE_T writedCount; bret=WriteProcessMemory(hopen, (LPVOID)(wow64GetContextEAX + 4), &buffer, 24, &writedCount); } ::SetThreadContext(hThread, &Regs); ResumeThread(hThread); CloseHandle(hThread); }
测试程序B的代码
int main(int argc, char* argv[]) { while(1) { Sleep(1000); HANDLE thread = GetCurrentThread(); { WOW64_CONTEXT context; context.ContextFlags = CONTEXT_ALL; BOOL status = Wow64GetThreadContext(thread, &context); if (!status) { return -1; } printf("WGTC %08x %08x %08x %08x %08x %08x %08x %08x\n", &context, context.ContextFlags, context.Dr0, context.Dr1, context.Dr2, context.Dr3, context.Dr6, context.Dr7); } { static CONTEXT threadContext; memset(&threadContext, 0, sizeof(CONTEXT)); threadContext.ContextFlags = CONTEXT_ALL; BOOL status = GetThreadContext(thread, &threadContext); printf("GTC %08x %08x %08x %08x %08x %08x %08x %08x\n", &threadContext, threadContext.ContextFlags, threadContext.Dr0, threadContext.Dr1, threadContext.Dr2, threadContext.Dr3, threadContext.Dr6, threadContext.Dr7); } } return 0; }
天然星☆↗
11 years, 4 months ago