# ddc — DEX → Java 反编译器(Rust) [English](README.md) | **简体中文** [![CI](https://github.com/ejfkdev/ddc/actions/workflows/ci.yml/badge.svg)](https://github.com/ejfkdev/ddc/actions/workflows/ci.yml) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE) `ddc` 把 Android DEX 字节码反编译回可读的 Java —— 真实 App 级别的速度、 可以像数据库一样查询,并且**经过 javac 验证**:七个真实 APK 共 909,689 个输出文件全部零语法错误。 ## 特性 - **快** —— 226MB/20 dex 的 weibo(9.8 万个类)全量反编译 **5.0s**, 398MB 的飞书 **5.5s**;病态类跑在带截止期的受控线程上,不会拖死 整个运行。 - **能编译** —— 七个基准 APK(reqable/Telegram/WhatsApp/weibo/weixin/ qq/lark,共 91 万文件)的输出全部通过 javac,**零语法错误**; 大小写仅差一位的类名对(`X/Cua` vs `X/cua`)两个类都各自成文件, 不再后者覆盖前者。 - **渐进式反编译** —— 20+ 查询子命令(字符串、交叉引用、继承谱、 manifest、资源、方法粒度反编译)毫秒级出答案:先查元数据、按需定点 反编译,绝大多数分析不必付全量的代价。 - **DEX 035–041 全版本** —— 多 dex APK、XAPK/APKS/APKM 容器、 invoke-custom;lambda 与字符串拼接折叠回真 Java(`(a) -> …`、 `Cls::name`、`a + b`)。 - **可读输出** —— jadx 式局部变量名(`str`、`getName() → name`、 Kotlin `Intrinsics` 参数名)取代 `v12`;IntDef 魔法数字开箱即用 按常量名渲染(`setVisibility(8)` → `View.GONE`;内置 android-37 域表,`--symbols` 可覆盖);Kotlin 空检查噪声消除、synthetic `access$NNN` 桥在调用点内联。 - **可复现输出** —— 无时间戳,两次运行 diff 干净。 - **中英双语 CLI** —— 按环境变量自动识别语言(`DDC_LANG=zh|en` 强制 指定,回退英文)。 - 基于 [`jdc-core`](https://crates.io/crates/jdc-core) —— 与 [jcdc](https://github.com/ejfkdev/jcdc) 共用的机器无关反编译核心。 ## 安装 **macOS**(Homebrew): ```bash brew install ejfkdev/tap/ddc ``` **Windows**(Scoop): ```bash scoop install ejfkdev/scoop-bucket/ddc ``` **cargo-binstall**(全平台——直接下载预编译 release 二进制,不用本地 编译): ```bash cargo binstall ddc-cli ``` **二进制**:每个 [release](https://github.com/ejfkdev/ddc/releases) 附带 裸二进制(无压缩包),覆盖 `linux-amd64`、`linux-arm64`、 `windows-amd64`、`windows-arm64`、`macos-amd64`、`macos-arm64`——非 macOS 平台已 UPX 压缩。 **源码构建**(Rust stable): ```bash git clone https://github.com/ejfkdev/ddc && cd ddc cargo build --release ``` ## 用法 ```bash ddc app.apk # 全量反编译 → app-out/ ddc app.apk -c com.example.Foo # 单类输出到 stdout ddc app.apk -o - | less # 全部输出到 stdout ddc info app.apk # App 上下文(应用名、包名、版本、 # md5)+ 每镜像计数 ddc mainactivity app.apk # 入口:包名 + 启动 Activity ddc findrefs app.apk string token # 每个 const-string "token" 引用点 ddc getmethod app.apk Foo.toString # 单方法,含全部重载 ddc pkg app.apk --app -o own/ # 只反编译 App 自身代码 ``` 完整选项与示例见 `ddc --help`(按工作流分组的子命令菜单)。更详细的 完整参考 —— 每个选项的语义、每个子命令的输出格式与行为 —— 见 [docs/zh-CN/cli.md](docs/zh-CN/cli.md)([English](docs/cli.md))。 ## 性能 七个真实 APK,release 构建,3 连测取平均(Apple Silicon 6P+12E)。 39 个 APK 的验证语料(408 万个反编译文件,每个 APK 的墙钟 / 峰值 RSS / javac 解析门)见 [docs/zh-CN/validation.md](docs/zh-CN/validation.md) ([English](docs/validation.md))。
全量反编译 —— 7 个真实 APK | APK | 大小 | 全量反编译 | 峰值 RSS | |---|---|---|---| | reqable | 34 MB | **0.25s** | 139 MB | | Telegram | 62 MB | **5.64s** | 1479 MB | | WhatsApp | 139 MB | **5.87s** (99,277 个文件——大小写变体类对全部保留) | 1116 MB | | weibo | 226 MB | **5.03s** | 1172 MB | | weixin | 268 MB | **11.61s** | 1339 MB | | lark | 398 MB | **5.52s** | 1831 MB | | qq | 374 MB | **15.92s** | 2459 MB |
同一批 APK 上的查询子命令(单元格:耗时 / 峰值 RSS;`strings -f <包名> --with-locations`,`findrefs` 查包名字符串与方法 `onCreate`, `hierarchy`/`disasm`/`getclass` 用各 App 启动类):
查询子命令 —— 13 个命令 × 7 个 APK | 子命令 | reqable | Telegram | WhatsApp | weibo | weixin | lark | qq | |---|---|---|---|---|---|---|---| | `info` | 0.12s / 40MB | 0.21s / 88MB | 0.42s / 305MB | 0.65s / 610MB | 0.79s / 550MB | 1.10s / 907MB | 1.08s / 1240MB | | `listclasses` | 0.04s / 21MB | 0.06s / 84MB | 0.08s / 93MB | 0.13s / 396MB | 0.21s / 417MB | 0.20s / 299MB | 0.27s / 391MB | | `manifest` | 0.03s / 7MB | 0.03s / 14MB | 0.02s / 20MB | 0.03s / 43MB | 0.04s / 31MB | 0.03s / 28MB | 0.03s / 47MB | | `mainactivity` | 0.04s / 24MB | 0.06s / 86MB | 0.08s / 224MB | 0.10s / 358MB | 0.13s / 371MB | 0.14s / 421MB | 0.21s / 554MB | | `res` | 0.02s / 7MB | 0.03s / 15MB | 0.03s / 22MB | 0.05s / 60MB | 0.04s / 32MB | 0.04s / 31MB | 0.05s / 53MB | | `largest` | 0.05s / 29MB | 0.08s / 78MB | 0.15s / 236MB | 0.31s / 500MB | 0.32s / 500MB | 0.46s / 676MB | 0.66s / 810MB | | `strings` | 0.05s / 24MB | 0.10s / 85MB | 0.21s / 222MB | 0.39s / 354MB | 0.45s / 395MB | 0.52s / 431MB | 0.81s / 551MB | | `findrefs-string` | 0.04s / 26MB | 0.05s / 70MB | 0.06s / 214MB | 0.10s / 403MB | 0.12s / 446MB | 0.07s / 335MB | 0.14s / 871MB | | `findrefs-method` | 0.05s / 26MB | 0.07s / 70MB | 0.07s / 219MB | 0.09s / 410MB | 0.10s / 458MB | 0.10s / 620MB | 0.15s / 896MB | | `members` | 0.07s / 23MB | 0.21s / 86MB | 0.62s / 222MB | 1.32s / 366MB | 1.17s / 381MB | 1.64s / 443MB | 2.66s / 572MB | | `hierarchy` | 0.04s / 24MB | 0.05s / 86MB | 0.09s / 212MB | 0.12s / 396MB | 0.14s / 386MB | 0.17s / 429MB | 0.22s / 548MB | | `disasm` | 0.04s / 23MB | 0.07s / 88MB | 0.09s / 214MB | 0.12s / 371MB | 0.13s / 392MB | 0.16s / 422MB | 0.20s / 533MB | | `getclass` | 0.05s / 34MB | 0.28s / 182MB | 0.14s / 357MB | 0.33s / 740MB | 0.37s / 942MB | 0.50s / 1235MB | 0.76s / 1651MB |
## 文档 | | | |---|---| | [架构](docs/zh-CN/architecture.md) | 三个 crate、提升/结构化/输出管线、DEX 版本、invoke-custom([EN](docs/architecture.md)) | | [CLI 参考](docs/zh-CN/cli.md) | 全部选项与子命令详解([EN](docs/cli.md)) | | [子命令](docs/zh-CN/subcommands.md) | 渐进式分析完整参考([EN](docs/subcommands.md)) | | [基准](docs/zh-CN/benchmarks.md) | 耗时/内存、方法论、与 ASC 对比([EN](docs/benchmarks.md)) | | [性能工程](docs/zh-CN/optimization.md) | 5 分钟 → 6s:六轮优化与实测排除的捷径([EN](docs/optimization.md)) | | [语料验证](docs/zh-CN/validation.md) | 39 个真实 APK、408 万文件全部 javac 解析零错误,含发现并修复的 bug 清单([EN](docs/validation.md)) | ## 已知限制 擦除类型(DEX 无 Signature);d8 反糖的 `-$$Lambda$` 类独立成文件;极少数 R8 巨兽方法超时降级(个别被墙钟截止截断的类输出可能随运行浮动); pattern-switch 呈现为反糖分发链。上述 javac 门控是**语法**门——语义级 诊断(缺 Android classpath、极少数寄存器密集巨兽方法中的类型混淆局部 变量)仍会存在。详见[架构文档](docs/zh-CN/architecture.md)。 ## 测试 ```bash cargo test # 56 个测试 ``` ## 许可 [MIT](LICENSE) © ejfkdev