-
-
[原创]ring3下的Inline hook
-
发表于:
2013-3-28 22:03
15279
-
inline hooking
在IAT hook的时候,如果遇到延迟绑定,即使再IAT hook GetProcAddress,也会使得本来很简单的事情,看起来是那么的复杂。那么有没有一种更好的方法来避免DLL延迟绑定的问题,答案是肯定有的,inline hook会是一种不错的选择。
Inline Hook通过硬编码的方式修改目标函数的内存空间(通常是开始的一段字节,且一般在第一个call之前,很多时候是第一个字节,这么做是主要是为了防止堆栈混乱,如果能够处理好堆栈问题,放在哪个位置都是无所谓的),写入跳转语句,跳转到对应的函数空间里去。这样,该目标函数只要被调用,程序就会跳转到我们的函数中来,我们在自己写的函数里需要完成2个问题:
1)处理好堆栈平衡。在程序流程中,堆栈的平衡是非常的重要,如果inline hook写入的是call语句,那么需要针对函数是否在函数里面做好了堆栈平衡做相应的处理,所以既要保证返回到目标函数中(如果写入的是jmp语句,就不需要),也要保证目标函数能在顺利执行完毕后返回到我们的函数中来。
2)执行被覆盖的指令。我们向目标函数地址空间些如跳转指令(jmp xxxxxxxx)时,势必要覆盖原先的一些汇编指令,所以我们一定要保证这些被覆盖的指令能够顺利执行。关于这部分指令的执行,一般是将其放在我们的函数中,让我们的函数“帮助”目标函数执行完被覆盖的指令,然后再跳回目标函数中被覆盖内后后的地址继续执行剩余内容。跳回去的时候,一定要算好是跳回到什么地址,是目标函数起始地址后的第几个字节。最好的处理方法就是跳回去之前,还原之前被覆盖的汇编指令。
如下分析所示:
Before hook:
INT Func() INT Func()
{ {
return 10; mov eax, 0xA
ret
} }
After hook:
INT Func() INT Func()
{ {
ReplaceFunc; jmp 0xXXXXXX;
ret
} }
VOID ReplaceFunc(VOID)
{
::MessageBox(NULL, "hello world!", "", MB_OK);
HookStatus(false, g_TargetFuncAddr);
//return fnTestDll();
}
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)