Windows API拦截技术

来源 :电脑知识与技术·学术交流 | 被引量 : 0次 | 上传用户:mingxing10192009
下载到本地 , 更方便阅读
声明 : 本文档内容版权归属内容提供方 , 如果您对本文有版权争议 , 可与客服联系进行内容授权或下架
论文部分内容阅读
  摘要:讲述了Windows API拦截的关键技术和方法,重点讲述了dll的注入技术和API拦截技术,并对各种技术进行了优缺点分析。
  关键词:API;拦截
  中图分类号:TP393文献标识码:A文章编号:1009-3044(2008)27-1920-03
  Windows API Hooking Method
  SHI Yong-lin,PAN Jin,LI Guo-Peng
  (Department one of Xi’an Communication Institute,Xi’an 710016,China)
  Abstract:This paper give a detail explanation of how to Intercepting Win32 API,its main concern is the way to inject dll into process’s space and API hooking.It also tell the strong and weak point of the different methods.
  Key words:API;hooking
  
  Windows下API(应用程序编程接口,实际上就是Windows系统调用)的拦截是个很有用的技术,现在很多商用的系统都用到了这种技术,如屏幕取词,内码转化,屏幕翻译,中文平台等等都涉及到了此项技术。比如大家熟悉的即时翻译软件,就是靠拦截TextOut()或ExtTextOut()这两个系统API调用实现的,在操作系统用这两个函数输出文本之前,通过拦截这两个调用,把传递给这两个调用的的英文替换成中文,然后再调用原来的API输出,从而达到即时翻译的目的。可以说,掌握了这种技术,从某种意义上讲就可以控制或改变操作系统或其他软件的功能,这也是许多游戏外挂等常用的技术。而且这种技术也被许多病毒和木马等利用,从而达到破坏系统和感染程序的目的,当然现在的反病毒软件也多用到此技术。
  
  1 Windows API拦截技术概述
  
  Windows API拦截的主要目的是在其他应用程序调用API之前将其拦截,由拦截者先处理传递的参数数据,然后决定是否再调用原来的API。比如API
  BOOL TextOutA( HDC hdc, int nXStart,int nYStart,LPCTSTR lpString, int cbString);
  在其他程序调用这个API之前,拦截程序可以先捕获这个调用,先对参数等进行处理,比如将cbString翻译为中文等,然后再调用原来的TextOutA进行文本输出,这样输出的文本就变成中文了。
  API拦截的原理很简单,但是要实现可靠的拦截则需要很多工作要做,首先需要把替换被拦截API的代码注入到目标进程中,这些代码一般是以动态链接库(DLL)的形式存在的,然后修改目标进程执行代码,使其在调用被拦截API之前先调用我们的替代代码。这个过程的示意图如图1所示。
  
  一般拦截程序至少需要两个部分,一个是管理服务器(Management server),它的主要工作是拦截DLL的注入工作,并管理DLL的工作状态,接收DLL发回的处理消息等;另一个是拦截DLL,它主要包含拦截代码以及代码注入和API拦截的一些辅助代码。
  总结起来API拦截主要有以下三点工作要做。
  1) 要决定拦截哪些进程的API,如果是拦截个别进程的API,那么只需要在这个进程中插入拦截DLL,否则则需要在系统的所有进程中插入拦截DLL。
  2) 决定采用哪种DLL注入技术。DLL注入技术有多种,但最常用的就两种,一种是windows全局钩子技术,另外一种是利用CreateRemoteThread() API来进行。我们将在第二节进行重点阐述。
  3) 决定采用哪种API拦截机制。这也有多种技术可用,可以在内核层(kernel level)中进行,也可以在用户层(user level)中进行。我们将在第三节对这个问题进行深入阐述。
  
  2 DLL注入技术
  
  代码注入技术分为动态代码注入技术和静态代码注入技术,动态代码注入技术就是在进程启动后或在进程启动时在进程的运行空间中注入代码的技术,而静态注入技术就是在PE格式的.exe文件中插入代码。静态注入技术是病毒感染文件的常用方法,在文献[1]中有详细的叙述。动态注入技术也分为直接代码注入技术和以dll形式的注入技术,直接代码注入技术是利用VirtualAllocEx和CreateRemoteThread两个API来进行的函数级代码注入技术,可以采用汇编的形式,这种方法在文献[1]中的进程隐藏一章中有详细的讲解,也可以采用高级语言如c语言的形式,这种方法有兴趣的可以参考文献[2]。很显然API拦截只能采用动态代码注入技术,由于直接代码注入技术很复杂,灵活性很差,所以一般采用dll形式的动态代码注入技术。
  2.1 windows全局钩子dll注入技术
  Windows钩子技术是windows提供的windows事件拦截技术,它可以使程序设计者在一些windows事件(如鼠标、键盘事件、窗口创建事件等)发送到特定窗口或线程之前捕获并处理它们。具体钩子的应用技术可以参考Microsoft msdn。
  Windows全局钩子可以把一个dll注入到系统中所有的进程空间中,这些都是由操作系统自动完成的。主要操作过程如下:
  1) 首先创建一个dll,在其中中输出注册钩子函数,如MouseProc和我们的拦截函数,如MyTextOutA等。
  2) 用SetWindowsHookEx函数注册全局钩子。这时操作系统会自动把包含钩子函数的dll映射到所有正在运行的进程空间。
  3) 当不需要钩子时,调用UnhookWindowsHookEx()函数卸载钩子,则系统会自动从所有进程空间中卸载钩子dll。
  全局钩子的使用是很简单的,只是要注意全局变量共享等问题,要把dll的共享变量放到一个共享区中。
  这种方法的优点是操作简单,性能稳定,因为dll的注入和卸载等工作都是由操作系统自动完成的。它的缺点是不能选择性的注入dll到特定的进程中,而且系统会调用我们的无用的钩子函数来处理消息,从而可能会较大的降低系统的性能。
  2.2 利用CreateRemoteThread的dll注入技术
  这种方法在[3]中有较详细的论述。它的原理也很简单,但实现起来较复杂。要在其他的进程中注入dll,就要求我们能在那个进程中调用LoadLibrary() API,但我们没有权限获得其他进程的执行控制权,幸好微软提供了一个函数CreateRemoteThread()可以在其他的进程中创建远程线程,而恰好线程函数的原型:
  DWORD WINAPI ThreadProc(LPVOID lpParameter);
  和LoadLibrary()的原型:
  HMODULE WINAPI LoadLibrary(LPCTSTR lpFileName);
  HMODULE和DWORD都是双字节,调用方式都是WINAPI,LPVOID和LPCTSTR都是双字节指针,所以函数原型是一样的。从而我们利用CreateRemoteThread()来欺骗操作系统,使其执行LoadLibrary() API,如下:
  hThread = ::CreateRemoteThread(
  hProcessForHooking, //要插入dll的进程句柄
  NULL,
  0,
  pfnLoadLibrary,// LoadLibrary函数的地址
  "C:\\HookTool.dll", //要注入的dll的全路径
  0,
  NULL);
  可以看出,采用这种方法的一个主要困难是要监视进程的创建和关闭,这样才能确保在所有的目标进程中注入dll,有关这部分的内容可以参考[4]。LoadLibrary函数的地址因为其所在的Kernel32.DLL的映射地址在所有进程中是确定的,所以其值可以通过调用GetProcAddress()获得。
  这种方法的优点是可以选择性的在特定进程中注入dll,而且不产生额外的开销,基本不降低系统的性能。缺点是实现起来较复杂,要监视系统进程的活动。
  
  3 API拦截机制技术
  
  API拦截也有多种技术可以采用,从编程层次上可以分为内核级的和用户级的。内核级的拦截技术灵活、可靠,但实现复杂,调试困难,有兴趣的可以参考文献[5]。用户级也有多种技术,如dll替换技术、debug技术、目标API代码修改和修改输入表等,这些方法中比较可靠,应用较广的是目标API代码修改和修改输入表两种技术。
  3.1 目标API代码修改
  这种技术说起来也不复杂,就是改变程序流程的技术。在CPU的指令里,有几条指令可以改变程序的流程:JMP,CALL,INT,RET, RETF,IRET等指令。理论上只要改变API入口和出口的任何机器码,都可以拦截API,但是实际实现起来要复杂很多,因为要处理好以下问题:
  1) CPU指令长度问题,在32位系统里,一条JMP/CALL指令的长度是5个字节,因此你只有替换API里超过5个字节长度的机器码(或者替换几条指令长度加起来是5字节的指令),否则会影响被更改的小于5个字节的机器码后面的数条指令,甚至程序流程会被打乱,产生不可预料的后果;
  2) 参数问题,为了访问原API的参数,你要通过EBP或ESP来引用参数,因此你要非常清楚你的拦截代码里此时的EBP/ESP的值是多少;
  3) 上下文的问题,有些拦截代码不能执行某些操作,否则会破坏原API的上下文,原API就失效了;
  举个例子,假如要拦截的API的指令如下:
  :71A21AF4 55 push ebp
  :71A21AF5 8BECmov ebp, esp
  :71A21AF7 83EC10sub esp, 00000010
  ......
  :71A21B64 E8C7F6FFFF call 71A21230//要修改的代码
  ......
  而我们的替换函数的地址为0x8321A341,则我们可以将地址:71A21B64的代码修改为call 8321A341,在我们的拦截代码执行完后执行jmp 71A21230,再返回原来代码处执行。可以看出,这种方法比较难找这条5字节的CALL指令,计算相对地址也复杂。
  这种方法实现起来相当困难,而且灵活性和可靠性都比较差。所以一般不采用这种方法。
  3.2 修改输入表
  通过修改目标进程的输入表来拦截API是一种可靠、简单而且容易实现的技术。这种技术在文献[6]中有详细的讲解。要实现这种方法需要熟悉PE文件的格式,这些内容可以从文献[1]中获取。具体的实现需要以下几个步骤:
  1) 从IMAGE_OPTIONAL_HEADER32结构的第二个IMAGE_DATA_DIRECTORY结构中获得输入表的地址。
  2) 根据要替换API所属dll的名字查找IMAGE_IMPORT_DESCRIPTOR表,找到dll对应的IMAGE_IMPORT_DESCRIPTOR结构体。
  3) 根据API的名字从IMAGE_IMPORT_DESCRIPTOR结构体中OriginalFirstThunk指向的IMAGE_THUNK_DATA列表中查找相应的API在数组中的序号。然后根据查得的序号在FirstThunk指向的IMAGE_THUNK_DATA列表中相应位置找到目标API地址。
  4) 用我们自己的替换函数的地址代替找到的API地址。
  这种方法简单可靠,一般API拦截都采用这种技术。
  
  4 总结
  
  该文文讲述了Windows API拦截的关键技术和方法,重点讲述了拦截dll的注入方法和API拦截方法。但由于篇幅问题本文只是从整体上介绍了API拦截的一些关键技术,具体实现时还要很多问题需要考虑。
  
  参考文献:
  [1] 罗云彬.Windows环境下32位汇编语言程序设计[M].北京:电子工业出版社,2002.
  [2] Ciro Sisman Pereira.Portable Executable (P.E.) Code Injection:Injecting an Entire C Compiled Application[EB/OL].http://www.codeproject.com.
  [3] Jeffrey Ritcher.Load Your 32-bit DLL into Another Process’s Address Space Using INJLIB.MSJ May 1994.
  [4] Ivo Ivanov.Detecting Windows NT/2K process execution[EB/OL].http://www.codeproject.com.
  [5] Sven Schreiber.Undocumented Windows 2000 Secrets.
  [6] Jeffrey Richter.Programming Application for MS Windows.
