反向工程应用功能 是做什么的?
读取第三方应用的发布代码,了解某项功能如何工作,然后将其映射到用户的项目中。使用 REA(rea-agents,github.com/morluto/rea)对应用进行分类。预计耗时约一小时。
基本规则
- 在临时目录中工作:
S=$(mktemp -d /tmp/rea-<目标>.XXXX); mkdir -p $S/{dl,tools,out}; K=~/.claude/skills/reverse-engineering-app-features。除非用户要求,否则不要触碰用户的仓库。 - 在
$S/tools中逐个命令运行 REA:npx -y rea-agents@latest <命令> --help。永远不要setup或注册 MCP(两者都会编辑 agent 配置)。不要在解压后的文件内运行 npx(它会读取当前目录的package.json)。 - 不要安装、启动或登录到目标应用;仅使用公开资源。下载的数据不可信:永远不要执行它们。辅助脚本放在
$S/tools中,使用python3 -I运行。学习其机制;不要将反编译的代码粘贴到项目中。
1. 获取目标
使用只读方式检查已安装的 .app,或使用官方安装程序:用 curl -sSIL <url> 跟踪下载按钮的重定向,并检查 content-type。记录 shasum -a 256 和 codesign -dv 签名者。使用 hdiutil attach -readonly -nobrowse -noautoopen -mountpoint $S/mnt <dmg> 挂载(弃用警告无害);最后卸载。
2. 按类型分类
| 目标 | 操作 |
|---|---|
Electron (Contents/Resources/app.asar) | analyze-javascript-application <app.asar> --format json > $S/out/rea-app.json 2>$S/out/rea-app.err(约 90 秒;超过 100 MB,因此永远不要 cat 它)。对已签名的应用,*.asar.unpacked/*.node 文件出现 artifact_integrity_mismatch 是正常的:使用 --integrity-policy record-and-continue 重新运行。读取 normalized_result.summary,然后按 kind(asar-entry、browser-window、electron-renderer、ipc-channel)读取 graph.nodes。extract-artifact(使用相同标志)将写入 $TMPDIR/rea-extracted-*(parameters.output_root):将其移动到 $S。薄外壳? REA 无法解析动态 URL,因此如果功能字符串不在那里,在主包中搜索 loadURL( 并读取 config.json。远程 URL:转到 Web 应用行。 |
| Web 应用或外壳 | 使用浏览器用户代理获取应用路由(例如 /login),而非营销页面。获取每个块:在 Service Worker(/sw.js、/service-worker.js 或 serviceWorker.register( 指定的名称)中搜索 fetch(/precache/manifest,并精确复制其请求(可能是带有 JSON 体的 POST 请求)。否则:使用 webpack 运行时块映射、_buildManifest.js、.vite/manifest.json。使用 xargs -P 16 -n 20 curl -sS --remote-name-all 下载。REA 的 Web 命令需要实时 CDP 浏览器;使用 curl 更简单。 |
| 原生 Mac 应用 | npx -y rea-agents@latest capabilities 列出可离线工作的功能(inspect-macho、inspect-plist、demangle-swift、decode-interface-builder、inspect-native-dispatch-metadata),以及 strings/nm。反编译需要 Ghidra、Hopper 或 IDA:安装前需要询问。跳过 capture-native-ui-scenario/observe-native-calls(它们会启动目标应用)。 |
| 其他(APK、.NET、WASM、HAR、SQLite) | `npx -y rea-agents@latest --help |
3. 在压缩的 JavaScript 中查找逻辑
非 REA:在大块上,它退出码为 0 但解析不到任何内容(statistics.parsed_javascript_files: 0,“超过其完整事实字节预算”);增大限制也无法解决。
- 对块进行排序:
LC_ALL=C /usr/bin/grep -c -F '<字符串>' *.js | grep -v ':0$' | sort -t: -k2 -nr(如果grep别名被设置为 ugrep,则会失败,提示“超过复杂度限制”)。永远不要打印整行。 - 好的锚点: 快捷键帮助文本(现成的规范)、键绑定表、撤销/分析操作名称、调试日志字符串、国际化
defaultMessage、正则表达式字面量、类型枚举。 - 上下文:
python3 -I $K/scripts/grep-context.py 文件 模式 [前后行数 最大] [--re]打印字节偏移量。 - 模块: ID 显示为
i(123456).name。python3 -I $K/scripts/extract-webpack-module.py 资源目录 ID OUT.js(文档字符串:导出映射、桶),然后从$S/tools中:npx -y prettier@3 --stdin-filepath m.js < OUT.js > OUT.pretty.js。 - 检查匹配逻辑 通过在
$S/tools中重新实现,而不是运行该包。
4. 交付
$S/REPORT.md:来源(版本、sha256、签名者、URL);每个答案标记为已确认(代码) 或推断并附置信度,引用文件、字节偏移量和构建版本(偏移量每次发布都会变化);复制/保留/跳过到项目中的映射到实际文件;REA 做了什么和没做什么。/tmp 在重启时被清除,因此提供将其复制到仓库的选项。
如需委派,向后台 agent 简要说明:功能、目标、项目(先阅读其 CLAUDE.md)、带有边界的编号问题、这些规则、本交付物。