<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>逆向工程 on 我的博客</title><link>https://blog.5616760.com/tags/%E9%80%86%E5%90%91%E5%B7%A5%E7%A8%8B/</link><description>Recent content in 逆向工程 on 我的博客</description><generator>Hugo -- gohugo.io</generator><language>zh</language><lastBuildDate>Mon, 12 Oct 2026 08:30:00 +0800</lastBuildDate><atom:link href="https://blog.5616760.com/tags/%E9%80%86%E5%90%91%E5%B7%A5%E7%A8%8B/index.xml" rel="self" type="application/rss+xml"/><item><title>104k 星的 REA：一个 MCP 同时接管 Hopper、Ghidra、IDA 和浏览器</title><link>https://blog.5616760.com/0044.html</link><pubDate>Mon, 12 Oct 2026 08:30:00 +0800</pubDate><guid>https://blog.5616760.com/0044.html</guid><description>&lt;p&gt;你有没有过这样的时刻：在一个 App 里发现一个做得很漂亮的功能，想在自己的项目里复刻它，但手里只有一个安装包。&lt;/p&gt;&#10;&lt;p&gt;没有源码，没有文档，混淆过的 JS 读不懂，二进制更是只能看到一堆汇编。这时候通常有两条路：一是买个 Hopper/Ghidra 会员坐进去一格格啃，二是去 GitHub 上找有没有人已经扒出来了——十有八九没有。&lt;/p&gt;&#10;&lt;p&gt;REA 想解决的就是这两条路之间的空档。它的定位写在 README 标题下面：&lt;strong&gt;Reverse Engineer Anything&lt;/strong&gt;，一个 MCP 服务同时覆盖原生二进制、应用结构和运行时行为。&lt;/p&gt;&#10;&lt;p&gt;&lt;img alt="图：REA 在 Hopper 中启动分析桥，检查一个原生二进制程序" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://blog.5616760.com/img/0044-001.jpg"&gt;&lt;/p&gt;&#10;&lt;p&gt;它的 slogan 更直接：&lt;em&gt;See a feature you like. Understand how it works, down to the binary level.&lt;/em&gt;&lt;/p&gt;&#10;&lt;p&gt;六个月内，这个项目在 GitHub 上攒到 &lt;strong&gt;104,150 star&lt;/strong&gt;、&lt;strong&gt;22,856 fork&lt;/strong&gt;，仓库创建于 2026-04-14，MIT 协议，最新版本 v6.4.0 发布于 2026-10-11——也就是我采集数据的前一天。&lt;/p&gt;&#10;&lt;p&gt;下面把它拆开看：它到底能分析什么、架构怎么搭的、有哪些地方值得抄、有哪些地方要小心。&lt;/p&gt;&#10;&lt;h2 id="一它解决的是一个很具体的痛点"&gt;一、它解决的是一个很具体的痛点&#10;&lt;/h2&gt;&lt;p&gt;先把场景说清楚。逆向工具的现状是&lt;strong&gt;割裂&lt;/strong&gt;的：&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;想分析原生二进制，得学 Hopper 或 Ghidra 的交互逻辑，记快捷键，理解数据库概念&lt;/li&gt;&#10;&lt;li&gt;想看 Electron 应用，那又是另一套——解 ASAR、扒 preload、追 IPC&lt;/li&gt;&#10;&lt;li&gt;想看 APK，需要 JADX、Apktool、adb 一套组合&lt;/li&gt;&#10;&lt;li&gt;想看网站运行时，得自己搭 Playwright + CDP&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;每换一个目标就要换一套工具，每套工具都要重新学一遍。更麻烦的是，&lt;strong&gt;这些工具产出的结果格式各异&lt;/strong&gt;：IDA 给伪代码，Ghidra 给 CFG，浏览器给 HAR 文件。你没法把它们拼成一个完整的「这个功能是怎么实现的」的答案。&lt;/p&gt;&#10;&lt;p&gt;REA 的做法是把这层割裂收进一个 MCP 服务后面。对 agent 来说，工具调用是统一的；具体的引擎差异被藏在 provider 层里。&lt;/p&gt;&#10;&lt;p&gt;这也解释了它为什么长成现在这样：539 个 provider 相关文件对 1,177 个 &lt;code&gt;src/&lt;/code&gt; 下的非测试 TypeScript 文件——大约三分之一的代码量花在做适配，而不是做核心逻辑。&lt;/p&gt;&#10;&lt;h2 id="二上手只要一条命令"&gt;二、上手只要一条命令&#10;&lt;/h2&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;npx rea-agents setup&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;前提是 Node.js 22.x（≥22.19）、24.x（≥24.11）或 26+，外加 npm。包名叫 &lt;code&gt;rea-agents&lt;/code&gt;，版本 6.4.0。&lt;/p&gt;&#10;&lt;p&gt;setup 做的事是：列出你要接入的 agent → 展示将要做的改动 → 你批准 → 写入 MCP server 配置和配套的工作流说明 → 备份原有配置 → 重启 agent。&lt;strong&gt;改动必须经过审批&lt;/strong&gt;，这一点比很多同类工具省心。&lt;/p&gt;&#10;&lt;p&gt;它支持 &lt;strong&gt;17 个 agent&lt;/strong&gt; 的自动配置，包括 Claude Code、Claude Desktop、Codex、Cursor、Gemini CLI、Windsurf、Copilot CLI、Qwen Code、VS Code、Grok Build、OpenCode、Devin 等，以及几个相对小众的（&lt;code&gt;omp&lt;/code&gt;、&lt;code&gt;pi&lt;/code&gt;、&lt;code&gt;hermes&lt;/code&gt;）。任何支持本地 MCP server 的客户端也都能用手动注册的方式接上。&lt;/p&gt;&#10;&lt;p&gt;装完之后，交互方式就是跟 agent 说话：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Understand how search works in the Notes app, show me the evidence, and build a&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;similar feature for my project.&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;也可以完全脱离 agent，直接在终端用 CLI：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;npm install --global rea-agents&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;rea --help&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;比如分析一个解包出来的 Electron 目录或 ASAR：&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;npx -y rea-agents@latest analyze-javascript-application /absolute/path/to/app --json&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;返回的是模块、imports、Electron 边界，&lt;strong&gt;以及这些结论各自的证据&lt;/strong&gt;。更新用 &lt;code&gt;rea update&lt;/code&gt;。&lt;/p&gt;&#10;&lt;p&gt;CLI 的命令集合是：&lt;code&gt;analyze&lt;/code&gt; / &lt;code&gt;search&lt;/code&gt; / &lt;code&gt;function&lt;/code&gt; / &lt;code&gt;decompile&lt;/code&gt; / &lt;code&gt;instructions&lt;/code&gt; / &lt;code&gt;xrefs&lt;/code&gt; / &lt;code&gt;trace&lt;/code&gt; / &lt;code&gt;providers&lt;/code&gt; / &lt;code&gt;capabilities&lt;/code&gt;。最后两个用来问「这台机器上现在有哪些引擎可用、每个引擎支持什么」，比猜配置文件靠谱。&lt;/p&gt;&#10;&lt;h2 id="三能分析什么16-类目标"&gt;三、能分析什么：16 类目标&#10;&lt;/h2&gt;&lt;p&gt;README 里的支持表格是这份项目文档写得像样的一处。每一行都写清了&lt;strong&gt;返回什么&lt;/strong&gt;和&lt;strong&gt;需要什么前提&lt;/strong&gt;，这点很关键——它不承诺「扔进来就能用」，而是老实列出依赖条件。&lt;/p&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;目标&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;返回什么&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;需要什么&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;原生二进制&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;伪代码、汇编、字符串、符号、调用与引用&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Hopper / Ghidra / IDA&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;离线 ELF 布局&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;段、节、原始符号与重定位、缓解措施候选&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Linux x64 上自备 pwntools&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;WASM 制品&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;校验、节、精确的 import/export WAT 形式&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;自备 WABT 1.0.42&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;EVM 字节码&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;分派选择器、字节偏移、推断参数与可变性&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Linux x64 上的本地载体&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Linux 崩溃转储&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;每个线程的寄存器与信号、可选映射候选&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;pwntools，可选 GDB / pwndbg&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;JavaScript / Electron&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;模块、imports、source map、路由、IPC 与原生插件关系&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;只需 Node.js 和 npm&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;网站&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;页面结构、脚本、网络观测、指定截图&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Chrome 系浏览器&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;已保存的网络抓包&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;请求、响应、暴露的载荷、源码位置&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;HAR；Linux 上抓 mitmproxy 需 mitmdump&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;.NET 程序集&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;元数据、CIL 指令、声明的原生依赖、构建对比&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;无需依赖（纯静态）&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Android APK&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Manifest 声明、类、反编译方法与引用&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;完整 JDK + headless JADX&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Android 设备&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;设备、包、进程、日志、dump、截屏、文件传输&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;自备 adb&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;JEB 工程&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;引擎级工程单元、制品摘要、类型/方法伪代码&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;自行启动的 JEB 客户端&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Android 资源&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;解码后的 Manifest、字符串表、语言包、版本信息&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;自备 Apktool&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;固件&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;区域划分、提取结果、原生分析交接&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Linux 上的 Binwalk / Unblob&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;包与资源&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;文件清单、摘要、plist、Apple bundle 结构&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;无&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;进程行为&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;终端输出、交互、退出与文件系统观测、运行对比&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;Linux / macOS + 原生 PTY&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;p&gt;一个容易被忽略的设计取向：&lt;strong&gt;静态 JS 分析和 .NET 分析不需要任何原生引擎&lt;/strong&gt;。这意味着哪怕你机器上什么都没装，MCP 一注册就能干活——只是分析不了二进制而已。&lt;/p&gt;&#10;&lt;p&gt;运行时会跑起目标进程，用的是你的用户权限。项目在每个 runtime 指南里都写明了影响范围，这点比含糊其辞要好。&lt;/p&gt;&#10;&lt;h2 id="四整个流程长什么样"&gt;四、整个流程长什么样&#10;&lt;/h2&gt;&lt;pre class="mermaid" style="visibility:hidden"&gt;flowchart TD&#10; U["分析者 / Agent&lt;br/&gt;提出一个功能问题"] --&gt; MCP["MCP stdio 服务&lt;br/&gt;src/main.ts"]&#10; MCP --&gt; ROUTER["SessionProviderRouter&lt;br/&gt;每个目标一个不可变深度绑定"]&#10; ROUTER --&gt; REG["AnalysisProviderRegistry&lt;br/&gt;候选排序 · 确定性选择 · 不回退"]&#10;&#10; REG --&gt; HOP["Hopper / Ghidra / IDA&lt;br/&gt;深度原生引擎"]&#10; REG --&gt; JS["JavaScript / Electron&lt;br/&gt;模块与 AST 投影"]&#10; REG --&gt; OTHER["WASM · EVM · .NET · APK&lt;br/&gt;固件 · 网络抓包"]&#10;&#10; HOP --&gt; LEDGER["EvidenceLedger&lt;br/&gt;证据台账与未知项归属"]&#10; JS --&gt; LEDGER&#10; OTHER --&gt; LEDGER&#10;&#10; LEDGER --&gt; REC["调查记录 InvestigationRecord&lt;br/&gt;observed / derived / inferred 分离"]&#10; REC --&gt; OUT["返回结果&lt;br/&gt;结论 + 证据引用 + 局限说明"]&#10;&#10; OUT --&gt; U&#10; OUT -.-&gt;|"follow-up：再问一次"| MCP&#10;&#10; style U fill:#2d6a4f,stroke:#2d6a4f,color:#ffffff&#10; style LEDGER fill:#5a189a,stroke:#5a189a,color:#ffffff&#10; style REC fill:#5a189a,stroke:#5a189a,color:#ffffff&#10; style OUT fill:#1d3557,stroke:#1d3557,color:#ffffff&#10; style REG fill:#9d0208,stroke:#9d0208,color:#ffffff&lt;/pre&gt;&lt;p&gt;这张图里有两处值得停下来看。&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;第一，&lt;code&gt;AnalysisProviderRegistry&lt;/code&gt; 写着「确定性选择，不回退」。&lt;/strong&gt; 意思是不做「Hopper 失败就悄悄换 Ghidra 再试」这种事。选哪个引擎是确定性的，失败了就把失败和局限报给你。这在科研意义上是对的——一个静默的 fallback 会让你以为结果来自 Hopper，实际上来自 Ghidra 的启发式反编译，而两者的伪代码质量差异极大。&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;第二，&lt;code&gt;EvidenceLedger&lt;/code&gt; 和「未知项归属」是一等公民。&lt;/strong&gt; REA 不只是返回结论，而是把「没查出来的东西」也结构化地记录下来。这一点在第四节之后会展开。&lt;/p&gt;&#10;&lt;h2 id="五六种工具形态而不是一百个工具"&gt;五、六种工具形态，而不是一百个工具&#10;&lt;/h2&gt;&lt;p&gt;&lt;code&gt;docs/tool-design.md&lt;/code&gt; 里有一张表，是整个项目最值得抄的部分之一。&lt;/p&gt;&#10;&lt;p&gt;REA 没有采用「每个格式一个工具、一个动作一个工具」的堆叠策略，而是先定义&lt;strong&gt;六种任务形态&lt;/strong&gt;：&lt;/p&gt;&#10;&lt;table&gt;&#10;&#9;&lt;thead&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;形态&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;用途&lt;/th&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;th&gt;返回什么&lt;/th&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/thead&gt;&#10;&#9;&lt;tbody&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;inspect&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;关于某个目标、对象或资源的事实&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;字段、位置、以及各类切面是否可用&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;search&lt;/code&gt; / &lt;code&gt;list&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;候选发现&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;稳定排序 + 上下文，必要时分页&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;trace&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;跨证据的关系&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;带类型的边、支撑事实、未解析的路径&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;compare&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;显式配对的制品或观测&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;同一性、可比覆盖范围、有支撑的差异&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;workflow&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;需要组合的、反复出现的结论&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;内联答案 + 贡献证据 + 部分完成的切面&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&#9;&#9;&lt;tr&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;&lt;code&gt;observe&lt;/code&gt; / &lt;code&gt;capture&lt;/code&gt;&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;运行时行为&lt;/td&gt;&#10;&#9;&#9;&#9;&#9;&#9;&lt;td&gt;权限、启动/附加影响、生命周期、清理状态&lt;/td&gt;&#10;&#9;&#9;&#9;&lt;/tr&gt;&#10;&#9;&lt;/tbody&gt;&#10;&lt;/table&gt;&#10;&lt;p&gt;文档明确写道：&lt;em&gt;These are task shapes, not mandatory prefixes.&lt;/em&gt; 也就是说这是设计约束，不是命名规范。&lt;/p&gt;&#10;&lt;p&gt;我在 &lt;code&gt;docs/mcp-contracts.md&lt;/code&gt; 里看到的实际工具名也印证了这一点——它们按动作和对象命名，而不是按形态加前缀：&lt;code&gt;open_binary&lt;/code&gt;、&lt;code&gt;analyze_function&lt;/code&gt;、&lt;code&gt;compare_artifacts&lt;/code&gt;、&lt;code&gt;trace_call_path&lt;/code&gt;、&lt;code&gt;get_evidence_bundle&lt;/code&gt;、&lt;code&gt;inspect_analysis_view&lt;/code&gt;、&lt;code&gt;analyze_javascript_application&lt;/code&gt;、&lt;code&gt;capture_browser_scenario&lt;/code&gt;、&lt;code&gt;build_reconstruction_obligation_ledger&lt;/code&gt;……&lt;/p&gt;&#10;&lt;p&gt;文档里还有一条我觉得是整份 MCP 设计文档的核心主张：&lt;/p&gt;&#10;&#10; &lt;blockquote&gt;&#10; &lt;p&gt;&lt;strong&gt;Prefer primitives; compose workflows.&lt;/strong&gt;&lt;/p&gt;&#10;&#10; &lt;/blockquote&gt;&#10;&lt;p&gt;原子的工具只报告「关于某个已识别对象或关系的可复用事实」。一个格式专用的解码器算原子工具；但&lt;strong&gt;某个应用的业务解释不属于通用契约&lt;/strong&gt;。只有当重复使用证明了「存在一个 REA 能完成、且不掩盖调用方选择和不确定性的多源结论」时，才把它提升成 workflow。&lt;/p&gt;&#10;&lt;p&gt;它还举了个反面例子：自研编排语言、重放引擎、独立的 prepare/execute 两段式计划——除非观察到原语满足不了的需求，否则不要做。以及一句很实在的话：&lt;/p&gt;&#10;&#10; &lt;blockquote&gt;&#10; &lt;p&gt;&lt;strong&gt;A plan without execution does not establish runtime behavior.&lt;/strong&gt;（没有执行的计划不能确立运行时行为）&lt;/p&gt;&#10;&#10; &lt;/blockquote&gt;&#10;&lt;h2 id="六证据哲学没覆盖不等于不存在"&gt;六、证据哲学：「没覆盖」不等于「不存在」&#10;&lt;/h2&gt;&lt;p&gt;这是我认为 REA 最值钱的两个设计决定。&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;第一条：Missing coverage is unknown, not absence.&lt;/strong&gt;&lt;/p&gt;&#10;&lt;p&gt;如果某个 provider 没有报告某条关系，REA 不会说「这条关系不存在」，而是说「这一项是未知的」。文档进一步规定：对 caller/callee 读取，&lt;code&gt;relationship_coverage&lt;/code&gt; 只描述 provider 观察到的直接关系集合；标记为 &lt;code&gt;complete&lt;/code&gt; 只意味着这个集合在没有已知读取上限的情况下被完整返回了，&lt;strong&gt;不代表运行时所有可能的边都被覆盖&lt;/strong&gt;。&lt;/p&gt;&#10;&lt;p&gt;这个区分看起来是吹毛求疵，但在逆向工程里，误判「不存在」和误判「存在」的代价是同一个量级——都会把你引向错误的实现。&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;第二条：observed / derived / inferred 三态严格分离。&lt;/strong&gt;&lt;/p&gt;&#10;&lt;p&gt;一条关系是直接从二进制里读出来的（observed），还是从多个观测推导出来的（derived），还是模型推断的（inferred）——这三种在返回结果里必须能被区分开。未解析的边和部分的 provider 事实要原样保留，而不是强行要求每个 provider 都填满同一套元数据。&lt;/p&gt;&#10;&lt;p&gt;配套的产物是 &lt;code&gt;Evidence&lt;/code&gt;：每条证据带 &lt;code&gt;evidence_id&lt;/code&gt; 和 &lt;code&gt;analysis_profile&lt;/code&gt;，&lt;strong&gt;可以直接作为参数传给对比工具&lt;/strong&gt;。这就是为什么 &lt;code&gt;compare_artifacts&lt;/code&gt; 这类工具能做到「显式配对」——它配对的是有出处的证据对象，不是字符串。&lt;/p&gt;&#10;&lt;p&gt;再往上一层，还有一个我觉得很有意思的抽象：&lt;strong&gt;重构义务账本&lt;/strong&gt;（reconstruction obligation ledger）。&lt;/p&gt;&#10;&lt;p&gt;&lt;code&gt;build_reconstruction_obligation_ledger&lt;/code&gt; 把已认证的 Evidence 转换成一份确定性的重构声明清单。义务要算「闭合」，必须同时满足四个条件：&lt;/p&gt;&#10;&lt;ol&gt;&#10;&lt;li&gt;有且只有一个 owner&lt;/li&gt;&#10;&lt;li&gt;必需的 parser / schema / domain 类型都齐了&lt;/li&gt;&#10;&lt;li&gt;全部必需的 case fixture 都齐了&lt;/li&gt;&#10;&lt;li&gt;有权限可比（permission-comparable）的通过 verifier&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;p&gt;这实际上是把「我大概明白了」变成了一份可被程序检查的清单。对要真正交付一个复刻版本的场景，这个约束比什么分析报告都管用。&lt;/p&gt;&#10;&lt;h2 id="七架构十层依赖方向单向"&gt;七、架构：十层，依赖方向单向&#10;&lt;/h2&gt;&lt;p&gt;&lt;code&gt;docs/architecture.mermaid&lt;/code&gt; 是项目自带的架构图，我按原图的结构重画了一张精简版。原图有 11 个 subgraph、150+ 条连线，直接贴进来在博客里没法读：&lt;/p&gt;&#10;&lt;pre class="mermaid" style="visibility:hidden"&gt;flowchart TD&#10; EP["入口层 Entry Points&lt;br/&gt;scripts/rea.mjs 分发&lt;br/&gt;src/cli.ts 一次性 CLI&lt;br/&gt;src/main.ts MCP stdio 服务"]&#10;&#10; COMP["组装层 Composition&lt;br/&gt;src/composition&lt;br/&gt;全新类型化的 provider 与 session 工厂"]&#10;&#10; APP["应用层 Application&lt;br/&gt;src/application&lt;br/&gt;CLI 与 MCP 共享的工作流&lt;br/&gt;SessionProviderRouter · EvidenceLedger · SnapshotCache"]&#10;&#10; PROV["Provider 层&lt;br/&gt;src/native · src/evm · src/hopper&lt;br/&gt;src/ghidra · src/ida · src/browser&lt;br/&gt;src/dotnet · src/android · src/firmware · src/inspector"]&#10;&#10; PROC["进程基础层 Process Foundation&lt;br/&gt;src/process 自有进程组 · 私有根目录 · 超时&lt;br/&gt;src/windows + native/windows Node-API"]&#10;&#10; CON["契约层 Contracts&lt;br/&gt;src/contracts 面向调用方的 schema&lt;br/&gt;Zod / Ajv 校验与生成错误目录"]&#10;&#10; DOM["领域层 Domain&lt;br/&gt;src/domain&lt;br/&gt;纯函数 · 无副作用"]&#10;&#10; EP --&gt; COMP --&gt; APP --&gt; PROV&#10; PROV --&gt; PROC&#10; PROV --&gt; CON --&gt; DOM&#10; APP --&gt; DOM&#10; PROC --&gt; DOM&#10; APP --&gt;|"记录回调"| DOM&#10;&#10; style EP fill:#1d3557,stroke:#1d3557,color:#ffffff&#10; style APP fill:#5a189a,stroke:#5a189a,color:#ffffff&#10; style DOM fill:#2d6a4f,stroke:#2d6a4f,color:#ffffff&#10; style PROC fill:#9d0208,stroke:#9d0208,color:#ffffff&lt;/pre&gt;&lt;p&gt;几个能读出信息量的细节：&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;依赖方向是单向且有强制的。&lt;/strong&gt; &lt;code&gt;AGENTS.md&lt;/code&gt; 里写得很清楚：领域语义与契约 → provider 适配器 → 共享应用工作流 → CLI/MCP 适配器。领域层是纯函数、无副作用。往上加一层都得问一句「这会不会反向依赖」。&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;进程层比想象的重。&lt;/strong&gt; &lt;code&gt;src/process/&lt;/code&gt; 负责自有进程组、私有根目录、超时控制、有界文件读取、诊断与清理。Windows 上还有一层 Node-API 原生实现（&lt;code&gt;native/windows/src/&lt;/code&gt;），做 NTFS 准入、受保护 DACL 和原子的 Job Object 分配。&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;外部引擎通过 bridge 接。&lt;/strong&gt; &lt;code&gt;bridge/hopper_bridge.py&lt;/code&gt; 跑在 Hopper 内部，把操作适配到 Hopper 的 Python API；&lt;code&gt;bridge/ghidra/ReaGhidraBridge.java&lt;/code&gt; 打包成 HeadlessScript，提供 inventory、decompiler、references、CFG。&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;测试是真的多。&lt;/strong&gt; 全量 file tree 有 &lt;strong&gt;2,870 个文件&lt;/strong&gt;，其中 &lt;strong&gt;884 个是测试文件&lt;/strong&gt;（Vitest），&lt;code&gt;tests/fixtures/&lt;/code&gt; 里放了假的 launcher、bridge 和 CDP 缝。测试覆盖率体现在架构里——那些 provider 都能被替身驱动。&lt;/p&gt;&#10;&lt;p&gt;项目用 Turborepo 管理，工具链是 Rolldown + oxlint/oxfmt + release-please，发布自动化做得挺完整。&lt;/p&gt;&#10;&lt;h2 id="八把工程债摆在明面上"&gt;八、把工程债摆在明面上&#10;&lt;/h2&gt;&lt;p&gt;做大体量 MCP 服务，绕不开一个问题：&lt;strong&gt;工具 schema 和返回结果会把客户端撑爆。&lt;/strong&gt;&lt;/p&gt;&#10;&lt;p&gt;REA 的处理方式值得单独说，因为它不是「我不返回那么多」，而是「我先量，再限，而且告诉你我限了」。&lt;/p&gt;&#10;&lt;p&gt;文档里一条硬规则：&lt;/p&gt;&#10;&#10; &lt;blockquote&gt;&#10; &lt;p&gt;&lt;strong&gt;An assumed agent budget is insufficient justification for a limit.&lt;/strong&gt;&#10;（凭空假设的 agent 预算，不足以成为设置上限的理由）&lt;/p&gt;&#10;&#10; &lt;/blockquote&gt;&#10;&lt;p&gt;对应的做法是：先测量资源，再选预算，在昂贵步骤之前就强制执行。文档要求把「价值替代、trace-frame 乘积、保留记录、序列化膨胀、临时文件增长」分别单独计账——而不是笼统地给一个数字。&lt;/p&gt;&#10;&lt;p&gt;几个已经落地的工程事实：&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;10 MiB&lt;/strong&gt; 的 MCP 接收缓冲预算&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;REA_MCP_INPUT_SCHEMA_PROFILE=compact&lt;/code&gt; 把输入 schema 压到 &lt;strong&gt;13,312 字节&lt;/strong&gt;，专门为 Moonshot / kimi-cli 这类客户端准备（它们大约 13.7 KB 接受、~15 KB 拒绝）&lt;/li&gt;&#10;&lt;li&gt;返回超限时触发 &lt;code&gt;resource_constraint&lt;/code&gt;，配上 &lt;code&gt;details.reported_limits.evidence_reference&lt;/code&gt;，agent 随后可以用 &lt;code&gt;inspect_analysis_view&lt;/code&gt; 分页续读&lt;/li&gt;&#10;&lt;li&gt;实际案例：一次 &lt;strong&gt;334 MB&lt;/strong&gt; 的 Obsidian Evidence 被投影成约 &lt;strong&gt;10 KB&lt;/strong&gt; 的 summary view，需要时再分页取&lt;/li&gt;&#10;&lt;li&gt;&lt;code&gt;REA_MCP_MAX_RESPONSE_BYTES&lt;/code&gt; 可控；&lt;code&gt;REA_GHIDRA_STARTUP_TIMEOUT_MS&lt;/code&gt; / &lt;code&gt;REA_HOPPER_STARTUP_TIMEOUT_MS&lt;/code&gt; 应对大二进制的启动慢&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;「超限就明说，还能续读」这件事，比默默截断重要得多——它让 agent 的推理链不至于建立在残缺事实上。&lt;/p&gt;&#10;&lt;h2 id="九安全边界写得相当克制"&gt;九、安全边界写得相当克制&#10;&lt;/h2&gt;&lt;p&gt;逆向工具天然带着一套「会不会乱来」的疑虑。REA 在 &lt;code&gt;AGENTS.md&lt;/code&gt; 和 FAQ 里的边界写得很明确：&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;分析全在本地跑&lt;/strong&gt;，不上传目标。（但 agent 会收到工具结果，而模型提供商有自己的数据策略——这句话也写出来了）&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Ghidra&lt;/strong&gt; 用临时数据库，&lt;strong&gt;不改可执行字节，不控制 GUI&lt;/strong&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;IDA&lt;/strong&gt; 只读，&lt;strong&gt;绝不保存或关闭已经附加的 GUI 数据库&lt;/strong&gt;&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;安装器不碰&lt;/strong&gt; Homebrew、Node、npm、Java、Ghidra —— 不静默安装或升级别人的工具链&lt;/li&gt;&#10;&lt;li&gt;setup 的改动&lt;strong&gt;先展示计划再等批准&lt;/strong&gt;&lt;/li&gt;&#10;&lt;li&gt;敏感值需要脱敏，但&lt;strong&gt;不从命名去推断&lt;/strong&gt;哪个值敏感&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p&gt;这几条单独看都不稀奇，加在一起是我愿意让 agent 在自己机器上跑它的原因。&lt;/p&gt;&#10;&lt;h2 id="十三个案例看它到底能走到哪一步"&gt;十、三个案例，看它到底能走到哪一步&#10;&lt;/h2&gt;&lt;p&gt;官方 showcase 页除了 README 里的三个，还列了几个社区案例。&lt;/p&gt;&#10;&lt;p&gt;&lt;img alt="图：DX-Ball 声音声像计算、Notion 剪贴板桥、TH04 弹幕环三个案例插画" loading="lazy" sizes="(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px" src="https://blog.5616760.com/img/0044-002.png"&gt;&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;DX-Ball：复现一个声音声像计算。&lt;/strong&gt; 跟一个音效调用进到「位置转声像」的辅助函数，看指令，把不完整的伪代码翻译成 C。重构结果通过了 &lt;strong&gt;3,205 个原始 x86 用例&lt;/strong&gt;，并且&lt;strong&gt;复现出全部 63 个编译后的函数字节&lt;/strong&gt;——不是行为近似，是字节级一致。项目还开源了重构仓库（&lt;a class="link" href="https://github.com/N0zoM1z0/dx-ball" target="_blank" rel="noopener"&#10; &gt;N0zoM1z0/dx-ball&lt;/a&gt;）。&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;Notion：追 Electron 剪贴板桥。&lt;/strong&gt; 找到渲染进程的剪贴板 API，穿过 preload 和 IPC 进到主进程，检视富文本剪贴板格式。三个案例里这个最贴近日常——它演示的正是「看到一个功能，想知道它怎么做的」这个核心场景。&lt;/p&gt;&#10;&lt;p&gt;&lt;strong&gt;TH04：复原 DOS 版弹幕环。&lt;/strong&gt; 查看 PC-98 原版游戏的 16 位指令，恢复固定角度与瞄准角度的计算，再把重构的 C++ 和历史编译器的输出做对比。&lt;/p&gt;&#10;&lt;p&gt;社区案例里还有 Aegis（分析 Android 认证器 APK）和 DownUnderCTF 的 flag checker。&lt;/p&gt;&#10;&lt;p&gt;DX-Ball 那个「复现全部 63 个编译字节」是我最看重的一个指标。逆向工具的输出历来止于「大概是这样」，而这里明确把验收标准定在&lt;strong&gt;可执行的等价性&lt;/strong&gt;上——通过 3,205 个用例，还要字节一致。这正好呼应第六节那个重构义务账本：义务闭合的条件不是「我觉得懂了」，而是「有可跑的 verifier 通过了」。&lt;/p&gt;&#10;&lt;h2 id="十一几个需要提前知道的限制"&gt;十一、几个需要提前知道的限制&#10;&lt;/h2&gt;&lt;p&gt;不是所有地方都适合它，坦白说清楚：&lt;/p&gt;&#10;&lt;ul&gt;&#10;&lt;li&gt;&lt;strong&gt;原生分析的门槛仍在&lt;/strong&gt;。要 Hopper、Ghidra 或 IDA 之一。Hopper 可以由 setup 在你批准后安装，Ghidra 和 IDA 用你已有的（其中 Windows 上的 Ghidra 还标注为实验性支持）。&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;平台限制零散且真实&lt;/strong&gt;。离线 ELF 要 Linux x64 + 自备 pwntools，EVM 要 Linux x64，进程捕获要 Linux/macOS 的原生 PTY，固件要 Linux 上的 Binwalk/Unblob。跨平台能力并不均匀。&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;它更偏「理解和取证」，不是自动化批量工具&lt;/strong&gt;。文档明确反对为了「看起来像个平台」而造编排引擎、计划层。它给的是原语，agent 在上面自己组合。&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;版本迭代很凶&lt;/strong&gt;。六个月内到 v6.4.0，几乎两天一个版本，新 release 常常带大量 bug 修复。文档里还专门有一节讲「最新 npm 版本之后才进主分支的特性」——用之前建议先看 CHANGELOG 对齐版本。&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;安装器会改你的 agent 配置&lt;/strong&gt;。虽然有审批和备份，但涉及 17 种 agent 的配置格式，跨环境时值得先在干净目录试一次。&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;h2 id="最后"&gt;最后&#10;&lt;/h2&gt;&lt;p&gt;REA 最值得借鉴的地方，其实不是它接了多少引擎，而是两条方法论。&lt;/p&gt;&#10;&lt;p&gt;一条是&lt;strong&gt;证据与结论分离&lt;/strong&gt;：&lt;code&gt;observed&lt;/code&gt; / &lt;code&gt;derived&lt;/code&gt; / &lt;code&gt;inferred&lt;/code&gt; 三态不混，「没覆盖」永远不等于「不存在」。这让 agent 在不完整信息下推理时，至少知道自己在哪儿是在猜。&lt;/p&gt;&#10;&lt;p&gt;另一条是&lt;strong&gt;验收标准机器可判&lt;/strong&gt;：重构义务账本把「我懂了」翻译成「有唯一 owner、有必需类型、有全部 fixture、有通过的 verifier」。这一条把逆向从手感活变成了工程活。&lt;/p&gt;&#10;&lt;p&gt;从工程规模看，2,870 个文件、884 个测试、539 个 provider 适配文件、六个月 104k star，这个项目的执行密度不低。当然，六个月的高热度究竟是长期价值还是 novelty 效应，还需要更长的时间才能判断——但那些关于证据和验收的设计，跟热度无关。&lt;/p&gt;&#10;&lt;p&gt;如果你手头正好有一个「只有安装包」的复刻需求，REA 的快速上手路径值得先花十分钟试一次。&lt;/p&gt;&#10;&#10; &lt;blockquote&gt;&#10; &lt;p&gt;&lt;strong&gt;项目地址&lt;/strong&gt;：&lt;a class="link" href="https://github.com/morluto/rea" target="_blank" rel="noopener"&#10; &gt;github.com/morluto/rea&lt;/a&gt;&#10;&lt;strong&gt;官网 / Guides / Showcase&lt;/strong&gt;：&lt;a class="link" href="https://rea.tools/" target="_blank" rel="noopener"&#10; &gt;rea.tools&lt;/a&gt; · &lt;a class="link" href="https://rea.tools/showcase/" target="_blank" rel="noopener"&#10; &gt;案例集&lt;/a&gt;&#10;&lt;strong&gt;MCP 工具契约文档&lt;/strong&gt;：&lt;a class="link" href="https://github.com/morluto/rea/blob/main/docs/mcp-contracts.md" target="_blank" rel="noopener"&#10; &gt;docs/mcp-contracts.md&lt;/a&gt;&#10;&lt;strong&gt;重构案例仓库&lt;/strong&gt;：&lt;a class="link" href="https://github.com/N0zoM1z0/dx-ball" target="_blank" rel="noopener"&#10; &gt;dx-ball&lt;/a&gt; · &lt;a class="link" href="https://github.com/N0zoM1z0/th04" target="_blank" rel="noopener"&#10; &gt;th04&lt;/a&gt;&lt;/p&gt;&#10;&lt;p&gt;本文数据采集于 2026 年 10 月 12 日，对应项目 v6.4.0 版本（发布于 10 月 11 日）。star / fork 数、文件统计与版本信息均为该时点快照；该项目迭代很快，实际使用前请以仓库 CHANGELOG 与 &lt;code&gt;docs/installation.md&lt;/code&gt; 的平台要求为准。逆向分析请仅用于你有权分析的目标，并遵守所在地区的法律与软件许可条款。&lt;/p&gt;&#10;&#10; &lt;/blockquote&gt;&#10;</description></item></channel></rss>