首页
社区
课程
招聘
[原创]linux/android 利用shadow内存无痕hook方法
发表于: 2026-3-13 14:17 17489

[原创]linux/android 利用shadow内存无痕hook方法

2026-3-13 14:17
17489

传统hook方案很成熟——找到目标函数入口,把前几个字节改成一条跳转指令,跳到你的 hook 函数里。处理完之后再跳回去执行原始逻辑。这就是 inline hook,几乎所有 hook 框架的基本套路。

你写好了 hook,注入进去,完美运行。函数被成功劫持,返回值被修改,一切如你所愿。

然后你发现目标应用闪退了。

翻日志,发现应用在启动后会做一轮"完整性自检"——它把自己 .text 段的每个字节读出来,算一遍 CRC,和编译时的预期值对比。你写入的那条跳转指令,就这样被发现了。

这不是什么罕见的对抗手段。很多加固方案、反作弊系统、甚至一些金融类 App 都会做类似的事:读自己的代码段,检查有没有被人动过。手段可以很简单(CRC、MD5),也可以很暴力(逐字节比对、mmap 后重新校验)。

你的 hook 面临一个尴尬的处境:它必须存在于代码段里才能生效,但只要它存在于代码段里就会被发现。

不只是 inline hook。调试器断点(BRK 指令)、热补丁(NOP 替换)、uprobe——任何需要修改代码页的技术,都面临同一个根本矛盾。

而基于硬件断点的无痕hook方法受限于寄存器数量,存在诸多局限性,本文提供的方法提供的无痕hook方式 不存在这种问题。

ARM64 的内存管理单元(MMU)负责把虚拟地址翻译成物理地址。翻译的依据是页表,页表的每一项(PTE)记录了两个关键信息:这个虚拟页对应哪个物理页帧,以及访问权限是什么。

通常,一个虚拟地址只对应一个物理页面。但如果我们能在不同的时机,让 PTE 指向不同的物理页面呢?

思路就是这么直接:

准备两个物理页面。 一个是原始代码的完整拷贝,在上面写入你需要的修改(跳转指令、BRK、NOP,随便什么)——叫它 shadow page。另一个就是原封不动的原始页面——叫它 original page。

然后,根据访问类型动态切换 PTE:

ARM64 的 PTE 里有三个和权限相关的关键位:

这里有一个关键的架构特性:ARM64 的指令 fetch 不检查 AP 位。

也就是说,即使你不设 AP[1](不允许 EL0 数据访问),用户态程序的 read() 会被拒绝,但 CPU 的指令 fetch 不受影响——只要 UXN 没有置 1,这个页面上的代码就能正常执行。

这就给了我们构造"仅执行"页面的能力:

有了这组权限编码,"仅执行"和"仅读取"就不再是概念,而是可以写进页表的具体比特位。


如果在虚拟化场景(Hypervisor / EL2),事情会更干净。Stage-2 页表使用一套完全独立的权限编码,数据访问和指令取指由两组互不干扰的比特位分别控制:

关键区别在于:Stage-1 里 AP 位同时影响数据和(间接地)取指;而 Stage-2 中 S2AP 只管数据路径,XN 只管取指路径,二者完全正交。

这意味着 S2AP=00, XN=00 就是一个干净的 execute-only 语义:CPU 能取指执行,但任何 LDR/STR 都会触发 Stage-2 Data Abort,陷入 EL2。


理解了权限编码之后,关键问题是:谁来触发切换?答案是——CPU 自己。

正常运行时,代码页处于 SHADOW_X 状态(PTE 指向 shadow page,权限 --x)。程序正常跑着,CPU 取指令一切正常。直到有人试图读这个页面——两个状态之间就开始来回切换:

整个过程对进程完全透明。它读到的永远是干净的原始代码,CRC、MD5、逐字节比对——全部通过。但实际执行的是 shadow page 上被修改过的指令。

切换通过 page fault 自动触发,不需要任何额外的定时器或轮询。读了就切到原始页,执行了就切回 shadow 页,像一个跷跷板。

除了用户态的 read(),还需要处理内核态的读取路径。/proc/pid/mem、process_vm_readv、ptrace 的 PEEKDATA 走的是 GUP(Get User Pages)路径,直接解析页表拿物理页,不触发 fault。对此,我们 hook GUP 的核心函数 follow_page_pte,在读取前临时将 PTE 指向 original page,读完立刻恢复,确保所有读取路径都拿到原始代码。

还有一点值得强调:R^X 的权限拆分仅发生在页表(PTE)层面,VMA 层面完全不受影响。 我们没有修改任何 vm_area_struct 的 vm_flags,所以进程通过 /proc/self/maps 看到的内存权限仍然是原始的 r-xp——不会突然变成 --xp 或 r--p。同理,mprotect 的查询、mincore、以及内核内部遍历 VMA 的逻辑,都看不到任何异常。权限的"跷跷板"只在硬件页表这一层悄悄发生,内核的内存管理子系统对此一无所知。


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

