论坛首页 逆向工程技术区 阅读主题

[原创] 半年时间,我终于用懂了 eDBG —— eBPF 轻量级 trace tenet 回放伪动调的调试器

370 浏览 10 回复
#1 楼主 2026-06-01 21:09:13
项目地址:37aK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6U0K9r3g2F1P5s2k6T1i4K6u0r3k6f1c8n7c8H3`.`.

搞 Android 逆向的都知道,ptrace 调试器(frida、IDA remote dbsrv)一上来就容易被检测,各种反调试手段层出不穷。花了大半年时间断断续续踩坑,我终于把 eDBG 这套基于 eBPF 的调试 + trace 回放工作流跑通了,感觉确实好用,写篇文章记录一下。
eDBG 是什么
eDBG 是一款基于 eBPF 的轻量级 CLI 调试器,专门针对 Android ARM64 平台。它不使用 ptrace 来附加进程,而是通过内核态的 eBPF uprobe 机制来实现断点和调试,因此能够几乎完全无视用户态的反调试检测。
这个魔改 fork 版 Unicorn Trace 功能 —— 在断点处 dump 上下文,用 Unicorn 引擎做指令级模拟执行,生成 Tenet 兼容的 trace 日志。这意味着你可以在 IDA 里像动态调试一样前进后退地回放执行过程。
为什么用它
相比传统方案(frida stalker、IDA trace、qiling),eDBG 版本的 tracer 有以下好处:

基于 eBPF,基本完全无视反调试 —— uprobe 工作在内核态,用户态的 ptrace 检测、/proc/self/status TracerPid 检查等手段全部失效
下断运行更轻量,崩溃少,内嵌 dump 更快 —— 不需要注入 so,不需要 attach 进程,断点触发后直接在内核态采集寄存器和内存
可以 Unicorn 回放,直接丢给 AI 看 trace —— dump 出来的 regs.json + 内存 bin 可以直接给 LLM 分析执行流(eDBG 本身也支持 MCP 模式直接对接 AI agent)
支持 Tenet 回放调试,相当于 IDA 里伪动调,但更舒服 —— 在 IDA 里可以前进/后退逐条指令查看,还支持内存断点,比真动调更自由

效果展示
Unicorn Trace Dump 全流程
参考仓库图片
Tenet 回放调试

Tenet 内存断点
这是 eDBG + Tenet 最惊艳的能力之一:你可以在 Tenet 的回放中对任意内存地址下断点,当该地址被读写时自动定位到对应的指令。这对于分析加密算法中的 buffer 变化、追踪关键数据流向非常高效。

工作流
一个典型的 eDBG trace 分析流程如下:
┌─────────────────────────────────────────────────────────┐
│ 1. IDA 静态分析,确定目标函数入口和出口偏移 │
│ 找到 libxxx.so 中目标函数: 入口 0x1234, 出口 0x5678 │
└───────────────────────────┬─────────────────────────────┘


┌─────────────────────────────────────────────────────────┐
│ 2. 手机端启动 eDBG,设置断点 │
│ ./eDBG -p com.target.app -l libxxx.so -b 0x1234 │
└───────────────────────────┬─────────────────────────────┘


┌─────────────────────────────────────────────────────────┐
│ 3. 启动/操作目标 APP,触发断点 │
│ 程序命中 0x1234,eDBG 暂停 │
└───────────────────────────┬─────────────────────────────┘


┌─────────────────────────────────────────────────────────┐
│ 4. 执行 trace,dump + Unicorn 模拟执行 │
│ (eDBG) trace libxxx.so+0x5678 ./trace_out --tenet │
│ │
│ eDBG 自动: │
│ ① dump 当前寄存器 + 内存段 │
│ ② Unicorn 模拟执行每条指令 │
│ ③ 遇到外部调用 → 切回真实调试器执行 → 重新 dump │
│ ④ 生成 uc.log(反汇编日志)+ tenet.log(回放日志) │
└───────────────────────────┬─────────────────────────────┘


┌─────────────────────────────────────────────────────────┐
│ 5. 将 trace 产物 pull 到 PC │
│ adb pull /data/local/tmp/trace_out ./ │
└───────────────────────────┬─────────────────────────────┘

┌───────────┴───────────┐
▼ ▼
┌──────────────────────┐ ┌──────────────────────────────┐
│ 6a. IDA + Tenet │ │ 6b. 直接看 uc.log / │
│ 加载 tenet.log │ │ 丢给 AI 分析 trace │
│ 前进后退回放 │ │ 或用 local_emu.py 回放 │
│ 内存断点追踪数据流 │ │ │
└──────────────────────┘ └──────────────────────────────┘

命令速查
# 基本调试
./eDBG -p com.target.app -l libxxx.so -b 0x1234
(eDBG) c # 继续运行到断点
(eDBG) s / n # 单步步入 / 步过
(eDBG) info r # 查看寄存器
(eDBG) x SP 128 # 查看栈内存

# Trace(核心用法)
(eDBG) trace libxxx.so+0x5678 ./trace_out --tenet # trace 到目标地址,输出 tenet 日志
(eDBG) trace x30 ./trace_out --tenet # trace 到 LR(整个函数)

# 内存操作
(eDBG) dum

...(已截断)

---
来源: 看雪论坛
原文链接: https://bbs.kanxue.com/thread-291272.htm
#2 2026-06-01 21:09:13
test大佬我记得之前说过uprobe处理混淆的so不太好
#3 2026-06-01 21:09:13
动调混淆会有啥问题吗,目前我用还没遇到什么问题。如果有问题也可以用 ida 版本的插件 dump
#4 2026-06-01 21:09:13
tql
#5 2026-06-01 21:09:13
魔改kernel+硬断点替代uprobes岂不是没内存特征了?

最后于 2026-5-21 18:07
被userapp编辑

,原因:
#6 2026-06-01 21:09:13
感谢分享
#7 2026-06-01 21:09:13
这个在框架里面可以用吗?手机没root
#8 2026-06-01 21:09:13
感谢分享。
#9 2026-06-01 21:09:13
谢谢群主分享。
#10 2026-06-01 21:09:13
userapp

魔改kernel+硬断点替代uprobes岂不是没内存特征了?
是的,毕竟读取内存寄存器都是外部完成的,没有内存注入特征
#11 2026-06-01 21:09:13
啊你好哇123

这个在框架里面可以用吗?手机没root
没有 root 应该是无法用的

请登录后参与讨论

立即登录 注册账号