
Analizador de snapshots AOT de Dart basado en configuración que exporta símbolos y estructuras compatibles con blutter para IDA, radare2 y Frida, y descompila funciones a Dart limpio para dart-analyze sin necesidad de un SDK de Dart.
Analizador de snapshots AOT de Dart basado en configuración y exportador de información de depuración. Sin Dart SDK, nunca ejecuta el objetivo: localiza el snapshot embebido dentro de Mach-O / ELF / PE, exporta los mismos símbolos y structs que blutter para IDA / radare2 / Frida (con cuatro correcciones deliberadas donde la referencia de la que fue portado estaba equivocada — véase
src/export/mod.rs), y descompila funciones a Dart quedart analyzeacepta. Cubre compilaciones de escritorio y de dispositivos móviles reales (punteros comprimidos).
Funciona con cualquier artefacto AOT de Dart — compilaciones release de Flutter, dart compile exe, dart compile aot-snapshot (snapshots de clúster de Dart 2.7+).
Autocontenido y con autodetección — los 26 perfiles de SDK más 21 variantes de punteros comprimidos están embebidos; la versión de Dart se empareja por hash del snapshot y la variante (compressed-pointers, es decir, toda compilación móvil de Flutter) a partir de la propia cadena de características del snapshot, con un fallback de sonda estructural para compilaciones personalizadas/del motor de Flutter. Verificado contra aplicaciones reales en producción, no solo nuestras propias compilaciones:
dart analyze (95,9% y 91,1% estructurado).dart analyze 0 errores.material_3_demo (5 107 líneas) y
animations (2 108 líneas): 15 796 y 11 102 funciones, ambas 92,5% estructurado, ambas
dart analyze 0 errores. Como la fuente es conocida, se verifican contra ella:
se recuperan el 98,8% y el 100% de las clases/mixins/enums públicos declarados en lib/, el 95,4% y
el 97,4% de sus literales de cadena aparecen en la salida, y 18/18 y 21/23 archivos fuente se mapean a una
librería recuperada. tests/app_truth.rs verifica esas proporciones (mínimo 0,90) para que la cadena no
se degrade silenciosamente.Descompila a Dart válido — lift → CFG → emisión estructurada, no un volcado de desensamblado: bucles,
if/else, break/continue, literales del pool de objetos insertados en su sitio de carga, nombres de campos
recuperados como comentarios de atribución. En 26 artefactos (291 archivos, 24 253 funciones) la salida
se analiza con 0 errores de dart analyze, y en aplicaciones reales también se mantiene — Lark 3.6.1 al 95,9%
estructurado y Weibo 2.19.6 al 91,1% (19 053 funciones, 1,53 M sentencias), ambas sin errores.
El flujo de control irreducible conserva un gotoLabel explícito y una cabecera NOTE en lugar de ser
aplanado silenciosamente. Véase Descompilador.
Rápido — todo medido con el binario de esta release: una muestra de Flutter de macOS de 9 MB se exporta en
0,26 s; --decompile tarda 1,5 s en Lark (25,6 MB Android, 25 183 funciones), 1,2 s en
material_3_demo (14 MB macOS, 15 796 funciones) y 1,7 s en Weibo (9 MB Android,
19 053 funciones descompiladas / 1,63 M sentencias), con 172–263 MB de RSS máximo. Eso es ~89× más rápido
que v0.1.7 en el mismo artefacto (106,8 s → 1,20 s) — por no reconstruir datos invariantes de ejecución
por función, por transmitir los artefactos a disco en lugar de almacenarlos en búfer, y por renderizar las
505 librerías en paralelo; no por un algoritmo más rápido. La ruta paralela es byte-idéntica a
la serie (diff -rq sobre 1011 archivos), porque los nombres de archivo y "qué librería emite cada
punto de entrada" se determinan ambos mediante una pasada previa secuencial antes de que comience cualquier renderizado.
CLI bilingüe — la configuración regional china imprime en chino, todo lo demás en inglés; se sobrescribe con DAE_LANG=zh|en.
Descompilador paralelo — las ~505 librerías se renderizan de forma concurrente (por defecto n_threads(),
es decir, número de núcleos limitado a 8); se sobrescribe con DAE_DEC_THREADS=N. La salida es byte-idéntica en cualquier
configuración, porque los nombres de archivo y "qué librería emite cada punto de entrada" se determinan mediante una pasada previa
secuencial primero. Más allá de 8 hilos se vuelve más lento y usa más memoria en un Mac de 6P+12E núcleos, por lo que el
límite es el punto óptimo, no una limitación. DART_AOT_PROF=1 imprime un desglose por fase — nótese que sus
porcentajes pueden superar el 100% porque las fases son tiempo de CPU sumado entre hilos.
Modo progresivo — 20 subcomandos para consultar el snapshot como una base de datos (libs, classes,
functions, members, strings, findrefs, callers, callees, pp, objs, stubs, ...)
y luego descompilar exactamente una cosa (getclass / getmethod / getlib / decompile --app).
Las consultas responden en 15–30 ms en un corpus pequeño y 43–311 ms en una aplicación de 15 796 funciones; una exportación
completa de esa aplicación es 0,55 s, o ~1,4 s con --decompile (~1000 archivos). La salida de cada comando
se puede pegar en el siguiente.
Véase Modo progresivo.
Sin toolchain requerido — un único binario autocontenido: sin Dart SDK, sin instalación de Flutter, y el objetivo nunca se ejecuta, solo se analiza. El análisis de Mach-O/ELF/PE y los 47 perfiles están integrados.
| Vía | Comando |
|---|---|
| Homebrew (macOS) | brew install ejfkdev/tap/dae |
| cargo | cargo install dae-rs |
| Precompilado | binario de Releases — Windows/macOS/Linux × x64/arm64 |
| Código fuente | cargo build --release |
Los binarios precompilados de macOS están firmados ad-hoc; si Gatekeeper bloquea la primera ejecución: xattr -dr com.apple.quarantine dae.
(El paquete de crates.io es dae-rs porque dae estaba ocupado; el repositorio, la librería y el binario siguen siendo dae.)