开源项目 GitHub Trending 2026-09-15T12:01 正文 ok 516 words

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

英文标题:🔥 MG1937/ASC

Droid ASC 是一款面向 Agent 和移动安全研究人员的 Android APK 反编译前端,主张绕过传统反编译器耗时且占用内存巨大的全量预处理与索引构建流程。它将已编译的 APK 直接视作可查询数据库,通过直接探测 Deflate 位流、利用 R8 编译器产生的物理布局特征,以及 O(1) 指令定位机制,实现按需提取和反编译。演示数据显示,针对一个 352MB 的商业 APK,Droid ASC 可在 1.79 秒内完成全局交叉引用搜索,并以 141MB 内存、177 毫秒完成目标类反编译。该工具为开发者和移动研究人员提供了更轻量、快速的 APK 代码检索、Manifest 解码与按需反编译方案。
打开原文相关 3 · 机会 3
media810.0 KB media90.9 KB

中文

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 位流中探测来放弃完整解压,构建高密度 Huffman 查找表,在不触碰无关数据块的情况下提取核心元数据。此外,我们将解释 R8 编译器的优化细节,尤其是确定性常量重定位和指令去重如何留下高度集中的物理布局;我们将这种编译器行为转化为能力,实现闪电般快速的跨 DEX 代码搜索。为将这些原始字节码偏移映射回方法,我们设计了一种 O(1) 指令定位原语,无需构建庞大的映射表即可实现常数时间的方法解析。最后,在命中目标后,Droid ASC 仅提取特定字节码及其依赖项,在内存中动态重建一个最小且自洽的 DEX,以实现即时反编译。

我们将针对一个 352MB 的商业 APK 现场演示这一架构。Droid ASC 能在 1.79 秒内执行全局交叉引用搜索,并且仅使用 141MB 内存,即可在 177 毫秒内反编译目标类。通过将产物视为只读数据库并实现零预处理,我们让反编译器回归其核心本质:它不再是臃肿的索引工具,而是一个闪电般快速、按需运行的反编译引擎,从根本上重新定义了分析编译代码的方式。

基准测试

视频/嵌入内容:ASC_Benchmark.mp4

# from PyPI
pip install droidasc

# or from source
pip install .

安装后,droidasc CLI 命令可在全局范围内使用:

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

ASC tooling entry.

positional arguments:
  {getclass,getmanifest,findrefs}
    getclass            Locate the target class in APK, extract one DEX in memory, then decompile.
    getmanifest         Decode AndroidManifest.xml from APK and print it as XML.
    findrefs            Find code references for string/type/method/field across all DEX entries in APK.

options:
  -h, --help            show this help message and exit

examples:
  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——它会委托给同一个入口点。

English / 原文

Droid ASC: R8 Compiler Optimization as a DeCompiler Primitive

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

When decompiling massive Android APKs, the standard procedure is to wait. We wait for tools to eat gigabytes of RAM, fully inflate the artifacts, and spend tens of minutes building heavy global indexes and cross references... All of this is just to guarantee fast code searches later, but here is the contradiction. A compiled artifact is already highly structured, modern decompilers never utilize this, they waste massive amounts of time and memory reconstructing a bloated database of code relationships over already structured data. This engineering approach defies common sense. When I can directly extract any code relationship from the APK in milliseconds, does this preprocessing still hold any value?

Instead of forcing decompilers into heavy preprocessing, we choose to query the compiled artifact directly as a database. We built a stateless, zero-overhead engine that extracts and searches code on demand in milliseconds. In this briefing, we will explore the underlying engineering required to bypass traditional bottlenecks. We will demonstrate how to abandon full inflate by probing directly within the Deflate bitstream, building dense Huffman lookup tables to extract core metadata without touching irrelevant data blocks. Furthermore, we will explain optimization details of the R8 compiler, especially how deterministic constant relocation and instruction deduplication leave behind highly concentrated physical layouts, we weaponize this compiler behavior to execute lightning-fast cross DEX code searches. To map these raw bytecode offsets back to methods, we engineered an O(1) instruction locating primitive, achieving constant-time method resolution without building heavy mapping tables. Finally, upon hitting a target, Droid ASC extracts only the specific bytecodes and its dependencies, dynamically reconstructing a minimal and self consistent DEX entirely in memory for instant decompilation.

We will demonstrate this architecture live against a 352MB commercial APK. Droid ASC executes global cross reference searches in 1.79 seconds and decompiles target classes in 177 milliseconds using only 141MB of RAM. By treating the artifact as a read only database and operating with zero preprocessing, we return the decompiler to its core essence. It is no longer a bloated indexing tool, but a lightning fast, on demand decompilation engine that fundamentally redefines how we analyze compiled code.

Benchmark

ASC_Benchmark.mp4

# from PyPI
pip install droidasc

# or from source
pip install .

After installation, the droidasc CLI command is available globally:

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

ASC tooling entry.

positional arguments:
  {getclass,getmanifest,findrefs}
    getclass            Locate the target class in APK, extract one DEX in memory, then decompile.
    getmanifest         Decode AndroidManifest.xml from APK and print it as XML.
    findrefs            Find code references for string/type/method/field across all DEX entries in APK.

options:
  -h, --help            show this help message and exit

examples:
  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

You can also use python main.py as before — it delegates to the same entry point.