PTE Breakpoint — 问题总结
已解决的问题
1. Kernel Text 写保护 Panic
- 现象: insmod 直接 panic
- 根因:
*(u32*)addr = insn直接写内核 .text 段,CONFIG_STRICT_KERNEL_RWX 禁止 - 修复: 改用 kallsyms 解析
aarch64_insn_patch_text_nosync(内核函数,会临时关写保护) - 状态: ✅ 已修复,B-detour hook 安装成功
2. set_memory_x 未导出
- 现象: insmod 报
Unknown symbol set_memory_x (err -2) - 根因: 编译环境 Module.symvers 有该符号,但设备运行内核未导出
- 修复: 改为 kallsyms 解析 +
__nocfiwrapper - 状态: ✅ 已修复
3. register_user_step_hook 未导出
- 现象: 交叉验证发现之前 agent 幻觉称已导出
- 根因: 源码确认无 EXPORT_SYMBOL_GPL,只有 break_hook 系列导出
- 修复: 改为 kallsyms 解析 +
__nocfiwrapper - 状态: ✅ 已修复
4. 首条指令是 PACIASP 不是 SCS push
- 现象: dmesg
first insn: 0xd503233f - 根因: SM8750 有 PAC 硬件,
should_patch_pac_into_scs()返回 false,不替换 - 修复: 运行时读取实际指令保存到 trampoline,不硬编码
- 状态: ✅ 已修复
5. CFI 拦截 kallsyms 间接调用
- 现象: CONFIG_CFI_CLANG=y,通过函数指针调用会被 KCFI 类型检查拒绝
- 修复: 所有 kallsyms 调用用
__nocfiwrapper 包装(同 kernel_patch.c 模式) - 状态: ✅ 已修复
6. cpuhp 回调 WARN_ON
- 现象:
ptebp_cpu_online在 dmesg 打出大量 Call trace - 根因:
enable_debug_monitors内部WARN_ON(preemptible()),cpuhp 回调上下文可能 preemptible - 影响: 只是 warning,不 panic,功能正常
- 状态: ⚠️ 已知,可后续修复(在 callback 里加 preempt_disable)
当前卡住的问题
7. PTE=0 后 fault handler 没有命中
- 现象: ptebp_set 返回 0(成功),PTE 确认被改为 0,但 3 秒后 poll 返回 0 hits
- 已排除:
- TLB flush:已改为
tlbi vmalle1is(全局刷新),仍无效 - PTE 值:dmesg 确认 before=0x20000bcb50afc3, after=0x0(PTE=0 确实写入了)
- fault handler 是否被调用:是的,加载时有 fault 进来,说明 B-detour 工作正常
- 地址范围:delta=47MB,在 ±128MB B 指令范围内
- TLB flush:已改为
- 可能根因:
- contpte: 即使 PTE=0,contiguous PTE 优化可能让 TLB 仍使用相邻 PTE 的 contiguous 条目。需要在 set 时清除相邻 15 个 PTE 的 PTE_CONT bit
- __set_pte vs contpte_set_ptes: 这个内核的
__set_pte可能被 contpte 层包装了,实际写入时被 contpte 逻辑”修复”回去 - PTE walk 返回的 ptep 指向 contpte 的折叠页表项:
pte_offset_map在 contpte 内核上返回的可能不是真正的硬件 PTE,而是 contpte 的软件映射 - mm 不匹配: fault handler 里
current->mm != slot->mm(不太可能,同一进程) - FSC 过滤: PTE=0 应该产生 translation fault (FSC 0x04-0x07),fault handler 已处理这个范围
- server.c 的 ioctl 调用: 可能 server 端 ioctl 没有正确传递参数(但 dmesg 有 “ptebp set” 日志说明 ioctl 到达了内核)
8. 权限位方案被 contpte 阻挡(已放弃)
- 现象: 设 PTE_UXN 后 PTE 确认改变(0x20→0x60),但无 fault
- 根因: contpte 将 16 个连续 PTE 合并为一个 TLB 条目,修改单个 PTE 的权限位不影响 TLB 缓存的 contiguous 条目
- 状态: ❌ 放弃权限位方案,改用 PTE=0(但 PTE=0 也不工作,见问题 7)
下一步调查方向
- 验证 contpte 对 PTE=0 的影响:在
do_ptebp_set里打印__ptep_get返回值(contpte 可能让读回的值和写入的不同) - 用
contpte_try_unfold先展开 contiguous 块再修改:通过 kallsyms 解析__contpte_try_unfold - 对比 shadow_pg.c 的做法:shadow_pg 在 patched kernel 里工作,它的
__set_pte调用为什么能生效?可能因为 shadow_pg 通过 kernel_patch.ko 的 fault hook 工作,而 kernel_patch.ko 可能在 hook 点之前做了 contpte unfold - 直接写物理地址:绕过 contpte 层,直接操作硬件 PTE(通过 phys_to_virt 或 fixmap)
- 用 ptep_clear_flush 内核函数:这是内核正规的清 PTE 路径,会正确处理 contpte
架构总结
[工作的部分]
- kallsyms 解析 ✅
- B-detour hook 安装 ✅ (aarch64_insn_patch_text_nosync)
- fault handler 被正确调用 ✅
- step hook 注册 ✅
- MDE 全局启用 ✅ (on_each_cpu + cpuhp)
- server CMD 0xD0-0xD3 ✅
- 客户端 ce_client.py + settings.py + hwbp_window.py 分流 ✅
[不工作的部分]
- PTE 修改不生效(contpte 问题)❌
- 因此整个 fault→hit→single-step→re-arm 链路未验证Last updated on