Break instruction exception - code 80000003 (first chance)
0033:00007ff7`ca9816a3 cc int 3
kd> g
Hook system initialized
Hooking SendMessageW at address: 0x00007FFB8F95D5B0
Hook set successfully
Test window created
Sending test message… 没有输出"Message hooked at: …"(其中…是消息参数的地址)。#include <Windows.h>
#include <vector>
#include <string>
#include <intrin.h>
#include <mutex>
// 回调函数类型定义
typedef bool (*HOOKBACK2)(PCONTEXT);
// 硬件断点结构
struct DbgPoint {
LPVOID Address;
HOOKBACK2 DestCall;
LPVOID AddressRet;
};
// 硬件断点管理器
class DbgPointManager {
private:
std::vector<DbgPoint> points;
std::mutex mtx; // 线程安全锁
public:
// 添加硬件断点
bool AddHookPoint(LPVOID Address, HOOKBACK2 hookBack, LPVOID AddressRet = nullptr) {
std::lock_guard<std::mutex> lock(mtx);
if (points.size() >= 4) return false; // DR0-DR3只有4个
points.push_back({ Address, hookBack, AddressRet });
return true;
}
// 查找断点
DbgPoint* FindPoint(LPVOID Address) {
std::lock_guard<std::mutex> lock(mtx);
for (auto& point : points) {
if (point.Address == Address) return &point;
}
return nullptr;
}
// 启用硬件断点
void OpenDbg(PCONTEXT context) {
std::lock_guard<std::mutex> lock(mtx);
context->Dr0 = 0;
context->Dr1 = 0;
context->Dr2 = 0;
context->Dr3 = 0;
if (points.size() > 0) context->Dr0 = (ULONG_PTR)points[0].Address;
if (points.size() > 1) context->Dr1 = (ULONG_PTR)points[1].Address;
if (points.size() > 2) context->Dr2 = (ULONG_PTR)points[2].Address;
if (points.size() > 3) context->Dr3 = (ULONG_PTR)points[3].Address;
// 设置断点类型:执行断点 (00 = 执行, 01 = 写, 10 = IO, 11 = 读写)
context->Dr7 = 0;
if (points.size() > 0) context->Dr7 |= (1 << 0); // L0
if (points.size() > 1) context->Dr7 |= (1 << 2); // L1
if (points.size() > 2) context->Dr7 |= (1 << 4); // L2
if (points.size() > 3) context->Dr7 |= (1 << 6); // L3
}
};
// Hook管理器
class htdHook2 {
private:
static htdHook2* instance;
DbgPointManager DbgPoints;
PVOID handler;
bool initialized = false;
// 触发初始化的函数(使用编译器内部函数替代内联汇编)
static void ThreadTrap() {
// 使用编译器内部函数替代内联汇编
__nop(); __nop(); __nop();
}
public:
// 单例模式
static htdHook2* getInstance() {
if (!instance) {
instance = new htdHook2();
}
return instance;
}
htdHook2() {
handler = AddVectoredExceptionHandler(1, VectoredHandler);
}
~htdHook2() {
if (handler) RemoveVectoredExceptionHandler(handler);
instance = nullptr;
}
// 设置硬件断点Hook
bool SetHook(LPVOID Address, HOOKBACK2 hookBack, LPVOID AddressRet = nullptr) {
return DbgPoints.AddHookPoint(Address, hookBack, AddressRet);
}
// VEH异常处理
static LONG CALLBACK VectoredHandler(PEXCEPTION_POINTERS ExceptionInfo) {
PCONTEXT ctx = ExceptionInfo->ContextRecord;
DWORD exceptionCode = ExceptionInfo->ExceptionRecord->ExceptionCode;
auto manager = getInstance();
// 获取指令指针(兼容32/64位)
ULONG_PTR eip = 0;
#if defined(_M_X64)
eip = ctx->Rip;
#else
eip = ctx->Eip;
#endif
char debugMsg[256];
if (exceptionCode == STATUS_BREAKPOINT) { // 0x80000003
sprintf_s(debugMsg, "Breakpoint at: 0x%p\n", (void*)eip);
OutputDebugStringA(debugMsg);
// 检查是否是我们设置的断点
if (eip == (ULONG_PTR)ThreadTrap) {
// 恢复原始代码
DWORD oldProtect;
VirtualProtect((LPVOID)ThreadTrap, 1, PAGE_EXECUTE_READWRITE, &oldProtect);
*(BYTE*)ThreadTrap = 0x90; // NOP
VirtualProtect((LPVOID)ThreadTrap, 1, oldProtect, &oldProtect);
// 设置硬件断点
manager->DbgPoints.OpenDbg(ctx);
// 确保从下一条指令继续执行
eip++;
#if defined(_M_X64)
ctx->Rip = eip;
#else
ctx->Eip = eip;
#endif
return EXCEPTION_CONTINUE_EXECUTION;
}
}
else if (exceptionCode == STATUS_SINGLE_STEP) { // 0x80000004
sprintf_s(debugMsg, "Single step at: 0x%p\n", (void*)eip);
OutputDebugStringA(debugMsg);
if (auto point = manager->DbgPoints.FindPoint((LPVOID)eip)) {
if (point->DestCall(ctx)) {
// 继续单步模式
ctx->Dr7 = 0;
ctx->EFlags |= 0x100; // 设置TF标志
}
else {
// 清除单步标志
ctx->EFlags &= ~0x100;
}
return EXCEPTION_CONTINUE_EXECUTION;
}
// 重新激活所有断点
manager->DbgPoints.OpenDbg(ctx);
// 清除单步标志
ctx->EFlags &= ~0x100;
return EXCEPTION_CONTINUE_EXECUTION;
}
return EXCEPTION_CONTINUE_SEARCH;
}
// 初始化硬件断点环境
void Init() {
if (initialized) return;
// 设置临时断点获取CONTEXT
DWORD oldProtect;
VirtualProtect((LPVOID)ThreadTrap, 1, PAGE_EXECUTE_READWRITE, &oldProtect);
BYTE originalByte = *(BYTE*)ThreadTrap; // 保存原始字节
*(BYTE*)ThreadTrap = 0xCC; // INT3
// 触发异常
__debugbreak();
// 恢复原始代码
*(BYTE*)ThreadTrap = originalByte;
VirtualProtect((LPVOID)ThreadTrap, 1, oldProtect, &oldProtect);
initialized = true;
}
};
// 初始化静态成员
htdHook2* htdHook2::instance = nullptr;
// 示例:消息Hook回调函数(兼容32/64位)
bool __stdcall HookMsgCallback(PCONTEXT ctx) {
// 获取消息内容(兼容不同架构)
DWORD_PTR msgAddr = 0;
#if defined(_M_X64)
// x64调用约定:第一个参数在RCX
msgAddr = ctx->Rcx;
#else
// x86调用约定:第一个参数在[ESP+4]
// 使用安全的指针访问替代内联汇编
DWORD espValue = ctx->Esp;
if (espValue) {
msgAddr = *(DWORD*)(espValue + 4);
}
#endif
// 在实际应用中解析消息结构
char buf[256];
sprintf_s(buf, "Message hooked at: 0x%p\n", (void*)msgAddr);
OutputDebugStringA(buf);
return true; // 继续Hook
}
int main() {
OutputDebugStringA("Application started\n");
// 初始化Hook系统
auto hookMgr = htdHook2::getInstance();
hookMgr->Init();
OutputDebugStringA("Hook system initialized\n");
// 设置Hook
HMODULE hUser32 = LoadLibraryA("user32.dll");
if (!hUser32) {
OutputDebugStringA("Failed to load user32.dll\n");
return 1;
}
LPVOID targetFunc = GetProcAddress(hUser32, "SendMessageW");
if (!targetFunc) {
char errMsg[256];
sprintf_s(errMsg, "Failed to find SendMessageW: error %d\n", GetLastError());
OutputDebugStringA(errMsg);
return 1;
}
char infoMsg[256];
sprintf_s(infoMsg, "Hooking SendMessageW at address: 0x%p\n", targetFunc);
OutputDebugStringA(infoMsg);
if (!hookMgr->SetHook(targetFunc, HookMsgCallback)) {
OutputDebugStringA("Failed to set hook (hardware breakpoint limit reached?)\n");
}
else {
OutputDebugStringA("Hook set successfully\n");
}
// 创建测试窗口
WNDCLASSA wc = { 0 };
wc.lpfnWndProc = DefWindowProcA;
wc.hInstance = GetModuleHandle(NULL);
wc.lpszClassName = "TestWindowClass";
if (!RegisterClassA(&wc)) {
OutputDebugStringA("Failed to register window class\n");
return 1;
}
HWND hWnd = CreateWindowA("TestWindowClass", "Hardware Breakpoint Demo",
WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
400, 300, NULL, NULL, GetModuleHandle(NULL), NULL);
if (hWnd) {
ShowWindow(hWnd, SW_SHOW);
UpdateWindow(hWnd);
OutputDebugStringA("Test window created\n");
}
else {
OutputDebugStringA("Failed to create window\n");
return 1;
}
// 发送测试消息
if (hWnd) {
OutputDebugStringA("Sending test message...\n");
SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)"Hello, Hardware Breakpoint!");
// 额外发送消息确保触发
SendMessageA(hWnd, WM_PAINT, 0, 0);
SendMessageA(hWnd, WM_NCPAINT, 1, 0);
}
// 主消息循环
MSG msg;
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
OutputDebugStringA("Application exiting\n");
return 0;
}
最新发布