
Konfigurationsgesteuerter Dart-AOT-Snapshot-Analysator, der blutter-kompatible Symbole und Structs für IDA, radare2 und Frida exportiert und Funktionen in dart-analyze-clean Dart ohne Dart SDK dekompiliert.
Konfigurationsgesteuerter Dart-AOT-Snapshot-Analysator und Debug-Info-Exporter. Kein Dart SDK, führt das Ziel niemals aus: lokalisiert den eingebetteten Snapshot innerhalb von Mach-O / ELF / PE, exportiert dieselben Symbole und Structs wie blutter für IDA / radare2 / Frida (mit vier bewussten Korrekturen, wo die Referenz, von der portiert wurde, falsch lag — siehe
src/export/mod.rs), und dekompiliert Funktionen zu Dart, dasdart analyzeakzeptiert. Deckt Desktop- und echte Mobile-Geräte-Builds (Compressed-Pointer) ab.
Funktioniert mit jedem Dart-AOT-Artefakt — Flutter-Release-Builds, dart compile exe, dart compile aot-snapshot (Dart 2.7+ Cluster-Snapshots).
Eigenständig & selbsterkennend — alle 26 SDK-Profile plus 21 Compressed-Pointer-Varianten sind eingebettet; die Dart-Version wird über den Snapshot-Hash abgeglichen und die Variante (compressed-pointers, d. h. jeder mobile Flutter-Build) aus dem Features-String des Snapshots selbst, mit einem strukturellen Probe-Fallback für benutzerdefinierte/Flutter-Engine-Builds. Verifiziert gegen echte ausgelieferte Apps, nicht nur gegen unsere eigenen Builds:
dart analyze-sauberem Dart (95,9 % und 91,1 % strukturiert).dart analyze 0 Fehler.material_3_demo (5 107 Zeilen) und
animations (2 108 Zeilen): 15 796 und 11 102 Funktionen, beide 92,5 % strukturiert, beide
dart analyze 0 Fehler. Da der Quellcode bekannt ist, werden diese dagegen geprüft:
98,8 % und 100 % der in lib/ deklarierten öffentlichen Klassen/Mixins/Enums werden
wiedergewonnen, 95,4 % und 97,4 % ihrer String-Literale erscheinen in der Ausgabe, und
18/18 bzw. 21/23 Quelldateien lassen sich einer wiedergewonnenen Bibliothek zuordnen.
tests/app_truth.rs prüft diese Verhältnisse (Untergrenze 0,90), damit die Kette nicht
still verrottet.Dekompiliert zu gültigem Dart — Lift → CFG → strukturierte Ausgabe, kein Disassembly-Dump: Schleifen,
if/else, break/continue, Object-Pool-Literale an ihrer Lade-Stelle eingefügt, wiedergewonnene Feldnamen
als Attributionskommentare. Über 26 Artefakte (291 Dateien, 24 253 Funktionen) analysiert die Ausgabe
mit 0 dart analyze-Fehlern, und bei echten Apps hält es ebenfalls stand — Lark 3.6.1 bei 95,9 %
strukturiert und Weibo 2.19.6 bei 91,1 % (19 053 Funktionen, 1,53 M Statements), beide fehlerfrei.
Irreduzibler Kontrollfluss behält ein explizites gotoLabel und einen NOTE-Header, statt still
flachgeklopft zu werden. Siehe Decompiler.
Schnell — alles gemessen mit dem Binary dieses Releases: ein 9 MB macOS-Flutter-Sample exportiert in
0,26 s; --decompile dauert 1,5 s bei Lark (25,6 MB Android, 25 183 Funktionen), 1,2 s bei
material_3_demo (14 MB macOS, 15 796 Funktionen) und 1,7 s bei Weibo (9 MB Android,
19 053 dekompilierte Funktionen / 1,63 M Statements), bei 172–263 MB Spitzen-RSS. Das ist ~89× schneller
als v0.1.7 beim selben Artefakt (106,8 s → 1,20 s) — durch das Vermeiden des Neuaufbaus laufunabhängiger
Daten pro Funktion, durch das Streamen von Artefakten auf die Festplatte statt sie zu puffern, und durch das
parallele Rendern der 505 Bibliotheken; nicht durch einen schnelleren Algorithmus. Der parallele Pfad ist
byte-identisch zum seriellen (diff -rq über 1011 Dateien), weil Dateinamen und „welche Bibliothek
gibt welchen Einstiegspunkt aus" beide durch einen sequenziellen Vorlauf festgelegt werden, bevor
irgendein Rendering beginnt.
Zweisprachige CLI — chinesisches Locale gibt Chinesisch aus, alles andere Englisch; überschreibbar mit DAE_LANG=zh|en.
Paralleler Dekompiler — die rund 505 Bibliotheken werden nebenläufig gerendert (Standard n_threads(),
d. h. Kernanzahl gedeckelt auf 8); überschreibbar mit DAE_DEC_THREADS=N. Die Ausgabe ist bei jeder
Einstellung byte-identisch, weil Dateinamen und „welche Bibliothek gibt welchen Einstiegspunkt aus"
zuerst durch einen sequenziellen Vorlauf festgelegt werden. Ab 8 Threads wird es langsamer und
verbraucht mehr Speicher auf einem 6P+12E-Kern-Mac, daher ist die Deckelung der Sweet Spot, keine
Einschränkung. DART_AOT_PROF=1 gibt eine Aufschlüsselung pro Phase aus — beachte, dass die
Prozentangaben 100 % überschreiten können, weil die Phasen CPU-Zeit sind, über Threads summiert.
Progressiver Modus — 20 Unterbefehle, um den Snapshot wie eine Datenbank abzufragen (libs, classes,
functions, members, strings, findrefs, callers, callees, pp, objs, stubs, ...)
und dann genau eine Sache zu dekompilieren (getclass / getmethod / getlib / decompile --app).
Abfragen antworten in 15–30 ms bei einem kleinen Korpus und 43–311 ms bei einer App mit 15 796 Funktionen;
ein vollständiger Export dieser App dauert 0,55 s, oder ~1,4 s mit --decompile (~1000 Dateien). Die Ausgabe
jedes Befehls lässt sich in den nächsten einfügen.
Siehe Progressiver Modus.
Keine Toolchain erforderlich — ein eigenständiges Binary: kein Dart SDK, keine Flutter-Installation, und das Ziel wird niemals ausgeführt, nur geparst. Mach-O/ELF/PE-Parsing und alle 47 Profile sind eingebaut.
| Weg | Befehl |
|---|---|
| Homebrew (macOS) | brew install ejfkdev/tap/dae |
| cargo | cargo install dae-rs |
| Vorgebaut | Binary von Releases — Windows/macOS/Linux × x64/arm64 |
| Quelle | cargo build --release |
Vorgebaute macOS-Binaries sind ad-hoc signiert; falls Gatekeeper den ersten Start blockiert: xattr -dr com.apple.quarantine dae.
(Das crates.io-Paket heißt dae-rs, weil dae vergeben war; Repository, Bibliothek und Binary bleiben alle dae.)