leanrea: ruta rápida
Ya conoces estas herramientas. Este archivo solo enumera el comando más rápido para cada objetivo y las trampas.
Reglas
- Trabaja sobre una copia (
cp -cen APFS es instantáneo). Coloca cada extracción en un nuevo directorio bajo$TMPDIR/re/<nombre>. Reutiliza una extracción si existe. - Enruta primero por
file -b Ty los bytes mágicos. Ejecuta el inventario más barato a continuación. Solo entonces descompila o lee código. rgomite archivos ocultos e ignorados, y los empaquetadores ocultan el código (Electron:.webpack/,.vite/). Siempre busca en árboles extraídos conrg -uu.- Nunca hagas
catde un archivo grande o minificado. Córtalo:rg -o '.{0,200}AGUJA.{0,200}' F | head. Volca un desensamblado una vez a un archivo y luego grepéalo. - Agrupa sondeos independientes en UNA llamada de shell con
;y marcadoresecho '--- nombre'(entrecomillado: zsh expande un==xdesnudo). Limita cada salida conheado-m. - Responde basándote en evidencia. En la respuesta, marca cada afirmación como visto (cita archivo:offset, o un símbolo/cadena) o inferido. Un hecho que no encontraste es desconocido, no "ausente". La lectura estática no es ejecución observada.
- Una herramienta faltante no es un bloqueo. Usa la alternativa en la misma fila, o
brew install <x>si el usuario lo permite. - Las vueltas cuestan más que los bytes. Apunta a 2–4 llamadas de herramienta: una llamada de reconocimiento por lotes, uno o dos cortes dirigidos, luego responde. Detente cuando cada elemento que se te pidió tenga evidencia. No vuelvas a verificar lo que ya viste.
Primer movimiento: una llamada cada uno, pega y ejecuta
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
Luego lee una función: awk '/^FUNC_LABEL:$/{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
Luego corta la aguja a través del bundle: rg -uu -o --glob '!node_modules' '.{0,250}AGUJA.{0,250}' $X | head -20.
Go: go version -m T solo suele responder la pregunta.
Enrutador
| Objetivo (detección) | Ruta más rápida |
|---|---|
Aplicación Electron (*.app/Contents/Resources/app.asar) | npx -y @electron/asar extract app.asar X (también ver app.asar.unpacked/ para addons .node). Punto de entrada: jq .main X/package.json. Superficie: `rg -n -o '.{0,120}(ipcMain.(handle |
| Web bundle / JS minificado | Encuentra sourceMappingURL. Si el mapa tiene sourcesContent, extrae las fuentes: jq -r '.sources[]'. Para webpack, grep de los ids de módulo, luego corta alrededor del acierto. Para pretty-print: npx -y prettier --parser babel F > F.pretty.js, luego lee con rangos de línea. |
| Hermes / bytenode / V8 snapshot | Hermes magic es c6 1f bc 03 (index.android.bundle): usa hermes-dec / hbc-decompiler. .jsc (bytenode) no puede descompilarse: usa cadenas y hooks en tiempo de ejecución. |
Mach-O (file: Mach-O) | lipo -info (primero adelgazar: lipo -thin arm64 -o T1 T). Luego: otool -L (librerías); xcrun dyld_info -exports -imports; nm -gU (exportaciones) / nm -u (importaciones = el mapa de capacidades); strings -a -n 6; `otool -l |
| Lógica de código nativo | otool -tV T > $D/dis.txt (o llvm-objdump -d --no-show-raw-insn -C). Encuentra la función: rg -n '^_?.*Nombre.*:$'. Lee el rastro de llamadas/cadenas: `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 da el toolchain, ruta, módulo, dependencias y flags de compilación en una sola llamada. Sin Go: `strings -a T |
| Rust | Dependencias (cargo-auditable): cargo audit bin T, o extrae .dep-v0 / __DATA,.dep-v0 e infla con zlib. Compilador: `strings -a T |
.NET (file: Mono/.Net) | ilspycmd -p -o X T.dll (instalar: dotnet tool install -g ilspycmd), luego rg. P/Invoke: rg DllImport X. NativeAOT/IL2CPP son nativos: usa las filas de nativo. |
| APK Android | jadx -d X --show-bad-code a.apk luego rg. Solo recursos/manifiesto: apktool d --no-src -o X a.apk. Vistazo rápido: unzip -l a.apk. lib/*/libflutter.so significa Flutter (Dart AOT: blutter); libhermes.so significa React Native (fila de Hermes). |
| Hash de snapshot de Flutter | En libapp.so, encuentra el magic f5 f5 dc dc; los 32 caracteres hex en +20 son el hash del snapshot. Mapea a una versión de Dart. |
| WASM | wasm-objdump -x, wasm2wat, wasm-decompile (WABT). |
| SQLite | Copia la base de datos, más el archivo -wal si está presente. sqlite3 'file:C?mode=ro' '.schema', luego SELECT * FROM t LIMIT 20. |
| plist / nib / car | plutil -p F. Info.plist contiene el bundle id, esquemas URL y cadenas de privacidad. 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 o unblob -e X F. Luego enruta cada binario extraído a través de esta tabla. |
| Sitio web | curl -sL URL para el HTML y las fuentes de scripts, luego obtén el JS y córtalo. Para comportamiento en tiempo de ejecución, usa un navegador sin cabeza con un registro de red (Playwright page.on('request')) o Chrome --remote-debugging-port. |
| Aplicación en ejecución / runtime | macOS: lldb -p PID, dtrace/fs_usage/log stream --predicate 'process=="X"'. Electron main: --inspect (solo si los fusibles RunAsNode/inspect lo permiten). Android: adb logcat, frida -U -f pkg -l hook.js. |
Patrones de velocidad
- Cadenas e importaciones primero. En un binario pequeño,
nm -u+strings+ la lista de exportaciones suelen responder "¿qué hace?" sin desensamblado. - Para encontrar quién usa una cadena: obtén su dirección de los comentarios "literal pool for" de
otool -tV, org -n 'literal pool for: "X'. Luego encuentra la etiqueta de la función que la envuelve arriba de esa línea. - Un nombre C++ en un objetivo
blya te dice el protocolo (por ejemplogetpeereid,write,std::hash). Lee la secuencia de llamadas, no cada instrucción. - Para JS, ve desde el límite nativo/JS hacia adentro: encuentra la llamada nativa, luego su clase llamante, luego el registro IPC, luego el renderer/preload.
- Comparar versiones: haz diff de los inventarios (
nm, la lista de módulos,go version -m) antes de hacer diff de cualquier código. - Reconstruir: escribe la reimplementación mínima, luego pruébala contra el original (mismas entradas, mismas salidas).
Instalación (solo a pedido)
brew install jadx apktool radare2 binwalk wabt wireshark ghidra · npm i -g @electron/asar · dotnet tool install -g ilspycmd · cargo install cargo-audit.