type
Post
status
Published
date
May 3, 2026
slug
summary
tags
系统调用
作弊
内核
内核模块
Linux
安全
category
技术分享
icon
password
核心原理
ARM64 页表项有一个 UXN(Unprivileged eXecute Never)位。将目标代码页的 PTE 设置 UXN=1 后,用户态执行该页任何指令都会触发 Instruction Abort(EC=0x20, DFSC=Permission Fault),陷入 EL1。
内核侧通过 inline hook do_mem_abort() 注册自定义 handler,在异常到达信号投递之前拦截。handler 检查 fault 地址是否属于已注册的断点页,是则修改 pt_regs->pc 重定向到预编译的 recomp(重编译)页,返回用户态后 CPU 从recomp 页继续执行。整个过程对用户态透明:没有 ptrace、没有 BRK 指令、没有信号投递。
重编译引擎
对目标页的全部 1024 条指令(4KB / 4 = 1024)做静态重编译:
两趟扫描
- 布局计算:遍历每条指令,分类并计算 expansion 大小,构建 offset_map[insn_idx] → output_offset 映射表
- 代码生成:根据分类结果 emit 重编译指令到 output buffer
指令分类与改写规则
指令类型 | 页内 (inpage) | 页外 (outpage) |
普通指令 | 1:1直通 | — |
B (无条件跳转) | 重算 offset | nearby: 直接 B /far: 压栈 + 跳回原页触发 fault |
BL (带链接跳转) | LR = 原始下一条,B 页内 | LR = 原始下一条,B/BR 外部目标 |
B.cond / CBZ / TBZ | 重算 imm | 条件跳 + 8, B skip, far redirect |
ADRP / ADR | LDR Xd, [PC, #8]; B skip; .quad addr | — |
LDR literal | 用 X17 做中转加载原始数据地址 | — |
关键设计:所有 PC-relative 指令都被改写为绝对寻址,保证在 recomp 页新位置上语义不变。
recomp 页以
VM_READ | VM_EXEC | VM_MIXEDMAP | VM_DONTDUMP 映射到目标进程用户空间,由 insert_vm_struct() 直接插入 VMA。三种断点模式
BP_MODE_DBI(轻量断点,12 slot prefix)
BP_MODE_INSTRUMENT(全上下文,89 slot prefix)
BP_MODE_INLINE_HOOK(函数替换,4 slot prefix)
不保存 LR,handler 看到原始调用者的 LR。适合函数级替换。
Fault Handler 调度逻辑
Nearby vs Far 模式
recomp 页分配时用 get_unmapped_area(hint=原始页地址) 尝试就近分配:
- Nearby(±120MB 内):outpage 分支直接用 B imm26(±128MB 范围),零寄存器污染
- Far(超出范围):压 32 字节栈帧(saved X17 + magic + target PC),跳回原始 UXN 页触发 fault,fault handler 从栈帧取出真实目标地址
BP_FLAG_NO_NEARBY 可强制 far 模式.
