Hook 技术原理篇

一、论

什么是HOOK ,HOOK技术应用在那些场景?

二丶立场

HOOK 是一场黑与白的博弈,不管立场是黑是白。HOOK 的中文词汇是 “钩子” 的意思,HOOK 技术正如名字;

三、一个例子

假设:小A给小B打电话,小A说:"明天下午3点我们在1号广场进行交易",小A与小B打电话的时候恰好小C把小A的电话给监听起来了,所以小A电话中的信息,小C了如指掌;第二天小C早就带着人在现场潜伏好了,结果小A乖乖的被抓走了!

在上面这个例子中,小C 可能是个警察,他通过某种手段把小A的电话给监听起来了,实际上这种监听手段在我们所研究的领域中就称作HOOK技术

四、计算机中的应用场景

API的拦截:假设一个病毒程序要试图修改系统中的文件,那么相应的安全软件会把一些比较敏感的API函数给监听起来,如果API做出来一些过分的事情,安全软件将会给拦截下来。

获取数据:假设想在进程中得到一段代码的运算结果,那么就可以在程序代码附近的地址上安装钩子进行监听数据此过程也是可以进行修改数据的,很多黑客在写游戏外挂的时候会大量使用HOOK技术

上图是一个正常进程的执行流程,接下来我在0x40030000处挂一个钩子,如下图

在简单说一下上图进行挂钩子的步骤:

(1)确定钩子安装的位置,图中安装到了内存地址为40030000处

(2)构造自己目标目的代码,这个过程需要在目标进程中找一块空内存进行钩子逻辑代码

(3)执行完自己的代码了一定要擦干净现场装作一无所知回到目标地址处

五、代码编写

BYTE* g_PreservationData = NULL;		//保存改变前的原来指令

										//一个加法函数
int add(int a, int b)
{
	return a + b;
}

//安装钩子
//lpAddress		hook的地址
//dwSize		改变的内存大小
//procAddress	跳转到的函数
int InstallInlineHook(void* lpAddress, DWORD dwSize, void* procAddress)
{
	DWORD oldProtect;

	//判断地址是否有效
	if (lpAddress == NULL || procAddress == NULL)return -1;
	//判断长度
	if (dwSize < 5)return -2;


	VirtualProtectEx(GetCurrentProcess(), lpAddress, dwSize, PAGE_EXECUTE_READWRITE, &oldProtect);
	g_PreservationData = (BYTE*)malloc(dwSize);

	//保存原数据
	memcpy(g_PreservationData, lpAddress, dwSize);

	//构造跳转地址
	//公式:
	DWORD dwJmpCode = (DWORD)procAddress - (DWORD)lpAddress - 5;
	memset(lpAddress, 0x90, dwSize);
	*(BYTE*)lpAddress = 0xE9;
	*(DWORD*)((BYTE*)lpAddress + 1) = dwJmpCode;

	return 0;
}

//卸载钩子
//卸载地址		hook的地址
//dwSize		内存大小
int UnInlineHook(void* lpAddress, DWORD dwSize)
{
	DWORD oldProtect;
	if (g_PreservationData == NULL)return -1;
	if (lpAddress == NULL)return -2;
	if (dwSize == NULL)return -3;

	VirtualProtectEx(GetCurrentProcess(), lpAddress, dwSize, PAGE_EXECUTE_READWRITE, &oldProtect);
	memcpy(lpAddress, g_PreservationData, dwSize);
	free(g_PreservationData);


	return 0;
}

//对于没有用naked声明的函数一般编译器都会产生保存现场
extern "C" _declspec(naked)void HookProc()
{
	_asm {
		pushad
		pushfd
	}

	MessageBox(NULL, NULL, NULL, MB_OK);

	UnInlineHook(add, 6);

	_asm {
		popfd
		popad
	}

	_asm {
		jmp add
	}

}

int main()
{

	printf("inline hook");
	InstallInlineHook(add, 6, HookProc);

	printf("add = %d", add(100, 200));
	system("pause");
	return 0;
}


点赞

发表评论

电子邮件地址不会被公开。必填项已用 * 标注