首页
社区
课程
招聘
Android inline hook
发表于: 2021-10-13 20:49 6652

Android inline hook

2021-10-13 20:49
6652

原理

Inline Hook 是修改原方法头几个指令,将其跳转到新方法去执行,以 ARM 指令为例,正常函数调用如图所示

 

 

调用 FuncA 方法实际是根据 FuncA_ptr 找到 FuncA 指令块执行的。

 

Inline Hook 要做的是修改正常调用流程,主要是通过修改 PC 寄存器值完成跳转

1
2
LDR PC, [PC, #-4]
addr

Arm 处理器采用3级流水线来增加处理器指令流的速度,也就是说程序计数器 R15(PC) 总是指向“正在取指”的指令,而不是指向“正在执行”的,即 PC 总是指向当前正在执行的指令地址再加 2 条指令的地址。比如当前指令地址是 0×8000, 那么当前 pc 的值,在 thumb 下面是 0×8000 + 2 * 2, 在 arm 下面是 0×8000 + 4 * 2

 

所以 ARM 执行到 LDR PC, [PC, #-4] 指令是,[PC, #-4] 代表的位置为当前指令的下一条指令,即 addr 代表的值。将 addr 写入 PC 寄存器后代表程序跳到 addr 处执行,如此就完成了函数的替换。替换后只是完成了第一步,因为必须提供方式调用原方法。

 

第二步是提供调用原函数功能,做法是开辟一块空间,记为 trampoline,将原方法的前两条指令放到 trampoline 中,然后在 trampoline 的第三条指令中加入

1
2
LDR PC, [PC, #-4]
addr2

其中 addr2 为原方法的第三条指令地址,这样调用 trampoline 就相当于调用原方法了。大体过程如下图:

 

 

第 1 步

 

修改 FuncA 函数前两个汇编指令,程序中再调用 FuncA_ptr 时,会经过 FuncA 前两条指令跳到 new-add 地址(即,方法 FuncNew)处执行,红线以下的会直接忽略,这样就做到了虽然调用的是 FuncA 函数,其实内部执行的确实 FuncNew 函数。

 

第 2 步

 

增加 Proto 方法,作用是执行原 FuncA 方法,方法 FuncNew 中调用 Proto 方法,就完成了整个 hook 过程,即,在 FuncNew 函数中既能获取到原函数 FuncA 的参数,也能获取到原函数 FuncA 的返回值。

 

以上分析属于原理分析,规避了很多问题,比如

  1. thumb 指令该如何处理
  2. arm64 指令该如何处理
  3. 原函数前两个指令中有跳转指令该如何处理
  4. 多线程中如何处理
  5. PC 相关指令的修正
  6. 其他未知情况

(inline hook 框架就是帮助处理以上问题的)

参考

Android-Arm-Inline-Hook:arm 架构下的 inline hook 讲解

Android-Arm-Inline-Hook Github 地址

Hookzz: arm64 架构下的 inline hook 讲解


[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 1
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//