其他文献
摘要:该文分析了和P2P技术相关的信息安全问题,包括由其自身的技术缺陷所带来的主要安全威胁。针对这些安全问题,介绍了如何构建P2P网络的安全防御体系。  关键词:P2P;信息安全;防御体系  中图分类号:TP393文献标识码:A文章编号:1009-3044(2008)34-1859-02  P2P Technology on the Issue of Information Security Re
书名:简说中华传统文化  作者:傅荆原  出版社:中国民族文化出版社  出版时间:2012年  ISBN:978988170878  定价:25元  随着我国综合实力的不断提升,中国文化在世界范围内的影响力和热度都与日俱增,国内对文化自觉和文化自信的呼声也越来越高,国人对传统文化的关注度和学习热情也达到了空前的高度。不仅相关的研究成果越来越丰富,研究群体也越来越大众化、年轻化。著名传统文化研究学者
摘要:Ad Hoc网络IP地址自动分配是Ad Hoc网络能够正常运行的必要条件。论文对基于伙伴系统的分布式动态地址分配协议进行了优化与扩展,新加入节点首先要发出邻居可用地址池空间大小的探测消息,便于选取拥有最大可用地址池的邻居并向其发送可用地址池请求消息,减少了已存在节点可用地址池枯竭的可能,最大可能的实现网络中每个节点的可用地址池中ip地址数目的均衡,减少了已存在节点递归查找可用地址池的频率。实
摘要:分析了我国中专体校传统教学模式存在的诸多弊端,介绍了Moodle平台的特点及应用价值,有效解决了体校文化课教学难的问题。  关键词:魔灯;教学;兴趣;组织   中图法分类号: G622文献标识码: A 文章编号:1009-3044(2008)19-30187-02  Moodle Application in The Culture Teaching of Sports School  YO
摘要:通过对J2EE架构的分析,提出了基于J2EE体系的办公自动化总体架构和子系统的分块,然后分别阐述了各子系统的功能及设计方法。  关键词:J2EE架构;办公自动化;设计  中图分类号:TP317文献标识码:A文章编号:1009-3044(2008)09-11656-03    The Analysis and Design of OA System Based on J2EE Frame  L
摘要:网络团购已经成为一种新的购物时尚,中国的团购网站不再是单纯的模仿Groupon模式,而是走出了一条本土化发展的道路,该文将从网络团购的含义和现状介绍起,分析中国目前团购模式本土化的情况和存在的问题,最后预测网络团购本土化未来的发展趋势。  关键词:网络团购;本土化;发展问题;未来预测  中图分类号:TP311文献标识码:A文章编号:1009-3044(2012)03-0543-03   1什
摘要:结合中职课堂教学现状介绍交互式电子白板在中职课堂教学中的优势和应用原则。设计中职课堂教学案例,并进行设计反思。  关键词:中职课堂;交互式电子白板;课堂教学  中图分类号:G424 文献标识码:A 文章编号:1009-3044(2013)28-6356-03  根据人本主义的观点,在课堂教学中,要以“人”为中心,充分调动学生的积极性。传统的课堂教学主要借助黑板 粉笔进行,教学方式单一,主要是
摘要:VHDL作为一种新型的硬件描述语言,主要用于数字电路与系统的描述、模拟和自动设计,是当今电子设计自动化(EDA)的核心技术。文章通过十六位计数器的实例介绍了用VHDL语言设计数字系统的流程和方法,并通过仿真实现预定目的。实践证明,VHDL语言在数字系统设计中具有硬件描述能力强,设计方法灵活等优点,从而降低了数字系统设计的难度,提高了工作效率。  关键词:VHDL;MAX PLUSⅡ;仿真;数
学生的核心素养是指适应学生个人终身发展和社会发展的必备品德和关键能力。把核心素养落实到课堂教学中,是当前教学改革的重要任务。核心素养必须从课程建设和教学模式两个方面落实,二者相辅相成、缺一不可。那么作为一线教师,具体该如何做呢?高茂军、王英兰主编的《核心素养引领下的课堂教学革新》一书围绕这一问题,通过五个专题,指导教师基于学生核心素养的发展,转变观念,创新思路,多路径、多方法改革课堂教学,实现教学
摘要:针对我国高校毕业生就业形势日趋严峻,用人单位招不到符合要求的毕业生,毕业生找不到适合自己的岗位等问题,以海南经贸职业技术学院的就业信息化建设情况为例,通过对毕业生、教师及其他高校的就业信息网的调查研究,分析海南经贸职业技术学院的就业信息网的组成、使用效果及其原因,并借鉴各高校的就业信息网的优点,结合学校实际情况,分析存在问题并提出解决建议。  关键词:高校;信息化;就业;信息网;招聘  中图