
Analizzatore di snapshot AOT Dart basato su configurazione che esporta simboli e struct compatibili con blutter per IDA, radare2 e Frida, e decompila le funzioni in Dart pulito per dart-analyze senza un Dart SDK.
Analizzatore di snapshot Dart AOT e esportatore di informazioni di debug basato su configurazione. Nessun Dart SDK, non esegue mai il target: individua lo snapshot incorporato all'interno di Mach-O / ELF / PE, esporta gli stessi simboli e struct di blutter per IDA / radare2 / Frida (con quattro correzioni deliberate laddove il riferimento da cui è stato portato era errato — vedi
src/export/mod.rs), e decompila le funzioni in Dart chedart analyzeaccetta. Copre build desktop e mobile su dispositivo reale (compressed-pointer).
Funziona su qualsiasi artefatto Dart AOT — build di release Flutter, dart compile exe, dart compile aot-snapshot (snapshot cluster di Dart 2.7+).
Autonomo e con rilevamento automatico — tutti i 26 profili SDK più 21 varianti compressed-pointer sono incorporati; la versione di Dart viene individuata tramite l'hash dello snapshot e la variante (compressed-pointers, ovvero ogni build Flutter mobile) dalla stringa delle feature dello snapshot stesso, con un fallback basato su sonda strutturale per build personalizzate/Flutter-engine. Verificato su app reali in distribuzione, non solo sulle nostre build:
dart analyze (95,9% e 91,1% strutturato).dart analyze 0 errori.material_3_demo (5 107 righe) e
animations (2 108 righe): 15 796 e 11 102 funzioni, entrambe al 92,5% strutturato, entrambe
con dart analyze 0 errori. Poiché il sorgente è noto, queste vengono verificate contro di esso:
98,8% e 100% delle classi/mixin/enum pubblici dichiarati in lib/ vengono recuperati, 95,4% e
97,4% dei suoi letterali stringa compaiono nell'output, e 18/18 e 21/23 file sorgente mappano a una
libreria recuperata. tests/app_truth.rs verifica quei rapporti (soglia 0,90) così che la catena non
possa marcire silenziosamente.Decompila in Dart valido — lift → CFG → emissione strutturata, non un dump di disassemblaggio: cicli,
if/else, break/continue, letterali dell'object-pool inline nel loro punto di caricamento, nomi di campo
recuperati come commenti di attribuzione. Su 26 artefatti (291 file, 24 253 funzioni) l'output
viene analizzato con 0 errori di dart analyze, e anche su app reali regge — Lark 3.6.1 al 95,9%
strutturato e Weibo 2.19.6 al 91,1% (19 053 funzioni, 1,53 M istruzioni), entrambi senza errori.
Il flusso di controllo irriducibile mantiene un gotoLabel esplicito e un'intestazione NOTE invece di essere
silenziosamente appiattito. Vedi Decompiler.
Veloce — tutto misurato con il binario di questa release: un sample Flutter macOS da 9 MB viene esportato in
0,26 s; --decompile impiega 1,5 s su Lark (25,6 MB Android, 25 183 funzioni), 1,2 s su
material_3_demo (14 MB macOS, 15 796 funzioni) e 1,7 s su Weibo (9 MB Android,
19 053 funzioni decompilate / 1,63 M istruzioni), con un picco di RSS di 172–263 MB. Ovvero ~89× più veloce
della v0.1.7 sullo stesso artefatto (106,8 s → 1,20 s) — grazie al non ricostruire dati invarianti per esecuzione
per ogni funzione, allo streaming degli artefatti su disco invece di bufferizzarli, e al rendering delle
505 librerie in parallelo; non grazie a un algoritmo più veloce. Il percorso parallelo è byte-identico a
quello seriale (diff -rq su 1011 file), perché i nomi dei file e "quale libreria emette ciascun
entry point" sono entrambi stabiliti da una pre-passata sequenziale prima che inizi qualsiasi rendering.
CLI bilingue — la locale cinese stampa in cinese, tutto il resto in inglese; sovrascrivibile con DAE_LANG=zh|en.
Decompilatore parallelo — le circa 505 librerie vengono renderizzate in modo concorrente (default n_threads(),
cioè numero di core limitato a 8); sovrascrivibile con DAE_DEC_THREADS=N. L'output è byte-identico a qualsiasi
impostazione, perché i nomi dei file e "quale libreria emette ciascun entry point" sono stabiliti da una pre-passata
sequenziale. Oltre 8 thread diventa più lento e usa più memoria su un Mac con 6P+12E core, quindi il
limite è il punto ottimale, non una limitazione. DART_AOT_PROF=1 stampa una ripartizione per fase — nota che le sue
percentuali possono superare il 100% perché le fasi sono tempo CPU sommato tra i thread.
Modalità progressiva — 20 sottocomandi per interrogare lo snapshot come un database (libs, classes,
functions, members, strings, findrefs, callers, callees, pp, objs, stubs, ...)
e poi decompilare esattamente una cosa (getclass / getmethod / getlib / decompile --app).
Le query rispondono in 15–30 ms su un corpus piccolo e 43–311 ms su un'app da 15 796 funzioni; un export
completo di quell'app è 0,55 s, o ~1,4 s con --decompile (~1000 file). L'output di ogni comando
è incollabile nel successivo.
Vedi Modalità progressiva.
Nessun toolchain richiesto — un singolo binario autonomo: nessun Dart SDK, nessuna installazione Flutter, e il target non viene mai eseguito, solo analizzato. Il parsing Mach-O/ELF/PE e tutti i 47 profili sono integrati.
| Modo | Comando |
|---|---|
| Homebrew (macOS) | brew install ejfkdev/tap/dae |
| cargo | cargo install dae-rs |
| Precompilato | binario da Releases — Windows/macOS/Linux × x64/arm64 |
| Sorgente | cargo build --release |
I binari precompilati per macOS sono firmati ad-hoc; se Gatekeeper blocca la prima esecuzione: xattr -dr com.apple.quarantine dae.
(Il pacchetto crates.io è dae-rs perché dae era già occupato; il repository, la libreria e il binario restano tutti dae.)