API Hook基本原理和实现

http://tech.ddvip.com   2008年01月10日    社区交流

内容摘要:将网络上几篇有代表性的api hook文章的精华进行了浓缩和适当简化,写成这篇介绍性文章。另外也希望初学者能够认真思考本文采用的循序渐进的分析思路,如何解决了一个未知的问题。文中借鉴的文献资料列于文末附录一节。

  当PE文件准备执行时,前图已转换成上图。一个结构指向不变,另一个出现api函数地址

  如果PE文件从kernel32.dll中引入10个函数,那么IMAGE_IMPORT_DESCRIPTOR 结构的 Name1域包含指向字符串"kernel32.dll"的RVA,同时每个IMAGE_THUNK_DATA 数组有10个元素。(RVA是指相对地址,每一个可执行文件在加载到内存空间前,都以一个基址作为起点,其他地址以基址为准,均以相对地址表示。这样系统加载程序到不同的内存空间时,都可以方便的算出地址)

  上述这些结构可以在winnt.h头文件里查到。

  具体编程实现

  我将手上的vc示例代码进行了适当修正,修改了一些资源泄漏的小问题,移植到c++builder6 & update4上,经过测试已经可以完成基本的api hook功能。有几个知识点说明一下:

  1、  dll中共享内存变量的实现

  正常编译下的dll,它的变量使用到的内存是独立的。比如你同时运行两个调用了某个dll的用户程序,试图对某一个在dll中定义的全局变量修改赋值的时候,两个程序里的变量值仍然是不同的。

  共享的方法为:在.cpp文件(.h文件里如此设置会提示编译错误)的头部写上如上两行:

#pragma option -zRSHSEG      // 改变缺省数据段名
#pragma option -zTSHCLASS    // 改变缺省数据类名
HINSTANCE hdll = NULL;          // 用来保存该动态连接库的句柄
HHOOK hApiHook = NULL;          // 钩子句柄
HHOOK hWndProc = NULL;          // 窗口过程钩子用来拦截SendMessage
int threadId = 0;

  另外建立一个与dll同名,不同后缀的def文件,如HookDll.def文件,写上:

LIBRARY HookDll.dll
EXPORTS
;...
SEGMENTS
  SHSEG CLASS 'SHCLASS' SHARED
;end

来源:www.ccrun.com    作者:wskjuf    责编:豆豆技术应用

正在加载评论...