最后于 2026-3-16 23:44 被wx_唔.编辑 ,原因:
收藏
点赞 ・103
打赏
分享
最新回复 (63)
雪    币: 0
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
2 楼
666
2026-3-13 14:19
0
雪    币: 13
活跃值: (2758)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
3 楼
首评666
2026-3-13 14:19
0
雪    币: 1883
活跃值: (3063)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4 楼
夜深灯冷代码长,
反编译里见锋芒。
字节翻飞寻旧迹,
栈帧回溯破迷障。

影子一页藏天地,
Hook落指改阴阳。
众人只见程序跑,
谁识其间妙手匠。

彪天帝名传逆向界,
一行补丁定四方。
安卓千层迷雾里,
提剑而行是彪郎。
2026-3-13 14:20
2
雪    币: 1674
活跃值: (1289)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
5 楼
夜深灯冷代码长,
反编译里见锋芒。
字节翻飞寻旧迹,
栈帧回溯破迷障。

影子一页藏天地,
Hook落指改阴阳。
众人只见程序跑,
谁识其间妙手匠。

彪天帝名传逆向界,
一行补丁定四方。
安卓千层迷雾里,
提剑而行是彪郎。
2026-3-13 14:21
0
雪    币: 1
活跃值: (201)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6 楼
牛逼 大佬????‍♂️
2026-3-13 14:21
0
雪    币: 5678
活跃值: (6960)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
7 楼
牛逼
2026-3-13 14:26
0
雪    币: 51
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
8 楼
tql
2026-3-13 14:26
0
雪    币: 20
活跃值: (1792)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9 楼
tql
2026-3-13 14:36
0
雪    币: 10
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
10 楼
夜深灯冷代码长,
反编译里见锋芒。
字节翻飞寻旧迹,
栈帧回溯破迷障。

影子一页藏天地,
Hook落指改阴阳。
众人只见程序跑,
谁识其间妙手匠。

彪天帝名传逆向界,
一行补丁定四方。
安卓千层迷雾里,
提剑而行是彪郎。
2026-3-13 14:39
0
雪    币: 411
活跃值: (1041)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11 楼
夜深灯冷代码长,
反编译里见锋芒。
字节翻飞寻旧迹,
栈帧回溯破迷障。

影子一页藏天地,
Hook落指改阴阳。
众人只见程序跑,
谁识其间妙手匠。

彪天帝名传逆向界,
一行补丁定四方。
安卓千层迷雾里,
提剑而行是彪郎。
2026-3-13 14:40
0
雪    币: 1883
活跃值: (3063)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12 楼
彪天帝牛逼
2026-3-13 14:41
0
雪    币: 3654
活跃值: (7535)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
13 楼
夜深灯冷代码长,
反编译里见锋芒。
字节翻飞寻旧迹,
栈帧回溯破迷障。

影子一页藏天地,
Hook落指改阴阳。
众人只见程序跑,
谁识其间妙手匠。

彪天帝名传逆向界,
一行补丁定四方。
安卓千层迷雾里,
提剑而行是彪郎。
2026-3-13 14:41
0
雪    币: 198
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
14 楼
tql
2026-3-13 14:43
0
雪    币: 2036
活跃值: (3876)
能力值: ( LV4,RANK:49 )
在线值:
发帖
回帖
粉丝
15 楼
tql
2026-3-13 14:58
0
雪    币: 6771
活跃值: (17229)
能力值: ( LV9,RANK:270 )
在线值:
发帖
回帖
粉丝
16 楼
点赞,一个硬件断点一个PET ,都是可以不修改内存实现hook,各有各的好 ,能结合一下是最好的。
2026-3-13 15:12
1
雪    币: 547
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
17 楼
LittleQ发来贺电
2026-3-13 15:22
0
雪    币: 20
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
18 楼
6666
2026-3-13 15:31
0
雪    币: 764
活跃值: (3857)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19 楼
6666
2026-3-13 15:34
0
雪    币: 21
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
20 楼

我不是卷王发来贺电
2026-3-13 15:57
0
雪    币: 200
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
21 楼
硬件断点命中了直接pc到自己的逻辑去,是一个比较成熟的无痕hook方案了
2026-3-13 16:06
0
雪    币: 35
活跃值: (8488)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
22 楼
无敌了
2026-3-13 16:23
0
雪    币: 24
活跃值: (1574)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
23 楼
开始掀桌子了
2026-3-13 16:31
0
雪    币: 110
活跃值: (9616)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
24 楼
tql
2026-3-13 16:42
0
雪    币: 3633
活跃值: (7450)
能力值: ( LV11,RANK:185 )
在线值:
发帖
回帖
粉丝
25 楼
你这个思路很润,我拿走了,哈哈
2026-3-13 17:07
0
游客
登录 | 注册 方可回帖
返回