cecini
1. [但是由于eBPF的局限性,其无法替代FART等基于主动调用的脱壳工具](c1eK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6T1L8r3!0Y4i4K6u0W2L8r3I4W2j5i4k6W2M7$3N6Q4x3X3g2@1L8%4m8Q4x3V1k6S2M7Y4c8A6j5$3I4W2i4K6u0r3k6f1u0b7c8V1c8W2P5p5c8#2L8i4m8W2M7W2)9J5z5b7`.`.
有什么局限,导致功能 ...
1. eBPF 局限带来的功能区别
eBPF/uProbe 方案的限制主要在“只能看到发生过的事”:
- 没执行到的方法,不一定能拿到真实 CodeItem。壳如果按需解密方法体,只有方法真正进入解释器/ART 路径时,eBPF 才有机会记录。
- 它不能主动枚举类和方法,也不能替你调用每个方法。FART 的强项正是主动遍历类方法、触发方法解密,再 dump CodeItem 并回填。
- 如果代码走 AOT/JIT/native 快路径,绕开你挂的 ART 解释器点,eBPF 可能只能拿到整体 DEX,拿不到执行时还原的方法体。
- 如果内存中没有连续合法 DEX,只是 native 层临时拼出碎片、解密后马上擦除,通用 eBPF DEX 扫描也不一定能拼回完整文件。
- eBPF 内核侧不能随意做复杂逻辑,受 verifier、栈大小、ring buffer、用户内存读取限制影响。文章里也提到过内核侧分片传 DEX 容易丢数据,后来才转向用户态 process_vm_readv 读取。
所以功能上可以这么理解:
- eBPFDexDumper-rs 更适合:低侵入、被动捕获、拿运行时已加载的 DEX、记录已执行方法字节码、适合常规壳和动态加载场景。
- FART 更适合:代码抽取壳、方法体被 nop/占位替换、需要主动触发每个方法恢复真实 CodeItem 的场景。
- eBPF 的优势是隐蔽和部署轻;FART 的优势是覆盖率和主动性,但侵入更强,通常依赖 ART/系统改造或更重的运行时控制。
2. “不绕过所有反分析,不保证 native/VMP 极端样本”具体指什么
“反分析能力”这里不是一句泛泛而谈,具体包括这些:
- 目标可以检测 root、调试环境、异常系统属性、可疑文件、SELinux 状态、Magisk 痕迹等。这个项目不会帮你隐藏这些环境特征。
- uProbe 不是完全无痕。它通常会在目标映射上留下可检测的断点式痕迹,强对抗样本可以校验 libart.so 代码页、扫描异常指令、检测性能/时序异常。
- 目标可以检测 BPF/tracing 相关状态,比如内核 tracing、perf/uProbe 行为、BPF program/map 痕迹。当前项目提供 --probe-mode lifecycle|maps-only 降低探针面,但不是“反检测框架”。
- 目标可以不让敏感代码进入 ART 字节码路径,例如把核心逻辑搬到 native .so,Java 层只剩 JNI 壳或空方法。这种情况下 dump 出 DEX 也看不到核心算法。
- “完全 native 化”指业务逻辑已经变成 ARM64 机器码,DEX 里只有声明、桥接、加载器或少量壳代码。eBPF 盯 ART/DexFile 只能拿 Java 层结构,不能自动还原 native 算法。
- “VMP 化”指原始字节码被翻译成壳自定义虚拟机指令,运行时由 native VM 解释器执行。此时 DEX 里可能只剩 VM 入口和字节码 blob,真实语义在 native VM 指令集中,dump DEX 不等于还原源码。
- “代码抽取”指 DEX 方法体被 nop、空实现或占位结构替代,真实 CodeItem 在执行前才临时恢复。被动方案只能覆盖触发过的部分;没触发的仍然缺失。