MG1937/ASC:面向 Agent 的极速 Android 反编译前端

ASC 是一款专为安全研究人员和移动取证人员打造的超高速 Android 反编译前端工具。


Droid ASC:将 R8 编译器优化作为反编译原语

https://blackhat.com/europe/arsenal/schedule/index.html#droid-asc-r8-compiler-optimization-as-a-decompiler-primitive-54834

在反编译大型 Android APK 时,常规做法是等待——等待工具消耗数 GB 内存,完全展开所有构件,并花费数十分钟构建庞大的全局索引与交叉引用……这一切都只是为了后续能够快速搜索代码,但其中却存在矛盾。

已编译的二进制文件本身已经高度结构化,而现代反编译器却从未加以利用,反而浪费大量时间和内存,在已有结构化的数据上重新构建臃肿的代码关系数据库。

这种工程思路有悖常理:既然我能够在毫秒级时间内直接从 APK 中提取任意代码关系,那么这种预处理还有存在的价值吗?

我们没有让反编译器进行繁重的预处理,而是选择直接将已编译的二进制文件当作数据库来查询。我们开发了一种无状态、零开销的引擎,能够在毫秒级时间内按需提取并搜索代码。

在本次分享中,我们将探讨绕过传统瓶颈所需的底层技术;演示如何通过直接解析 Deflate 压缩流来避免完整解压,构建高效的霍夫曼查找表,从而在不触碰无关数据块的情况下提取核心元数据;此外,我们还将阐述 R8 编译器的优化细节,特别是其确定性的常量重定位与指令去重机制如何生成高度紧凑的物理布局,并利用这一特性实现闪电般的跨 DEX 代码搜索。

为了将这些原始字节码偏移映射回方法,我们设计了一种 O(1) 复杂度的指令定位原语,无需构建庞大的映射表即可实现常数时间的方法解析。

最后,当命中目标时,Droid ASC 仅提取相关字节码及其依赖项,在内存中动态重建一个精简且自洽的 DEX 文件,从而实现即时反编译。

我们将针对一个 352 MB 的商业 APK 现场演示该架构。Droid ASC 在 1.79 秒内完成全局交叉引用搜索,仅使用 141 MB 内存便能在 177 毫秒内反编译目标类。

通过将二进制文件视作只读数据库并完全跳过预处理,我们让反编译器回归其本质:它不再是一个臃肿的索引工具,而是一台超高速、按需运行的反编译引擎,从根本上重塑了我们分析已编译代码的方式。

基准测试

Benchmark

https://github.com/user-attachments/assets/4c4a6813-8561-490c-a573-ef113da861b6

安装

# 从 PyPI 安装
pip install droidasc

# 或者从源码安装
pip install .

安装完成后,droidasc 命令行工具将在系统中全局可用:

用法:droidasc [-h] {getclass,getmanifest,findrefs} ...

ASC 工具入口。

位置参数:
  {getclass,getmanifest,findrefs}
    getclass            在 APK 中定位目标类,在内存中提取单个 DEX 并进行反编译。
    getmanifest         从 APK 中解码 AndroidManifest.xml 并以 XML 格式输出。
    findrefs            在 APK 的所有 DEX 文件中查找字符串/类型/方法/字段的代码引用。

可选参数:
  -h, --help            显示本帮助信息并退出

示例:
  droidasc app.apk --gui
  droidasc getclass app.apk Lcom/poc/Main; -o Main.java
  droidasc getclass app.apk com.poc.Main --threads 16
  droidasc getmanifest app.apk -o AndroidManifest.xml
  droidasc findrefs app.apk string token -o string_refs.txt
  droidasc findrefs app.apk type com.poc.Main
  droidasc findrefs app.apk method onCreate --class com.poc.Main
  droidasc findrefs app.apk method notify --class MainActivity --fuzzy-class -o method_refs.txt
  droidasc findrefs app.apk field apiKey -o field_refs.txt

您也可以像以前一样使用 python main.py,它会调用相同的入口点。

添加评论
点赞收藏
点踩分享查看原文
评论
?
参与讨论