浅淡 “对 HOOK PE 的学习体会”
我们都知道,对于PE 文件的结构中,有一个叫做导出表的东西,这个表中存放着这个程序运行所需要的函数。这些函数都存放在一个结构中。如果,我们能够替换这个结构中的某些地址,那么,我们就能够在程序执行之前,拿到控制权。
下边看一下这个结构的示意图:
从这个图中,我们可以清楚的看到,导出表函数名和函数地址组成,它们可以通过导出表获得:
pModuleAddress = PEGetModuleBaseAddress("ntkrnlpa.exe");
pExportDir = (PIMAGE_EXPORT_DIRECTORY)(pModuleBase + pSecHead->VirtualAddress);
dwAddrName = (PDWORD)(pModuleBase + pExportDir->AddressOfNames);
dwAddrFun=(PDWORD)(pModuleBase+pExportDir->AddressOfFunctions;
dwAddrName :也就是指向那个表的第一个函数的名字,从图中可以知道,它们是一种链式结构,那么,我们就可以通过循环来遍历这个链表了。
dwAddrFun : 这是函数的偏移地址,我们可以通过基址 + 偏移的方式快速的定位函数的地址。。。获取方法和上边是一样的。
HOOK 的方法是替换函数的偏移地址,利用这个特性,我们可以快速得到原来的函数的地址,然后换成我们函数相对基址的偏移地址,最后,在我们的函数最后调用原来的函数,因为我们在 HOOK 的时候已经记录了它的地址,还是和原来一样,通过指向这个函数的指针完成。。。
在这里值得注意的是,ntkrnlpa.exe 这个是对于多核 CPU 单核的 ntoskrl.exe …不然的话,可以获取不到我们定位的函数。。。
下边,我们开始了替换的操作:
打印出了函数对应的地址注意最后一个,这是我们想要的,现记住这个地址:
函数名字 ------ZwCreateFile
函数地址-------0x804ff07c
、还有下边我们自定义的函数地址:
MyHookFunc------------------0xf89e37f0
看下边,我们替换完成后的情况。。。
发现什么了吗? 看 ZwCreateFile ------à 0xf89e37f0
和我们上边记录的我们定义的函数是一样,说明了我们 HOOK 住了这个函数。。。
具体的HOOK 过程:
__asm
{
mov eax, MyHookFunc;
sub eax, pModuleBase;
mov uAddress, eax;
}
上边计算出我们定义的函数相对于基址的偏移量,然后填充这个函数的偏移。。。
*dwAddrFun = uAddress;