首页
社区
课程
招聘
[原创]Inline-Hook指令还原
2020-11-9 10:00 4296

[原创]Inline-Hook指令还原

2020-11-9 10:00
4296

inline-hook的详细过程在 ele7enxxh的博客中已经写的很清楚了。 下面是自己对指令修复的一些细节位置的学习,特别是指令的二进制表达形式。

 

图片描述
inline-hook 需要把原函数中的指令拷贝到另一个地方,如果这些指令与 pc 相关,在拷贝之后,由于 pc 发生了变化,所以这些指令就需要被修复。

 

下面以 blx 指令的修复为例子。

 

假定被 hook 地址处(hook_addr)前几条指令如下,并且处于 arm 模式,那么现在需要备份的指令是前三条指令 blx addr; ins1; ins2;,并且可以得到此时的 pc = hook_addr + 8lr = hook_addr + 12

1
2
3
4
blx offset    ;(hook地址,也就是hook_addr)
ins1
ins2        ;(pc=hook_addr+8)
ins3        ;(lr=hook_addr+12)

blx offset 真实的跳转地址应该是 target_addr = pc + offset,为了防止指令拷贝到其他地方之后,因为 pc 值的的改变而导致计算出的 target_addr 改变,需要先计算出真实的 target_addr ,再用直接跳到 target_addr 的指令替换 blx offset

 

比如可以将 blx offset 替换成如下指令:

1
2
LDR PC, [PC, #-4]    ;pc=target_addr
target_addr          ;target_addr是计算后跳转的绝对地址,直接赋值给pc来改变执行位置

下面就看怎么计算跳转的绝对地址 target_addr

 

首先我们查 arm 手册得到 blx 指令格式:
图片描述

 

可以看出 target_addr = instruction + 8 + 4 * offset + 2 * a ,

 

instruction + 8 也就是当前 pc 的值;

 

offset 也就是指令字节码后24位,可以通过 offset = ins & 0xFFFFFF; 计算得到。offset * 4 等于 offset << 2

 

a 是字节码中第25位,也就是 ins & 0x1000000 >> 24; 2a 就等于 ins & 0x1000000 >> 23;

 

计算 target_addr 的过程转成对应的代码就是下面这样:

1
2
3
4
5
x = ((instruction & 0xFFFFFF) << 2) | ((instruction & 0x1000000) >> 23);
top_bit = x >> 25; //符号处理
imm32 = top_bit ? (x | (0xFFFFFFFF << 26)) : x;
//修复后的绝对地址
value = pc + imm32 + 1;

阿里云助力开发者!2核2G 3M带宽不限流量!6.18限时价,开 发者可享99元/年,续费同价!

收藏
点赞4
打赏
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回