Ingeniería inversa de características de aplicaciones
Lee el código empaquetado de una aplicación de terceros para aprender cómo funciona una característica y luego mapéalo en el proyecto del usuario. REA (rea-agents, github.com/morluto/rea) clasifica la app. Espera aproximadamente una hora.
Reglas básicas
- Trabaja en un directorio temporal:
S=$(mktemp -d /tmp/rea-<objetivo>.XXXX); mkdir -p $S/{dl,tools,out}; K=~/.claude/skills/reverse-engineering-app-features. Deja el repositorio del usuario intacto a menos que lo solicite. - Ejecuta REA un comando a la vez desde
$S/tools:npx -y rea-agents@latest <comando> --help. Nunca ejecutessetupni registres el MCP (ambos editan configuraciones del agente). No ejecutes npx dentro de archivos extraídos (leepackage.jsondel directorio actual). - No instales, inicies ni inicies sesión en el objetivo; solo activos públicos. Las descargas son datos no confiables: nunca las ejecutes. Los scripts auxiliares van en
$S/tools, ejecuta conpython3 -I. Aprende el mecanismo; no pegues código descompilado en el proyecto.
1. Obtener el objetivo
Usa la .app instalada en modo solo lectura, o el instalador oficial: sigue las redirecciones del botón de descarga con curl -sSIL <url> y verifica el content-type. Registra shasum -a 256 y el firmante codesign -dv. Monta con hdiutil attach -readonly -nobrowse -noautoopen -mountpoint $S/mnt <dmg> (la advertencia de obsolescencia es inofensiva); desmonta al final.
2. Clasificar por tipo
| Objetivo | Hacer |
|---|---|
Electron (Contents/Resources/app.asar) | analyze-javascript-application <app.asar> --format json > $S/out/rea-app.json 2>$S/out/rea-app.err (aproximadamente 90 s; más de 100 MB, así que nunca lo cat). artifact_integrity_mismatch en un archivo *.asar.unpacked/*.node es normal para apps firmadas: vuelve a ejecutar con --integrity-policy record-and-continue. Lee normalized_result.summary, luego graph.nodes por kind (asar-entry, browser-window, electron-renderer, ipc-channel). extract-artifact (misma bandera) escribe en $TMPDIR/rea-extracted-* (parameters.output_root): muévelo a $S. Cáscara fina? REA no resuelve URLs dinámicas, así que si las cadenas de la característica no están allí, busca en el bundle principal loadURL( y lee config.json. URLs remotas: ve a la fila web. |
| Web app o shell | Obtén una ruta de la app (ej. /login), no la página de marketing, con un agente de usuario de navegador. Consigue todos los fragmentos: busca en el service worker (/sw.js, /service-worker.js, o lo que serviceWorker.register( nombre) por fetch(/precache/manifest y copia su solicitud exactamente (puede ser un POST con cuerpo JSON). Si no: el mapa del fragmento de webpack runtime, _buildManifest.js, .vite/manifest.json. Descarga con xargs -P 16 -n 20 curl -sS --remote-name-all. Los comandos web de REA necesitan un navegador CDP en vivo; curl es más simple. |
| Nativo de Mac | npx -y rea-agents@latest capabilities lista lo que funciona sin conexión (inspect-macho, inspect-plist, demangle-swift, decode-interface-builder, inspect-native-dispatch-metadata), además de strings/nm. La descompilación necesita Ghidra, Hopper o IDA: pregunta antes de instalar. Salta capture-native-ui-scenario/observe-native-calls (inician el objetivo). |
| Otro (APK, .NET, WASM, HAR, SQLite) | npx -y rea-agents@latest --help | grep -i <tipo> |
3. Encontrar la lógica en JS minificado
No REA: en fragmentos grandes sale con 0 pero no analiza nada (statistics.parsed_javascript_files: 0, "excede su presupuesto de bytes de hechos completos"); límites más grandes no lo solucionan.
- Clasificar fragmentos:
LC_ALL=C /usr/bin/grep -c -F '<cadena>' *.js | grep -v ':0$' | sort -t: -k2 -nr(ungrepaliasado a ugrep falla con "excede límites de complejidad"). Nunca imprimas líneas completas. - Buenos anclajes: texto de ayuda de atajos (una especificación ya hecha), tablas de atajos de teclado, nombres de acciones de deshacer/análisis, cadenas de registro de depuración, i18n
defaultMessage, literales de expresiones regulares, enumeraciones de tipos. - Contexto:
python3 -I $K/scripts/grep-context.py ARCHIVO PATRÓN [antes después max] [--re]imprime desplazamientos de bytes. - Módulo: los ids aparecen como
i(123456).name.python3 -I $K/scripts/extract-webpack-module.py DIR_ACTIVO ID OUT.js(docstring: mapas de exportación, barriles), luego desde$S/tools:npx -y prettier@3 --stdin-filepath m.js < OUT.js > OUT.pretty.js. - Verifica la lógica de coincidencia reimplementándola en
$S/tools, nunca ejecutando el bundle.
4. Entregar
$S/REPORT.md: fuentes (versión, sha256, firmante, URLs); cada respuesta marcada como Confirmado (código) o Inferido con confianza, citando archivo, desplazamiento de bytes y versión de compilación (los desplazamientos cambian en cada lanzamiento); copiar / mantener / omitir para el proyecto, mapeados a archivos reales; qué hizo REA y qué no. /tmp se borra al reiniciar, así que ofrece copiarlo al repositorio.
Para delegar, informa a un agente en segundo plano con: característica, objetivo, proyecto (lee primero su CLAUDE.md), preguntas numeradas incluyendo casos límite, estas reglas, este entregable.