欢迎来到天天文库
浏览记录
ID:11580911
大小:139.00 KB
页数:37页
时间:2018-07-12
《hook api 函数跳转详解》由会员上传分享,免费在线阅读,更多相关内容在教育资源-天天文库。
1、HOOKAPI函数跳转详解什么是HOOKAPI: Windows下暴露的对开发人员的接口叫做应用程序编程接口,就是我们常说的API。我们在写应用层应用程序软件的时候都是通过调用各种API来实现的。有些时候,我们需要监控其他程序调用的API,也就是,当其他应用程序调用我们感兴趣的API的时候,我们在他调用前有一个机会做自己的处理,这就是HOOKAPI的涵义。 思路: 我们知道Windows系统API函数都是被封装到DLL中,在某个应用程序要调用一个API函数的时候,如果这个函数所在的DLL没有被加载到本进程中则加载它,然后保存当前环境(各个寄
2、存器和函数调用完后的返回地址等)。接着程序会跳转到这个API函数的入口地址去执行此处的指令。由此看来,我们想在调用真正的API之前先调用我们的函数,那么可以修改这个API函数的入口处的代码,使他先跳转到我们的函数地址,然后在我们的函数最后再调用原来的API函数。下面以拦截WS2_32.dll中的recv函数为例说明拦截的主要过程。首先把自己编写的DLL挂接到系统当前运行的所有进程中(要排除一些Windows系统自身的进程,否则会出现问题,影响系统正常工作),挂接的意思是,要我们的DLL运行在目标进程的地址空间中。可以使用列举系统进程然后用远程线程注入的方法,但是
3、这种方法只适用于Win2000以上的操作系统。 当我们的DLL被所有目标进程加载后,我们就可以进行真正的工作了。首先使用ToolHelp库的相关函数列举目标进程加载的所有模块,看看是否有ws2_32.dll,如果没有,说明这个进程没有使用Winsock提供的函数,那么我们就不用再给这个进程添乱了。如果找到ws2_32.dll模块,那么OK,我们可以开工了。先是用GetProcAddress函数获得进程中ws2_32.dll模块的recv函数的入口地址,也就是函数的起始地址。刚才说过,我们想把recv函数起始位置加入一条跳转指令,让它先跳转到我们的函数
4、中运行。跳转指令可以用0xE9来表示(0xE9是汇编语言中CALL指令的机器码),后面还有4个字节的我们函数的相对地址。也就是我们要修改recv函数前5个字节。这5个字节由1个字节的跳转指令和4个字节的地址组成。这样当程序运行到这里的时候,将会跳转到这4个字节表示的地址处去运行代码。还要注意的是这4个字节的地址是偏移地址,而偏移地址=我们函数的地址-原API函数的地址-5(我们这条指令的长度)。好了,别忘了我们要先读取稍后要被覆盖的recv函数入口处的5个字节的内容,把它保存起来留着以后恢复时使用。因为在我们的函数中要想调用真正的recv的时候,必须把它前5个字
5、节恢复了,他才能正常工作呢。 通过上面的说明,我们可以整理出这样的一个流程: 1. 保存recv的前5个字节的内容2. 把recv的前5个字节的内容改变成CALLxxxx(xxxx是我们的函数的偏移地址)3. 在我们的函数中恢复recv的前5个字节的内容,并作处理。4. 我们的函数返回后,再把recv的前5个字节的内容改变成CALLxxxx慢着,你一定发现问题了吧?当我们为了调用原来的recv函数而刚刚把recv入口处的5个字节恢复,这时系统中的其他线程调用了recv函数,而这个调用将会成为漏网之鱼而不会进入到我们的函数中来。简单的解决办法是使用临界
6、对象CriticalSection来保证同时只能有一个线程对recv函数入口处5个字节进行读写操作。 最后记得在你想要停止拦截的时候恢复所有你修改过的进程和这些进程中被修改的API的前5个字节。其实原理讲着容易,在实现的时候会遇到各种各样的问题,如98下这些系统的DLL被加载到系统内存区供应用程序共享,所以这些内存是受保护的,不能随意修改,还有nt/2000下权限问题,还要考虑到不要拦截某些系统进程,否则会带来灾难性的后果。这些都是在实践当中遇到的实际问题。 下面结合代码给大家讲解一下吧,首先我们要实现HOOK模块,我们给它起个名字叫做MainHookDll.D
7、LL。在此模块中,主要要实现一个CHookApi的类,这个类完成主要的拦截功能,也是整个项目的技术核心和难点,后面将具体介绍它。而且,MainHookDll模块就是将来要注入到系统其它进程的模块,而远程调用函数是非常困难的事情,所以我们设计此模块的时候应让其被加载后自动执行拦截的初始化等工作。这样,我们只需要让远程的进程加载HOOK,然后MainHookDll.dll就能够自动执行其它操作从而HOOK该进程的相关API。 MainHookDll模块中的CHookApi类拥有2个向外部提供的主要的方法,HookAllAPI,表示拦截指定进程中的指定API和Unh
8、ookAllAPI,表示
此文档下载收益归作者所有