本帖最后由 blbljj008 于 2023-5-31 19:06 编辑
刚刚学会了硬件断点的编写,先分享一波
第一步,添加VEH异常处理
AddVectoredExceptionHandler(1, (PVECTORED_EXCEPTION_HANDLER)ExceptionFilter);
第二步,设置要hook的地址
SetSehHook();
第三步,调用api引发异常
MessageBoxA(NULL, "349561280", "349561280", MB_OK);
具体代码
[C] 纯文本查看 复制代码 void SetSehHook()
{
g_HookAddr = (DWORD)GetProcAddress(GetModuleHandle(L"user32.dll"), "MessageBoxA");
g_HookAddrOffset = g_HookAddr + 2;
//遍历线程 通过openthread获取到线程环境后设置硬件断点
HANDLE hTool32 = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
if (hTool32 != INVALID_HANDLE_VALUE)
{
//线程环境结构体
THREADENTRY32 thread_entry32;
thread_entry32.dwSize = sizeof(THREADENTRY32);
HANDLE hHookThread = NULL;
//遍历线程
if (Thread32First(hTool32, &thread_entry32))
{
do
{
//如果线程父进程ID为当前进程ID
if (thread_entry32.th32OwnerProcessID == GetCurrentProcessId())
{
hHookThread = OpenThread(THREAD_SET_CONTEXT | THREAD_GET_CONTEXT | THREAD_QUERY_INFORMATION, FALSE, thread_entry32.th32ThreadID);
SuspendThread(hHookThread);//暂停线程
//设置硬件断点
CONTEXT thread_context = { CONTEXT_DEBUG_REGISTERS };
thread_context.Dr0 = g_HookAddr;
thread_context.Dr7 = 0x405;
//设置线程环境 这里抛异常了
DWORD oldprotect;
VirtualProtect((LPVOID)g_HookAddr, 5, PAGE_EXECUTE_READWRITE, &oldprotect);//修改PTE p=1 r/w1=0
SetThreadContext(hHookThread, &thread_context);
ResumeThread(hHookThread);//线程跑起来吧~~~
CloseHandle(hHookThread);
}
} while (Thread32Next(hTool32, &thread_entry32));
}
CloseHandle(hTool32);
}
}
[C] 纯文本查看 复制代码 LONG NTAPI ExceptionFilter(PEXCEPTION_POINTERS ExceptionInfo)
{
//判断当前异常码是否为硬件断点异常
if (ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_SINGLE_STEP)
{
//判断发生异常的地址是否和hook的地址一致
if ((DWORD)ExceptionInfo->ExceptionRecord->ExceptionAddress == g_HookAddr)
{
//获取当前线程上下文
PCONTEXT pcontext = ExceptionInfo->ContextRecord;
//打印测试是否处理了异常
printf("Num--d, Addr--08X, list--08X \n");
//修复EIP
pcontext->Eip = (DWORD)&OriginalFunc;
//异常处理完成 让程序继续执行
return EXCEPTION_CONTINUE_EXECUTION;
}
}
return EXCEPTION_CONTINUE_SEARCH;
}
现在求助内存断点的写法,因为硬件断点只能断代码,对于数据段,是不能执行的,数据段只能访问和写入操作,所以要用到内存断点
我现在研究明白了流程,内存断点也可以下了,但是异常处理这块没有写明白
原理是
1. 内存断点的设置
内存断点分为两类:访问断点与写入断点。
其本质是调用 VirtualProtected 来修改页(PTE)属性。
1)访问断点,则将页的属性设置为 PAGE_NOACCESS。
2)写入断点,PAGE_EXECUTE_READ。
这步已经实现
2. 内存断点的异常处理流程应该在下断点之前,添加好异常处理,
比如内存地址=0xA8022C,我已经下好内存断点
据说引发 AccessViolationException 异常
这步需要求助,如何添加异常处理。 |