API HOOK

简介

  • 分为inline hook 和 iat hook

inline HOOK

  • 修改api前5个字节 为 jmp 地址(偏移)
  • 计算公式为(地址):我们函数地址 - 当前地址(api地址)-5

inline HOOK 代码

#include <iostream>
#include<Windows.h>

char g_old[5];             //api函数前5个opcode
char g_new[5] = { 0xE9 };  //新的前5个 jmp xxxx
void UnHook();
void OnHook();


int WINAPI
MyMessageBoxW(
	_In_opt_ HWND hWnd,
	_In_opt_ LPCWSTR lpText,
	_In_opt_ LPCWSTR lpCaption,
	_In_ UINT uType)
{
	lpText = L"你已经被hook了";
	//卸载钩子
	UnHook();
	//调用原函数地址
	int nRet = MessageBoxW(hWnd, lpText, lpCaption, uType);
	return nRet;
}

void OnHook()
{
	//保存修改前的5个字节
	memcpy(g_old, MessageBoxW, 5);
	//计算偏移量
	DWORD dwOffset = (DWORD)MyMessageBoxW -            // 目标地址(自己的函数) - 当前函数地址 - 5 = 跳转偏移
		(DWORD)MessageBoxW - 5;                        // jmp 后是一个偏移 :偏移是从 jmp xxxxx 后算起

	//构造跳转指令
	memcpy(g_new + 1, &dwOffset, 4);                   //构造跳转偏移
	
	//写入构造跳转(HOOK)
	//修改写入地址属性(代码段没有可写属性)
	DWORD dwOld;
	VirtualProtect(MessageBoxW, 5, PAGE_READWRITE, &dwOld);
	//修改指令
	memcpy(MessageBoxW, g_new, 5);

	//恢复原来属性
	VirtualProtect(MessageBoxW, 5, dwOld, &dwOld);

}

void UnHook()
{
	DWORD dwOld;
	VirtualProtect(MessageBoxW, 5, PAGE_READWRITE, &dwOld);
	//修改指令
	memcpy(MessageBoxW, g_old, 5);

	//恢复原来属性
	VirtualProtect(MessageBoxW, 5, dwOld, &dwOld);
}



int main()
{
	MessageBox(0, 0, 0, 0);
	OnHook();
	MessageBox(0, 0, 0, 0);
	UnHook();
	MessageBox(0, 0, 0, 0);
	return 0;
}

相关推荐