1. 程式人生 > >inline Hook簡單介紹

inline Hook簡單介紹

What is Inline Hook ?

就是一個函式鉤子而已,把程式原本要呼叫的函式改成另一個函式,就是對原函式的一個掛鉤(hook) 。

How did this work ?

讓我們看看呼叫一個函式控制流的跳轉圖:

fun_b 呼叫 fun_a

如果我們需要修改、截獲對fun_a 函式呼叫的引數該怎麼做呢?

Definitely 對 fun_a 的呼叫進行Hook操作,看看Hook後的控制流跳轉圖:

       雖然在fun_hook函式中沒有修改、截獲fun_a 的引數,但是我們演示了Hook一個函式

的實質。就是修改指令call fun_a 的跳轉地址,把它改成我們的Hook函式的地址。

Hook函式想做啥就做啥,可以對原函式呼叫,也可以不對原函式進行呼叫,如果要

保證程式在Hook函式呼叫後能正常繼續執行,最好儲存下呼叫Hook函式時的Context現場。

用pushad 和 popad 指令就可以完成咯。

       進行Inline Hook並呼叫原函式需要兩個關鍵地址:

1. 呼叫原函式的指令位置 。以修改指令跳轉到鉤子函式.

2.原函式的地址。鉤子函式處理完後,呼叫原函式,保證程式繼續正常執行。

下面以Hook某程式中的某個函式呼叫為例,實戰下:

目標:用我的 evil.dll 中的匯出函式 Hook_fun 勾住某程式的某個函式呼叫。

DWORD jmpAddr;		//hook 函式結束後跳轉的原函式的地址

//獲取目標指令地址 和 原函式的地址
DWORD GetHookAddr(void)
{
	HMODULE hDll = GetModuleHandle(L"xxnetwork.dll");
	jmpAddr = (DWORD)hDll + 0x581C;		//hook 函式結束後跳轉的原函式的地址
	return (DWORD)hDll + 0x42855;		//要 Hook 的指令的地址
}


//安裝 Inline hook
bool MakeInlineHook(void)
{
	//1.獲取 hook 地址
	DWORD targetAddr = GetHookAddr();

	//2.計算相對跳轉偏移
	HMODULE hDll1 = GetModuleHandle(L"evil.dll");
	DWORD HookFunAddr = (DWORD)GetProcAddress(hDll1, "HookFun")+6 - targetAddr - 5;	//注意,這裡+6是為了跳過 vs2015 為函式生成的保護現場的指令(push ebp,mov ebp,esp)
//-5 是因為call 指令的偏移計算是按照下一條指令的首地址計算的

	//3.修改記憶體屬性,並寫入hook 程式碼
	DWORD oldP,tmp;
	unsigned char code[5];
	if (VirtualProtect((LPVOID)targetAddr, 5, PAGE_EXECUTE_READWRITE, &oldP))
	{
		code[0] = 0xe8;			//call 指令opcode
		memcpy(&code[1], &HookFunAddr,4);	//addr
		memcpy((void*)targetAddr, (void*)code, sizeof(code));		//修改程式碼
		VirtualProtect((LPVOID)targetAddr, 5, oldP, &tmp);			//還原保護屬性
		return true;
	}
	return false;
}

//DLL 匯出鉤子函式
DLLEXPORT void HookFun(void)
{


	_asm {
		pushad
                //在這裡可以截獲原函式的引數,修改……
                //用你的想象力,隨意發揮……

hookRet :
		popad
			//跳轉到原來的函式執行
			jmp jmpAddr
             }

}

//DLL main 函式,當載入程式的時候按照 Inline Hook

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
					 )
{
	switch (ul_reason_for_call)
	{
	case DLL_PROCESS_ATTACH:
            MakeInlineHook();
            break;
        }
}

OK,以上就是Inline hook 的基本介紹,是不是很簡單呢~~~