
Analisador de snapshot AOT do Dart orientado por configuração que exporta símbolos e structs compatíveis com blutter para IDA, radare2 e Frida, e descompila funções em Dart limpo para dart-analyze sem a necessidade de um Dart SDK.
Analisador de snapshot AOT do Dart orientado por configuração e exportador de informações de depuração. Sem Dart SDK, nunca executa o alvo: localiza o snapshot embutido dentro de Mach-O / ELF / PE, exporta os mesmos símbolos e structs que o blutter para IDA / radare2 / Frida (com quatro correções deliberadas onde a referência da qual foi portado estava errada — veja
src/export/mod.rs), e descompila funções para Dart que odart analyzeaceita. Cobre builds de desktop e de dispositivos móveis reais (ponteiros comprimidos).
Funciona em qualquer artefato AOT do Dart — builds de release do Flutter, dart compile exe, dart compile aot-snapshot (snapshots de cluster do Dart 2.7+).
Autocontido e com detecção automática — todos os 26 perfis de SDK mais 21 variantes de ponteiros comprimidos estão embutidos; a versão do Dart é identificada pelo hash do snapshot e a variante (compressed-pointers, ou seja, todo build móvel do Flutter) pela própria string de features do snapshot, com um fallback de sondagem estrutural para builds personalizados/do motor Flutter. Verificado contra aplicativos reais em produção, não apenas contra nossos próprios builds:
dart analyze (95,9% e 91,1% estruturado).dart analyze 0 erros.material_3_demo (5 107 linhas) e
animations (2 108 linhas): 15 796 e 11 102 funções, ambos 92,5% estruturado, ambos
dart analyze 0 erros. Como o código-fonte é conhecido, eles são verificados contra ele:
98,8% e 100% das classes/mixins/enums públicos declarados em lib/ são recuperados, 95,4% e
97,4% de seus literais de string aparecem na saída, e 18/18 e 21/23 arquivos-fonte mapeiam para uma
biblioteca recuperada. tests/app_truth.rs verifica essas proporções (piso 0,90) para que a cadeia não
apodreça silenciosamente.Descompila para Dart válido — lift → CFG → emissão estruturada, não um dump de desmontagem: loops,
if/else, break/continue, literais do pool de objetos embutidos no local de carregamento, nomes de campos
recuperados como comentários de atribuição. Em 26 artefatos (291 arquivos, 24 253 funções) a saída
é analisada com 0 erros no dart analyze, e em aplicativos reais também se sustenta — Lark 3.6.1 a 95,9%
estruturado e Weibo 2.19.6 a 91,1% (19 053 funções, 1,53 M instruções), ambos sem erros.
Fluxo de controle irredutível mantém um gotoLabel explícito e um cabeçalho NOTE em vez de ser
silenciosamente achatado. Veja Descompilador.
Rápido — tudo medido com o binário desta versão: uma amostra Flutter de macOS de 9 MB exporta em
0,26 s; --decompile leva 1,5 s no Lark (25,6 MB Android, 25 183 funções), 1,2 s no
material_3_demo (14 MB macOS, 15 796 funções) e 1,7 s no Weibo (9 MB Android,
19 053 funções descompiladas / 1,63 M instruções), com pico de RSS de 172–263 MB. Isso é ~89× mais rápido
que a v0.1.7 no mesmo artefato (106,8 s → 1,20 s) — por não reconstruir dados invariantes à execução
por função, por transmitir artefatos para o disco em vez de armazená-los em buffer, e por renderizar as
505 bibliotecas em paralelo; não por um algoritmo mais rápido. O caminho paralelo é byte-idêntico ao
serial (diff -rq em 1011 arquivos), porque os nomes de arquivo e "qual biblioteca emite cada
ponto de entrada" são ambos definidos por uma pré-passagem sequencial antes de qualquer renderização começar.
CLI bilíngue — o locale chinês imprime chinês, todo o resto inglês; substitua com DAE_LANG=zh|en.
Descompilador paralelo — as cerca de 505 bibliotecas são renderizadas simultaneamente (padrão n_threads(),
ou seja, número de núcleos limitado a 8); substitua com DAE_DEC_THREADS=N. A saída é byte-idêntica em qualquer
configuração, porque os nomes de arquivo e "qual biblioteca emite cada ponto de entrada" são definidos por uma pré-passagem
sequencial primeiro. Acima de 8 threads fica mais lento e usa mais memória em um Mac com 6P+12E núcleos, então o
limite é o ponto ideal, não uma limitação. DART_AOT_PROF=1 imprime um detalhamento por fase — note que suas
porcentagens podem exceder 100% porque as fases são tempo de CPU somado entre threads.
Modo progressivo — 20 subcomandos para consultar o snapshot como um banco de dados (libs, classes,
functions, members, strings, findrefs, callers, callees, pp, objs, stubs, ...)
e então descompilar exatamente uma coisa (getclass / getmethod / getlib / decompile --app).
As consultas respondem em 15–30 ms em um corpus pequeno e 43–311 ms em um aplicativo de 15 796 funções; uma exportação
completa desse aplicativo leva 0,55 s, ou ~1,4 s com --decompile (~1000 arquivos). A saída de cada comando
pode ser colada no próximo.
Veja Modo progressivo.
Nenhum toolchain necessário — um único binário autocontido: sem Dart SDK, sem instalação do Flutter, e o alvo nunca é executado, apenas analisado. O parsing de Mach-O/ELF/PE e todos os 47 perfis são embutidos.
| Forma | Comando |
|---|---|
| Homebrew (macOS) | brew install ejfkdev/tap/dae |
| cargo | cargo install dae-rs |
| Pré-compilado | binário de Releases — Windows/macOS/Linux × x64/arm64 |
| Código-fonte | cargo build --release |
Binários pré-compilados para macOS são assinados ad-hoc; se o Gatekeeper bloquear a primeira execução: xattr -dr com.apple.quarantine dae.
(O pacote do crates.io é dae-rs porque dae já estava em uso; o repositório, a biblioteca e o binário permanecem dae.)