
Android DEX → Java decompiler in Rust, built for speed — full apps in seconds, queries in milliseconds. Progressive analysis, javac-verified output, every DEX version, multi-dex & XAPK/APKS/APKM containers.
English | 简体中文
ddc decompiles Android DEX bytecode back into readable Java — at
real-world app scale, queryable like a database, and javac-verified:
every one of the 909,689 files it emits across seven real-world APKs
parses cleanly.
javac with zero syntax errors; every class of
a case-variant name pair (X/Cua vs X/cua) is preserved as
its own file instead of the last one silently overwriting.(a) -> …, Cls::name, a + b).str, getName() → name, Kotlin Intrinsics parameter strings) instead of v12;
IntDef literals render as their constants out of the box
(setVisibility(8) → View.GONE; a built-in android-37 domain
table, --symbols overrides); Kotlin null-check noise is elided and
synthetic access$NNN bridges inline at their call sites.--fast (skip
the simplification, keep formatting).ddc serve exposes every query as a REST route (GET with query
params or POST with a JSON body) plus GET /openapi.json and a streamable MCP endpoint at /mcp — point an
MCP client at http://addr/mcp; ddc http is REST-only (no
/mcp); ddc mcp stdio|http runs the same commands as MCP tools
with input and output schemas. Query commands take --format auto|text|table|markdown|md|json|jsonl (auto: table on a terminal,
the stable text form when piped).DDC_LANG=zh|en forces; English fallback).jdc-core, the
machine-neutral core shared with
jcdc.macOS (Homebrew):
brew install ejfkdev/tap/ddc
Windows (Scoop) — add the bucket once, then install by name (scoop
does not resolve a bare user/repo/app form — issue #3):
scoop bucket add ejfkdev https://github.com/ejfkdev/scoop-bucket
scoop install ddc
# or install straight from the manifest URL, no bucket needed:
scoop install https://raw.githubusercontent.com/ejfkdev/scoop-bucket/main/bucket/ddc.json
cargo-binstall (any platform — fetches the prebuilt release binary instead of compiling):
cargo binstall ddc-cli
Binaries: every release
ships raw binaries (no archives) for linux-amd64, linux-arm64,
windows-amd64, windows-arm64, macos-amd64 and macos-arm64 —
non-macOS builds UPX-compressed.
From source (Rust stable):
git clone https://github.com/ejfkdev/ddc && cd ddc
cargo build --release
ddc app.apk # full decompile → app-out/
ddc app.apk -c com.example.Foo # one class to stdout
ddc app.apk -o - | less # everything to stdout
ddc info app.apk # app context (label via arsc, package,
# version, md5) + per-dex counts
ddc mainactivity app.apk # entry point: package + launcher
ddc findrefs app.apk string token # every const-string "token" site
ddc getmethod app.apk Foo.toString # one method, all overloads
ddc pkg app.apk --app -o own/ # the app's own code only
Full options and examples: ddc --help (subcommand menu grouped by
workflow). The complete reference — every option's semantics, every
subcommand's output format and behavior — lives in
docs/cli.md (中文).
Seven real-world APKs, release build, measured after a cooldown (Apple Silicon, 6P+12E). The 39-APK validation corpus (4.08M decompiled files, per-APK wall time / peak RSS / javac parse gate) is in docs/validation.md (中文).
| APK | Size | Full decompile | Peak RSS |
|---|---|---|---|
| reqable | 34 MB | 0.57s | 162 MB |
| Telegram | 62 MB | 4.50s | 786 MB |
| 139 MB | 13.6s (99,483 files — case-variant class pairs all preserved) | 944 MB | |
| 226 MB | 13.5s | 1173 MB | |
| weixin | 268 MB | 32.7s | 1401 MB |
| lark | 398 MB | 16.1s | 2226 MB |
| 374 MB | 37.1s | 2268 MB |
Query subcommands on the same APKs (cells: time / peak RSS;
strings -f <package> --with-locations, findrefs on the package
string and method onCreate, hierarchy/disasm/getclass on each
app's launcher class):