O que leanrea: caminho rápido faz?
Você já conhece essas ferramentas. Este arquivo lista apenas o comando mais rápido para cada alvo e as armadilhas.
Regras
- Trabalhe em uma cópia (
cp -cno APFS é instantâneo). Coloque cada extração em um novo diretório em$TMPDIR/re/<nome>. Reutilize uma extração se existir. - Roteie por
file -b Te pelos bytes mágicos primeiro. Execute o inventário mais barato em seguida. Só então descompile ou leia o código. rgignora arquivos ocultos e ignorados, e bundlers escondem código (Electron:.webpack/,.vite/). Sempre pesquise em árvores extraídas comrg -uu.- Nunca
catum arquivo grande ou minificado. Fatias:rg -o '.{0,200}AGULHA.{0,200}' F | head. Despeje uma desmontagem uma vez em um arquivo e depois use grep nesse arquivo. - Agrupe sondas independentes em UMA chamada de shell com
;e marcadoresecho '--- nome'(entre aspas: o zsh expande um==xpuro). Limite cada saída comheadou-m. - Responda com base em evidências. Na resposta, marque cada afirmação como visto (cite arquivo:deslocamento, ou um símbolo/string) ou inferido. Um fato que você não encontrou é desconhecido, não "ausente". Leitura estática não é execução observada.
- Uma ferramenta ausente não é um bloqueador. Use a alternativa na mesma linha, ou
brew install <x>se o usuário permitir. - Turnos custam mais que bytes. Mire em 2–4 chamadas de ferramenta: uma chamada de reconhecimento agrupada, uma ou duas fatias direcionadas, depois responda. Pare quando todos os itens solicitados tiverem evidências. Não reverifique o que já viu.
Primeiro movimento: uma chamada para cada, cole e execute
Nativo (Mach-O):
T=./bin; D=$TMPDIR/re/$(basename $T); mkdir -p $D; file $T; lipo -info $T; otool -L $T; echo '--- EXPORTS'; nm -gU $T | head -150; echo '--- IMPORTS'; nm -u $T | rg -v '^__Z|napi_' | tr '\n' ' '; echo; echo '--- STRINGS'; strings -a -n 6 $T | rg -v '^[_$.]' | head -400; otool -tV $T > $D/dis.txt; echo '--- FUNCS'; rg '^[_a-zA-Z].*:$' $D/dis.txt | rg -v '^_?_?Z?N?St3' | head -150
Depois leia uma função: awk '/^ROTULO_FUNC:$/{p=1;next} p&&/^[_a-zA-Z].*:$/{exit} p' $D/dis.txt | rg 'bl|b\.|cmp|literal|mov\s+w2'.
Electron:
A=./app.asar; X=$TMPDIR/re/asar; rm -rf $X; npx -y @electron/asar extract $A $X && jq '{name,version,main}' $X/package.json; find $X -path '*/node_modules' -prune -o -type f \( -name '*.js' -o -name '*.node' \) -print | head -60; ls ${A}.unpacked/node_modules 2>/dev/null; rg -uu -l --glob '!node_modules' 'exposeInMainWorld' $X
Depois fatie a agulha no bundle: rg -uu -o --glob '!node_modules' '.{0,250}AGULHA.{0,250}' $X | head -20.
Go: go version -m T sozinho geralmente responde à pergunta.
Roteador
| Alvo (detectar) | Caminho mais rápido |
|---|---|
Electron app (*.app/Contents/Resources/app.asar) | npx -y @electron/asar extract app.asar X (veja também app.asar.unpacked/ para addons .node). Ponto de entrada: jq .main X/package.json. Superfície: `rg -n -o '.{0,120}(ipcMain.(handle |
| Bundle web / JS minificado | Encontre sourceMappingURL. Se o mapa tiver sourcesContent, despeje as fontes: jq -r '.sources[]'. Para webpack, use grep nos ids dos módulos e depois fatie em volta do resultado. Para pretty-print: npx -y prettier --parser babel F > F.pretty.js, depois leia com intervalos de linha. |
| Hermes / bytenode / V8 snapshot | A mágica do Hermes é c6 1f bc 03 (index.android.bundle): use hermes-dec / hbc-decompiler. .jsc (bytenode) não pode ser descompilado: use strings e hooks em tempo de execução. |
Mach-O (file: Mach-O) | lipo -info (primeiro thin: lipo -thin arm64 -o T1 T). Depois: otool -L (libs); xcrun dyld_info -exports -imports; nm -gU (exports) / nm -u (imports = o mapa de capacidades); strings -a -n 6; `otool -l |
| Lógica de código nativo | otool -tV T > $D/dis.txt (ou llvm-objdump -d --no-show-raw-insn -C). Encontre a função: rg -n '^_?.*Nome.*:$'. Leia o rastro de chamadas/strings: `awk '/^FUNC:/{p=1} p&&/^[_a-zA-Z].*:$/&&!/FUNC/{exit} p' dis.txt |
| ELF / PE | readelf -hlSW, readelf -dW (NEEDED), nm -D --defined-only, objdump -d -M intel. PE: objdump -x, pefile/wrestool para recursos. checksec: pwn checksec. |
Go (__go_buildinfo, .go.buildinfo) | go version -m T fornece a toolchain, caminho, mod, deps e flags de build em uma chamada. Sem Go: `strings -a T |
| Rust | Deps (cargo-auditable): cargo audit bin T, ou extraia .dep-v0 / __DATA,.dep-v0 e desinfle com zlib. Compilador: `strings -a T |
.NET (file: Mono/.Net) | ilspycmd -p -o X T.dll (instalar: dotnet tool install -g ilspycmd), depois rg. P/Invoke: rg DllImport X. NativeAOT/IL2CPP são nativos: use as linhas nativas. |
| Android APK | jadx -d X --show-bad-code a.apk depois rg. Recursos/manifest apenas: apktool d --no-src -o X a.apk. Olhada rápida: unzip -l a.apk. lib/*/libflutter.so significa Flutter (Dart AOT: blutter); libhermes.so significa React Native (linha Hermes). |
| Hash de snapshot Flutter | Em libapp.so, encontre a mágica f5 f5 dc dc; os 32 caracteres hexadecimais em +20 são o hash do snapshot. Mapeie para uma versão Dart. |
| WASM | wasm-objdump -x, wasm2wat, wasm-decompile (WABT). |
| SQLite | Copie o banco de dados, mais o arquivo -wal se presente. sqlite3 'file:C?mode=ro' '.schema', depois SELECT * FROM t LIMIT 20. |
| plist / nib / car | plutil -p F. Info.plist contém o bundle id, esquemas de URL e strings de privacidade. Catálogos de assets: assetutil --info Assets.car. |
| pcap / HAR | tshark -r C -q -z conv,tcp; `tshark -r C -T fields -e dns.qry.name -e tls.handshake.extensions_server_name -e http.request.full_uri |
| Firmware | binwalk -e F ou unblob -e X F. Depois roteie cada binário extraído através desta tabela. |
| Site | curl -sL URL para o HTML e srcs de script, depois busque o JS e fatie. Para comportamento em tempo de execução, use um navegador headless com um log de rede (Playwright page.on('request')) ou Chrome --remote-debugging-port. |
| App em execução / runtime | macOS: lldb -p PID, dtrace/fs_usage/log stream --predicate 'process=="X"'. Electron main: --inspect (apenas se os fusíveis RunAsNode/inspect permitirem). Android: adb logcat, frida -U -f pkg -l hook.js. |
Padrões de velocidade
- Strings e imports primeiro. Em um binário pequeno,
nm -u+strings+ a lista de exports geralmente respondem "o que ele faz" sem desmontagem. - Para descobrir quem usa uma string: obtenha seu endereço dos comentários "literal pool for" do
otool -tV, ourg -n 'literal pool for: "X'. Depois encontre o rótulo da função delimitadora acima dessa linha. - Um nome C++ em um alvo
bljá te conta o protocolo (por exemplogetpeereid,write,std::hash). Leia a sequência de chamadas, não toda instrução. - Para JS, vá da fronteira nativa/JS para dentro: encontre a chamada nativa, depois a classe chamadora, depois o registro IPC, depois o renderer/preload.
- Comparando versões: diferencie os inventários (
nm, a lista de módulos,go version -m) antes de diferenciar qualquer código. - Reconstruindo: escreva a reimplementação mínima, depois teste contra o original (mesmas entradas, mesmas saídas).
Instalar (apenas sob solicitação)
brew install jadx apktool radare2 binwalk wabt wireshark ghidra · npm i -g @electron/asar · dotnet tool install -g ilspycmd · cargo install cargo-audit.