VEH软件断点和硬件断点Hook管理

#pragma once



using HookTargetProc = LONG(NTAPI*)(struct _EXCEPTION_POINTERS* ExceptionInfo);


struct VEH_HOOK {
	LPVOID HookAddress;
	HookTargetProc TargetAddress;
	UCHAR OldCode;
	struct VEH_HOOK* next;
};

struct VEHCPUHOOK {
	LPVOID lpHookAddress;
	HookTargetProc TargetAddress;
};
using HOOKNODE = struct VEH_HOOK;
using CPUHOOKINFO = struct VEHCPUHOOK;
void InitVehHook();

void SetVehHook(LPVOID lpHookAddress, HookTargetProc lpTarget);

void SetVehCpuHook(LPVOID lpHookAddress, HookTargetProc lpTarget);

void SetThreadHook(HANDLE hThread);

void DeleteAllHook();




#include "pch.h"
#include "VehHook.h"
#include <TlHelp32.h>
#include <iostream>
HOOKNODE* nodeExceptionHook;
CPUHOOKINFO cpuHookInfo[4] = { 0 };

LONG NTAPI VehHookHandle(struct _EXCEPTION_POINTERS* ExceptionInfo) {

	if (ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_BREAKPOINT) {
		//		std::cout << 1;
		HOOKNODE* tempHookNode = nodeExceptionHook;
		while (tempHookNode != nullptr) {
			if (tempHookNode->HookAddress == ExceptionInfo->ExceptionRecord->ExceptionAddress) {
				DWORD dwOld;
				VirtualProtect(tempHookNode->HookAddress, 1, PAGE_EXECUTE_READWRITE, &dwOld);
				*(UCHAR*)(tempHookNode->HookAddress) = tempHookNode->OldCode;
				tempHookNode->TargetAddress(ExceptionInfo);
				ExceptionInfo->ContextRecord->EFlags |= 0x100;
				VirtualProtect(tempHookNode->HookAddress, 1, dwOld, &dwOld);
				return EXCEPTION_CONTINUE_EXECUTION;
			}
			tempHookNode = tempHookNode->next;
		}

		return EXCEPTION_CONTINUE_SEARCH;
	}
	else if (ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_SINGLE_STEP) {

		for (int i = 0; i < 4; i++) {
			if (cpuHookInfo[i].lpHookAddress == ExceptionInfo->ExceptionRecord->ExceptionAddress) {
				switch (i) {
				case 0: ExceptionInfo->ContextRecord->Dr0 = (LONG_PTR)cpuHookInfo[i].lpHookAddress; ExceptionInfo->ContextRecord->Dr7 &= 0xFFFFFFFE; break;
				case 1:	ExceptionInfo->ContextRecord->Dr1 = (LONG_PTR)cpuHookInfo[i].lpHookAddress; ExceptionInfo->ContextRecord->Dr7 &= 0xFFFFFFFB; break;
				case 2:	ExceptionInfo->ContextRecord->Dr2 = (LONG_PTR)cpuHookInfo[i].lpHookAddress; ExceptionInfo->ContextRecord->Dr7 &= 0xFFFFFFEF; break;
				case 3:	ExceptionInfo->ContextRecord->Dr3 = (LONG_PTR)cpuHookInfo[i].lpHookAddress; ExceptionInfo->ContextRecord->Dr7 &= 0xFFFFFFBF; break;
				}
				//				std::cout << 1;
				//				ExceptionInfo->ContextRecord->Dr7 = 0;
				cpuHookInfo[i].TargetAddress(ExceptionInfo);
				ExceptionInfo->ContextRecord->EFlags |= 0x100;
				return EXCEPTION_CONTINUE_EXECUTION;
			}
		}
		for (int i = 0; i < 4; i++) {
			if (cpuHookInfo[i].lpHookAddress != nullptr) {
				switch (i) {
				case 0: ExceptionInfo->ContextRecord->Dr0 = (LONG_PTR)cpuHookInfo[i].lpHookAddress; ExceptionInfo->ContextRecord->Dr7 |= 0b1; break;
				case 1:	ExceptionInfo->ContextRecord->Dr1 = (LONG_PTR)cpuHookInfo[i].lpHookAddress; ExceptionInfo->ContextRecord->Dr7 |= 0b100; break;
				case 2:	ExceptionInfo->ContextRecord->Dr2 = (LONG_PTR)cpuHookInfo[i].lpHookAddress; ExceptionInfo->ContextRecord->Dr7 |= 0b10000; break;
				case 3:	ExceptionInfo->ContextRecord->Dr3 = (LONG_PTR)cpuHookInfo[i].lpHookAddress; ExceptionInfo->ContextRecord->Dr7 |= 0b1000000; break;
				}
			}
		}

		//		ExceptionInfo->ContextRecord->Dr7 = 0x455;
		HOOKNODE* tempHookNode = nodeExceptionHook;
		while (tempHookNode != nullptr) {
			DWORD dwOld;
			VirtualProtect(tempHookNode->HookAddress, 1, PAGE_EXECUTE_READWRITE, &dwOld);
			*(UCHAR*)(tempHookNode->HookAddress) = 0xCC;
			VirtualProtect(tempHookNode->HookAddress, 1, dwOld, &dwOld);
			tempHookNode = tempHookNode->next;
		}
		ExceptionInfo->ContextRecord->EFlags &= 0xFFFFFEFF;
		return EXCEPTION_CONTINUE_EXECUTION;
	}
	return EXCEPTION_CONTINUE_SEARCH;
}

