-
-
未解决 [求助]硬件断点没有生效 10雪币
-
发表于: 2024-8-8 23:07 1437
-
硬件断点没生效,帮我看看,谢谢。
#include <windows.h> #include <stdio.h> //系统断点 BOOL isSystemInt3 = TRUE; //被调试进程 HANDLE debugProcess = NULL; //被调试线程 HANDLE debugThread = NULL; //被int3覆盖的原数据 CHAR oldData = 0; //旧的页属性 DWORD oldProtect = 0; DWORD Protect = 0; BOOL WaitForUserCommand() { BOOL ret = FALSE; CHAR cmd; printf("COMMAND>"); cmd = getchar(); switch (cmd) { case 't': ret = TRUE; break; case 'p': ret = TRUE; break; case 'g': ret = TRUE; break; default: break; } getchar(); return ret; } VOID SetInt3BreakPoint(PUCHAR addr) { CHAR data = 0xCC; ReadProcessMemory(debugProcess, addr, &oldData, 1, NULL); WriteProcessMemory(debugProcess, addr, &data, 1, NULL); } VOID SetMemBreakPoint(PUCHAR addr) { //访问断点 VirtualProtectEx(debugProcess, addr, 0x1000, PAGE_NOACCESS, &oldProtect); //写入断点 //VirtualProtectEx(debugProcess, addr, 0x1000, PAGE_EXECUTE_READ, &oldProtect); } VOID SetHardBreakPoint(PUCHAR addr) { CONTEXT threadContext = { 0 }; SuspendThread(debugThread); threadContext.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS; BOOL ret = GetThreadContext(debugThread, &threadContext); printf("GetThreadContext = %d \r\n", ret); //设置断点位置 threadContext.Dr0 = (DWORD64)addr; threadContext.Dr7 |= 0x1; // 启用 Dr0 ret = SetThreadContext(debugThread, &threadContext); ResumeThread(debugThread); printf("SetThreadContext = %d \r\n", ret); } BOOL Int3ExceptionHandler(EXCEPTION_DEBUG_INFO* info) { CONTEXT threadContext = { 0 }; BOOL ret = FALSE; //1、将INT3修复为原来的数据,如果是系统断点,不用修复 if (isSystemInt3) { isSystemInt3 = FALSE; return TRUE; } else { WriteProcessMemory(debugProcess, info->ExceptionRecord.ExceptionAddress, &oldData, 1, NULL); } //2、显示断点位置 printf("int3断点 => 0x%p \r\n", info->ExceptionRecord.ExceptionAddress); //3、获取线程上下文 SuspendThread(debugThread); threadContext.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS; GetThreadContext(debugThread, &threadContext); //4、修正EIP threadContext.Rip--; SetThreadContext(debugThread, &threadContext); ResumeThread(debugThread); //设置硬件断点 SetHardBreakPoint((PUCHAR)info->ExceptionRecord.ExceptionAddress + 1); //5、显示反汇编代码 //6、等待用户命令 while (ret == FALSE) { ret = WaitForUserCommand(); } return ret; } BOOL AccessExceptionHandler(EXCEPTION_DEBUG_INFO* info) { CONTEXT threadContext = { 0 }; BOOL ret = FALSE; //1、获取异常信息,修改内存属性 ULONG_PTR flag = info->ExceptionRecord.ExceptionInformation[0]; //访问类型 0读 1写 ULONG_PTR addr = info->ExceptionRecord.ExceptionInformation[1]; //访问地址 printf("内存断点 %llx %llx \r\n", flag, addr); VirtualProtectEx(debugProcess, (LPVOID)addr, 0x1000, oldProtect, &Protect); //2、获取线程上下文 SuspendThread(debugThread); threadContext.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS; GetThreadContext(debugThread, &threadContext); printf("Rip => 0x%llx \r\n", threadContext.Rip); SetThreadContext(debugThread, &threadContext); ResumeThread(debugThread); while (ret == FALSE) { ret = WaitForUserCommand(); } return ret; } BOOL SingleExceptionHandler(EXCEPTION_DEBUG_INFO* info) { CONTEXT threadContext = { 0 }; BOOL ret = FALSE; //获取线程上下文 SuspendThread(debugThread); threadContext.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS; GetThreadContext(debugThread, &threadContext); //判断是否是硬件断点导致的异常 if (threadContext.Dr6 & 0xF) { printf("硬件断点 %llx %llx \r\n", threadContext.Dr7 & 0x00030000, threadContext.Dr0); //将断点去除 threadContext.Dr0 = 0; threadContext.Dr7 &= ~1; } else { } SetThreadContext(debugThread, &threadContext); ResumeThread(debugThread); while (ret == FALSE) { ret = WaitForUserCommand(); } return ret; } BOOL exceptionHandler(DEBUG_EVENT* debugEvent) { BOOL ret = TRUE; EXCEPTION_DEBUG_INFO* info = &debugEvent->u.Exception; //得到线程句柄,后面要用 debugThread = OpenThread(THREAD_ALL_ACCESS, FALSE, debugEvent->dwThreadId); switch (info->ExceptionRecord.ExceptionCode) { //int3异常 case EXCEPTION_BREAKPOINT: { ret = Int3ExceptionHandler(info); } break; //访问异常 case EXCEPTION_ACCESS_VIOLATION: { ret = AccessExceptionHandler(info); } break; //单步处理 case EXCEPTION_SINGLE_STEP: { ret = SingleExceptionHandler(info); } break; default: break; } return ret; } int main() { BOOL isContinue = TRUE; DEBUG_EVENT debugEvent = { 0 }; BOOL ret = TRUE; DWORD dwContinue = DBG_CONTINUE; STARTUPINFO si = { 0 }; PROCESS_INFORMATION pi = { 0 }; GetStartupInfo(&si); //1、创建调试进程 ret = CreateProcess(TEXT("C:\\Windows\\notepad.exe"), NULL, NULL, NULL, TRUE, DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS, NULL, NULL, &si, &pi); if (!ret) { printf("CreateProcess %d \r\n", GetLastError()); return 0; } debugProcess = pi.hProcess; //2、调试循环 while (isContinue) { ret = WaitForDebugEvent(&debugEvent, INFINITE); if (!ret) { printf("WaitForDebugEvent %d \r\n", GetLastError()); return 0; } switch (debugEvent.dwDebugEventCode) { case EXCEPTION_DEBUG_EVENT: { ret = exceptionHandler(&debugEvent); if (!ret) { dwContinue = DBG_EXCEPTION_NOT_HANDLED; } } break; case CREATE_THREAD_DEBUG_EVENT: { } break; case CREATE_PROCESS_DEBUG_EVENT: { //进程创建的时候,在OEP处设置断点 SetInt3BreakPoint((PUCHAR)debugEvent.u.CreateProcessInfo.lpStartAddress); //进程创建的时候,在OEP处设置内存访问断点 //SetMemBreakPoint((PUCHAR)debugEvent.u.CreateProcessInfo.lpStartAddress); } break; case EXIT_THREAD_DEBUG_EVENT: { } break; case EXIT_PROCESS_DEBUG_EVENT: { } break; case LOAD_DLL_DEBUG_EVENT: { } break; case UNLOAD_DLL_DEBUG_EVENT: { } break; } //DBG_CONTINUE 表示调方式器已经处理了异常 //DBG_EXCEPTION_NOT_HANDLED 表示调试器没有处理该异常,转回到用户态中执行,寻找可以处理该异常的异常处理器 ret = ContinueDebugEvent(debugEvent.dwProcessId, debugEvent.dwThreadId, dwContinue); } return 0; }
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)
赞赏
看原图
赞赏
雪币:
留言: