Communitygithub.com

leanrea: caminho rápido

Faça engenharia reversa de software empacotado com ferramentas CLI locais simples, sem necessidade de MCP. Cobre bundles Electron/JS, binários nativos Mach-O/ELF/PE, Go/Rust/.NET/Flutter/WASM, APKs, SQLite, pcaps, firmware e sites. Use para explicar como um recurso funciona, extrair versões/dependências, comparar builds ou reconstruir um recurso.

O que é leanrea: caminho rápido?

O leanrea é uma skill de IA agente especializada em engenharia reversa de software, permitindo que o agente analise e extraia informações de uma ampla variedade de formatos de aplicativos empacotados e binários nativos usando apenas ferramentas CLI locais e comuns. Ela cobre desde bundles Electron e JavaScript minificado até binários Mach-O, ELF, PE, Go, Rust, .NET, Flutter, WASM, além de APKs, bancos de dados SQLite, arquivos de captura de pacotes (pcaps), firmware e sites. A principal vantagem é que o agente pode fornecer respostas baseadas em evidências sem depender de um Model Context Protocol (MCP) externo, usando ferramentas já instaladas no sistema do desenvolvedor. A skill define um fluxo de trabalho otimizado com regras claras para evitar chamadas de ferramenta excessivas, priorizando a inspeção de strings e imports antes da descompilação, e usando ferramentas como `asarc`, `otool`, `nm`, `strings`, `go version -m`, `jadx`, `wasm-decompile`, `tshark` e outras. Ela também fornece padrões de velocidade e comandos rápidos para cada tipo de alvo, permitindo que o agente atinja seus objetivos com apenas 2 a 4 chamadas de ferramenta agrupadas.

Funciona com~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/aicodeking/leanrea/tree/HEAD/leanrea

Perguntar na sua IA favorita

Abre um novo chat com esta habilidade de agente já pré-carregada.

Documentação

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 -c no 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 T e pelos bytes mágicos primeiro. Execute o inventário mais barato em seguida. Só então descompile ou leia o código.
  • rg ignora arquivos ocultos e ignorados, e bundlers escondem código (Electron: .webpack/, .vite/). Sempre pesquise em árvores extraídas com rg -uu.
  • Nunca cat um 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 marcadores echo '--- nome' (entre aspas: o zsh expande um ==x puro). Limite cada saída com head ou -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 minificadoEncontre 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 snapshotA 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 nativootool -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 / PEreadelf -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
RustDeps (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 APKjadx -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 FlutterEm 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.
WASMwasm-objdump -x, wasm2wat, wasm-decompile (WABT).
SQLiteCopie o banco de dados, mais o arquivo -wal se presente. sqlite3 'file:C?mode=ro' '.schema', depois SELECT * FROM t LIMIT 20.
plist / nib / carplutil -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 / HARtshark -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
Firmwarebinwalk -e F ou unblob -e X F. Depois roteie cada binário extraído através desta tabela.
Sitecurl -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 / runtimemacOS: 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, ou rg -n 'literal pool for: "X'. Depois encontre o rótulo da função delimitadora acima dessa linha.
  • Um nome C++ em um alvo bl já te conta o protocolo (por exemplo getpeereid, 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.

Habilidades Relacionadas