void InitVehHook() {
	nodeExceptionHook = nullptr;
	memset(cpuHookInfo, 0, sizeof(cpuHookInfo));
	AddVectoredExceptionHandler(1, VehHookHandle);
}

void SetVehHook(LPVOID lpHookAddress, HookTargetProc lpTarget) {
	HOOKNODE* tempHookNode = new HOOKNODE;
	tempHookNode->HookAddress = lpHookAddress;
	tempHookNode->TargetAddress = lpTarget;
	tempHookNode->next = nullptr;
	DWORD dwOld;
	if (VirtualProtect(lpHookAddress, 1, PAGE_EXECUTE_READWRITE, &dwOld)) {
		tempHookNode->OldCode = *(unsigned char*)lpHookAddress;
		*(unsigned char*)lpHookAddress = 0xCC;
		VirtualProtect(lpHookAddress, 1, dwOld, &dwOld);
		tempHookNode->next = nodeExceptionHook;
		nodeExceptionHook = tempHookNode;
	}
}

void SetVehCpuHook(LPVOID lpHookAddress, HookTargetProc lpTarget) {
	int i;
	for (i = 0; i < 4; i++) {
		//		std::cout << i << std::endl;
		if (cpuHookInfo[i].lpHookAddress == nullptr) {
			//			std::cout << i << std::endl;
			cpuHookInfo[i].lpHookAddress = lpHookAddress;
			cpuHookInfo[i].TargetAddress = lpTarget;
			DWORD dwProcessId = GetCurrentProcessId();
			HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, dwProcessId);
			if (INVALID_HANDLE_VALUE != hSnap) {
				THREADENTRY32 te32 = { sizeof(te32) };
				BOOL bRet = Thread32First(hSnap, &te32);
				while (bRet) {
					if (te32.th32OwnerProcessID == dwProcessId) {
						HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, FALSE, te32.th32ThreadID);
						if (hThread != NULL) {
							CONTEXT ctx;
							ctx.ContextFlags = CONTEXT_ALL;
							GetThreadContext(hThread, &ctx);
							switch (i) {
							case 0: ctx.Dr0 = (DWORD)lpHookAddress; ctx.Dr7 |= 0b1; break;
							case 1:	ctx.Dr1 = (DWORD)lpHookAddress; ctx.Dr7 |= 0b100; break;
							case 2:	ctx.Dr2 = (DWORD)lpHookAddress; ctx.Dr7 |= 0b10000; break;
							case 3:	ctx.Dr3 = (DWORD)lpHookAddress; ctx.Dr7 |= 0b1000000; break;
							}
							ctx.Dr7 &= 0xfff0ffff;
							SetThreadContext(hThread, &ctx);
							CloseHandle(hThread);
						}
					}
					bRet = Thread32Next(hSnap, &te32);
				}
				CloseHandle(hSnap);
			}
			break;
		}
	}
	if (i == 4) {
		MessageBoxA(NULL, "请下软件断点", "硬件断点已满", MB_OK);
	}

}

