如何高效的进行API Hook

来源:互联网 发布:淘宝店加盟骗局 编辑:程序博客网 时间:2024/05/15 20:19

原文:http://www.osdiy.com/Blog/article.asp?id=14

相信很多人都对全局的API Hook感兴趣,特别是做一些安全方便的小工具,对应用层的一些特定函数进行系统全局范围的拦截是很重要的,如何安全高效的进行拦截呢?下面本人给出一种拦截方式给大家做参考。

Win9x的内存管理模式和WinNT差距较大,本文仅对WinNT内核为例做说明,Win9x系统部分自行想办法。呵呵

如何进行全局Hook:
WinNT下由于COW(Copy On Wite)机制的存在,所以要进行全局Hook一般都是用驱动在Ring0进行操作,有两种方法,一种是直接通过CR3,找到你要修改地址所在的页目录项,修改其只读属性。其二,直接修改CR0中的WP位(第16位)。

Hook的时机:
一般来说,我们希望在进程未执行起来就进行Hook,所以传统的远线程注入和SetWindowsHookEx注入钩子的方式就不适合了,可以使用MengXP的方法,直接在Advapi32.dll入口处载入我们的DLL,因为不用Advapi32.dll的太少了,除非那个进程只用Kernel32.dll,当然我们也可以再做些改进,这里就不做讨论了。

Hook的对象:
一般我们都是对一些危险函数进行拦截,比如:CreateRemoteThread,URLDownloadToFile。这些函数是非常值得怀疑的,所以一般都是重点监视对象,但是如何高效的去监视这些函数呢?传统方法就是把要监视的函数全部载入,一个一个的函数进行Hook,这造成了宁可错杀一千,不可放过一个了。比如一个程序它本来仅仅使用MessageBox,而我们却怀疑它要使用网络而把所有网络方面的模块载入了。不说对程序或系统性能是否有影响,至少这样做是不够智能的,我们有更好的方法。先说说DLL的加载过程,首先,要载入的模块是先被系统映射到载入进程的内存空间的,然后会去调用DLL的入口函数。我们的拦截时机就在这里,因为我们希望DLL被载入的时候才进行拦截,我们无法准确的去判断DLL啥时候被映射完成的,但是我们可以通过分析得到什么时候调用DLL入口函数的,我们自己写一个DLL,然后获得入口函数的返回地址,然后反着推一条指令就是了,以WinXP为例,代码是这样的:
7C921193      55              push ebp
7C921194      8BEC            mov ebp,esp
7C921196      56              push esi
7C921197      57              push edi
7C921198      53              push ebx
7C921199      8BF4            mov esi,esp
7C92119B      FF75 14         push dword ptr ss:[ebp+14]
7C92119E      FF75 10         push dword ptr ss:[ebp+10]
7C9211A1      FF75 0C         push dword ptr ss:[ebp+C]
7C9211A4      FF55 08         call dword ptr ss:[ebp+8]
7C9211A7      8BE6            mov esp,esi
7C9211A9      5B              pop ebx
7C9211AA      5F              pop edi
7C9211AB      5E              pop esi
7C9211AC      5D              pop ebp
7C9211AD      C2 1000         retn 10


7C9211A4      FF55 08         call dword ptr ss:[ebp+8]
这一行就是调用DLL的入口点了,我们直接对这一行进行Hook就是了,然后通过对被调用的DLL入口点进行页对齐,向前找就能发现MZ标志了,然后GetModuleFileName获得文件名,根据载入的文件名来判断是否是我们需要拦截的模块。

到这里相信大家剩下的都会做了,也就不再多说了。
 
原创粉丝点击