flutterdec is a static Flutter AOT decompiler research tool for Android ARM64 binaries.
It takes an APK (or libapp.so) and emits readable pseudo-Dart plus optional IR/ASM artifacts.
- reverse engineers and security researchers
- Flutter internals researchers
- developers comparing stripped/unstripped engine builds
- Run with
nix run(recommended, no install):
nix run github:caverav/flutterdec -- --help
nix run github:caverav/flutterdec -- info ./sample.apk --jsonFrom this repository checkout:
nix run . -- --help- Install release binary (
v0.1.0-alpha.1):
Linux x64:
curl -fLO https://github.com/caverav/flutterdec/releases/download/v0.1.0-alpha.1/flutterdec-v0.1.0-alpha.1-Linux-X64.tar.gz
tar -xzf flutterdec-v0.1.0-alpha.1-Linux-X64.tar.gz
sudo install -m 0755 flutterdec /usr/local/bin/flutterdec
flutterdec --helpmacOS arm64:
curl -fLO https://github.com/caverav/flutterdec/releases/download/v0.1.0-alpha.1/flutterdec-v0.1.0-alpha.1-macOS-ARM64.tar.gz
tar -xzf flutterdec-v0.1.0-alpha.1-macOS-ARM64.tar.gz
sudo install -m 0755 flutterdec /usr/local/bin/flutterdec
flutterdec --helpOther platforms and future tags:
- Other options:
Install into user Cargo bin (requires Nix with flakes enabled):
nix develop -c cargo install --path crates/flutterdec-cli
~/.cargo/bin/flutterdec --helpRun from source without installing:
nix develop -c cargo run -p flutterdec-cli -- info ./sample.apk --jsonBuild local release binary:
nix develop -c cargo build -p flutterdec-cli --release
./target/release/flutterdec --help- Inspect target:
flutterdec info ./sample.apk --jsoninfo now includes detected app package candidates (app_package_counts_top) when adapter metadata is available.
- Install adapter for the detected Dart hash:
flutterdec adapter install --dart-hash <HASH>- Decompile:
flutterdec decompile ./sample.apk -o ./outBy default, decompile focuses app reversing (--function-scope app-unknown) and excludes known Flutter/Dart framework internals.
To include all functions (app + Flutter + Dart/runtime):
flutterdec decompile ./sample.apk -o ./out --function-scope allTo focus only specific Dart packages (repeatable):
flutterdec decompile ./sample.apk -o ./out \
--function-scope app-unknown \
--app-package my_appIf package names are unknown, inspect report.json at function_scope.app_package_counts_top.
When --app-package is not provided, capped prioritization also applies manifest-derived package hints (function_scope.priority_package_hints) to favor app-owned code (including normalized variants like localsend_app and localsend when applicable).
- Optional: improve call names with stripped/unstripped engine pair:
flutterdec map-symbols \
--stripped ./libflutter.stripped.so \
--unstripped ./libflutter.unstripped.so \
-o ./out/symbol-map
flutterdec decompile ./sample.apk -o ./out \
--extra-symbol-map-targets ./out/symbol-map/symbol_target_summary.json \
--extra-symbol-elf ./libflutter.unstripped.sodecompile exposes analysis-engine profiles so you can trade detail for speed.
Default profile:
balanced(recommended)
Available profiles:
balanced: full semantic naming/hints/reportinglight: lower-overhead analysis for faster large-scale runs
Example:
flutterdec decompile ./sample.apk -o ./out --analysis-profile lightAdapter backend selection:
--adapter-backend auto(default): try Blutter backend if configured, otherwise fallback to internal adapter--adapter-backend internal: force internal snapshot-string adapter--adapter-backend blutter: require Blutter backend (fail if unavailable)
Blutter backend environment knobs:
FLUTTERDEC_BLUTTER_CMD: full command to launch Blutter (for examplepython3 /path/to/blutter.py)FLUTTERDEC_BLUTTER_PY: path toblutter.py(uses current Python interpreter)
Nix integration:
nix developnow providesflutterdec-blutterand auto-exportsFLUTTERDEC_BLUTTER_CMDto that wrapper.- You can also run the wrapper directly via
nix run .#blutter-bridge -- --help.
You can explicitly enable/disable individual engine toggles:
--with-canonical-model-symbols/--no-canonical-model-symbols--with-pool-value-hints/--no-pool-value-hints--with-pool-semantic-hints/--no-pool-semantic-hints--with-semantic-reporting/--no-semantic-reporting--with-bootflow-category-seeds/--no-bootflow-category-seeds
Main outputs under -o <OUT_DIR>:
pseudocode/*.dartpseudoquality.jsonreport.jsonasm/*.s(if--emit-asm)ir/*.json(if--emit-ir)
- User guide: docs/user-guide.md
- CLI reference: docs/cli-reference.md
- Development guide: docs/development.md
- Architecture: docs/architecture.md
- Internals walkthrough: docs/how-it-works.md
- Research decisions: docs/research-decisions.md
- Contributing: CONTRIBUTING.md
- Context and project history: context.md
- Bug report: new bug issue
- Feature request: new feature issue
- Research finding: new research issue