void SetThreadHook(HANDLE hThread) {
	if (hThread != NULL) {

		CONTEXT ctx;
		ctx.ContextFlags = CONTEXT_ALL;
		GetThreadContext(hThread, &ctx);
		ctx.Dr0 = (DWORD)cpuHookInfo[0].lpHookAddress;
		ctx.Dr1 = (DWORD)cpuHookInfo[1].lpHookAddress;
		ctx.Dr2 = (DWORD)cpuHookInfo[2].lpHookAddress;
		ctx.Dr3 = (DWORD)cpuHookInfo[3].lpHookAddress;
		if (cpuHookInfo[0].lpHookAddress)
			ctx.Dr7 |= 0x401;
		else if (cpuHookInfo[1].lpHookAddress)
			ctx.Dr7 |= 0x404;
		else if (cpuHookInfo[2].lpHookAddress)
			ctx.Dr7 |= 0x410;
		else if (cpuHookInfo[3].lpHookAddress)
			ctx.Dr7 |= 0x440;
		SetThreadContext(hThread, &ctx);

	}

}

void DeleteAllHook() {
	std::cout << 1 << std::endl;
	HOOKNODE* tempHookNode = nodeExceptionHook;
	while (tempHookNode != nullptr) {
		DWORD dwOld;
		VirtualProtect(tempHookNode->HookAddress, 1, PAGE_EXECUTE_READWRITE, &dwOld);
		*(UCHAR*)(tempHookNode->HookAddress) = tempHookNode->OldCode;
		VirtualProtect(tempHookNode->HookAddress, 1, dwOld, &dwOld);
		HOOKNODE* delNode = tempHookNode;
		tempHookNode = tempHookNode->next;
		delete delNode;
	}
	nodeExceptionHook = nullptr;
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
VEH机制中使用硬件断点可以帮助我们在特定的内存地址上设置断点,当程序执行到该地址时触发断点异常。以下是一个使用硬件断点VEH例子: ```c++ #include <Windows.h> // Vectored Exception Handler函数 LONG WINAPI VehHandler(PEXCEPTION_POINTERS pExceptionInfo) { // 判断是否是硬件断点异常 if (pExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_SINGLE_STEP) { // 处理硬件断点触发逻辑 // ... // 取消硬件断点,恢复程序执行 CONTEXT* pContext = pExceptionInfo->ContextRecord; pContext->Dr0 = 0; pContext->Dr7 &= ~0x00000001; // 返回处理结果,终止异常处理链 return EXCEPTION_EXECUTE_HANDLER; } // 返回继续搜索异常处理链 return EXCEPTION_CONTINUE_SEARCH; } int main() { // 注册Vectored Exception Handler PVOID pHandler = AddVectoredExceptionHandler(1, VehHandler); if (pHandler == NULL) { // 处理注册失败情况 // ... return 1; } // 设置硬件断点 CONTEXT context; memset(&context, 0, sizeof(CONTEXT)); context.ContextFlags = CONTEXT_DEBUG_REGISTERS; context.Dr0 = 0x12345678; // 设置断点地址 context.Dr7 = 0x00000001; // 设置断点条件和长度 if (!SetThreadContext(GetCurrentThread(), &context)) { // 处理设置硬件断点失败情况 // ... RemoveVectoredExceptionHandler(pHandler); return 1; } // 触发硬件断点 int* p = reinterpret_cast<int*>(0x12345678); *p = 42; // 移除Vectored Exception Handler RemoveVectoredExceptionHandler(pHandler); return 0; } ``` 在上述代码中,我们首先定义了一个VEH处理函数`VehHandler`,当异常发生时会被调用。在该函数中,我们判断异常类型是否为硬件断点异常(EXCEPTION_SINGLE_STEP),如果是,则执行我们定义的硬件断点触发逻辑。在本例中,我们取消硬件断点(清除Dr0和Dr7寄存器的相应位),并返回`EXCEPTION_EXECUTE_HANDLER`来终止异常处理链。 在`main`函数中,我们首先注册VEH处理函数,然后使用`SetThreadContext`函数设置硬件断点。通过设置`Dr0`寄存器为要设置断点的地址,设置`Dr7`寄存器来指定断点条件和长度。如果设置成功,则触发硬件断点,程序会在指定地址处触发断点异常。最后,移除VEH处理函数并结束程序。 请注意,硬件断点的使用需要注意调试器的干扰,因为调试器可能会使用硬件断点进行调试操作。因此,在实际应用中需要谨慎使用硬件断点,并根据具体需求进行详细的异常处理和错误处理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值