逆向工程核心原理-29

逆向工程核心原理-第29章-API钩取: 逆向分析之”花”

29.1 钩取

钩取(Hooking)是一种截取信息, 更改程序执行流向, 添加新功能的技术.

钩取流程如下:

  • 使用反汇编器/调试器把我程序的结构与工作原理
  • 开发需要的”钩子代码”, 用于修改Bug, 改善程序功能
  • 灵活操作可执行文件与进程内存, 设置”钩子代码”

我们前面学习的是消息钩子, 钩取的对象是消息, 而现在学习的是API钩取, 对象是Win32的API. 这是二者本质的区别

29.2 API是什么

API (Application Programming Interface, 应用程序编程接口)

Windows中, 用户程序要使用系统资源(内存, 文件, 网络, 视频, 音频等)时无法直接访问, 这些资源都是由Windows OS直接管理的, 处于多种考虑(稳定性, 安全, 效率), Windows进制用户程序直接访问它们. 用户程序需要这些资源时, 必须向系统内核(Kernel)申请, 申请的方法就是使用微软提供的Win32 API函数.

为运行实际的应用程序代码, 需要加载许多系统库(DLL), 所有进程都会默认加载kerne32.dll库, kernel32.dll又会加载ntdll.dll库.(也有特殊情况的程序不会加载kernel32.dll)

关系如下图所示

Untitled

用户模式中的应用程序代码要访问系统资源时, 由ntdll.dll向内核模式提出访问申请

下面是一个例子

1
2
3
4
5
6
7
8
notepad.exe要打开C:\abc.txt, 需要调用msvcrt!fopen(), 感叹号表示所属关系, 翻译过来就是: 需要调用msvcrt库中的fopen()函数
然后引发了一系列的API调用:
-msvcrt!fopen()
kernel32!CreateFileW()
ntdll!ZwCreateFile()
ntdll!KiFastSystemCall()
SYSENTER //IA-32 Instruction
->进入内核模式

如上所示, 使用常规系统资源的API会经由kernel32.dll与ntdll.dll不断向下调用, 最后通过SYSENTER命令进入内核模式, 从而实现对系统资源的调用.

29.3 API钩取

通过API钩取技术可以实现对某些Win32的API调用过程的拦截, 并获取相应的控制权限. 使用API钩取技术的优势如下:

  • 在API调用前后运行用户的”钩子”代码
  • 查看或操作传递给API的参数或API函数的返回值
  • 取消对API的调用, 或更改执行流, 执行用户代码

29.3.1 正常使用API

下图展示了正常调用API的情形, 首先在应用程序代码区域调用CreateFile()APi, 由于CreateFile()是kernel32.dll的导出函数, 所以kernel32.dll区域中的CreteFile()API会被调用执行并正常返回.

Untitled

29.3.2 钩取APi调用

下图描述的是kernel32!CreateFile()调用的情形.

Untitled

用户先使用DLL注入技术将hook.dll注入到目标进程内存空间, 然后用hook!MyCreateFile钩取对kernel32!CreateFile()的调用. 这样, 每当目标进程要调用kernel32!CreateFile() API时都会先调用hook!MyCreateFile()

29.4 技术图表

下图是一张技术图表, 涵盖了API钩取的所有技术内容.

Untitled

29.4.1 方法对象

API钩取方法(Method)的分类, 根据针对的对象(Object)不同, API钩取大致可以分为静态方法, 与动态方法

  • 静态方法针对的是”文件”
  • 动态方法针对的是进程内存

Untitled

静态方法一般很少用到, 下面主要学习的都是动态方法.

29.4.2 位置(何处)

IAT

IAT将内部的API地址更改为钩取函数地址即可

  • 优点: 实现简单
  • 缺点: 无法钩取不再IAT而在程序中使用的API

代码

系统库映射到进程内存时, 从中查找API的实际地址, 并直接修改代码.

下面有几种修改选择:

  • 使用JMP指令修改起始代码
  • 覆写函数局部
  • 仅更改必需部分的局部

EAT

将记录在DLL的EAT中的API起始地址更改为钩取函数地址. 并不常用

29.4.3 技术(如何)

具体技术分为两种:

  • 调试法:
  • 注入法: 代码注入 或 DLL注入

调试

通过调试目标进程钩取API, 这里的调试是指自己写一个调试器, 该调试器可以实现我们的钩取目的.

注入

注入技术是一种向目标进程内存区域进行渗透的技术, 根据注入对象的不同, 可细分为DLL注入和代码注入两种. 其中DLL注入技术应用最为广泛.

  • DLL注入

使用DLL注入技术可以驱使目标进程强制加载用户指定的DLL文件. 使用该技术时, 先在要注入的DLL中创建钩取代码与设置代码, 然后再DllMain中调用设置代码, 注入的同时即可完成API钩取.

  • 代码注入

广泛应用于恶意代码(病毒, ShellCode等)

代码注入实现起来要复杂一些, 原因在于, 它不像DLL注入技术那样针对的是完整的PE影响, 而是在执行代码与数据被注入的情况下直接获取自身所需API地址来使用. 访问代码中的内存地址时必须十分小心, 防止访问到错误地址.

文章作者: LamのCrow
文章链接: http://example.com/2022/04/18/逆向工程核心原理-第 a5434/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 LamのCrow