大多数人尝试逆向工程一个二进制文件时,都是把它丢进十六进制编辑器,翻上二十分钟,然后放弃。
他们不知道该用哪个工具来加载文件,不知道哪条提示词能把逻辑抽出来,更不知道怎么把满屏的汇编变成真正能重构的东西。
这套 11 步教程,会把 Claude Opus 5.5 变成一台开源万物的机器。
关注我的 Substack,获取最新 AI alpha:
逆向工程不是为了破解,而是为了把一个东西理解透,直到你能亲手造出它。
2026 年 10 月 7 日,Replit CEO Amjad Masad 发了一句话:
https://x.com/amasad/status/2107671204639465961
帖子下面,一位叫 @morluto 的开发者甩出了实锤:一套能让 Agent 驱动 Hopper 和 Ghidra、并且走得很远的工具。
这个项目就是 REA,几天之内 GitHub star 就突破了 11 万。

https://github.com/morluto/rea
这不是吹牛。同一周,一个叫 WordCraft 的开源项目,用纯 Rust 交付了 Microsoft 和 Adobe 的净室(clean-room)重制版:

它的做法是观察 Word 和 Adobe 的行为、阅读公开的文件格式规范,全程没碰过一行源码。

本教程会带你走完从密封的二进制文件到这种级别重制版的完整路径,而负责阅读的,是 Opus 5.5。
01. 引擎 ——Agent 如何读取二进制文件
Opus 5.5 自己跑不了反汇编器。它只读文本、写文本。
用 Agent 做逆向之所以行得通,是因为在模型和二进制之间夹着一层工具:它把文件加载进真正的反汇编引擎,把结果暴露成可调用的函数,让模型去提问。

这个工具就是 REA,底层的引擎则是 Hopper、Ghidra 或 IDA。
循环很简单,而且不断重复:模型让 REA 检查目标,REA 返回发现结果以及背后的确凿证据(地址、字节、伪代码、调用点),模型再用这些结果提出下一个问题,或者编写并测试重实现代码。

一切都在你本地机器上运行。除了模型推理所需的发现结果,没有任何东西会被上传;每一个结论都会被标记为“观察”、“推断”或“未知”。
**
02. 安装 ——rea-agents 加一个反汇编器
安装过程会把 REA 的 MCP server 注册到你的 Agent,并装上配套的工作流指令。
一条命令就能搞定:写入任何内容前,它会先把所有变更展示给你看,并且备份它动过的东西。

反汇编器你自己挑:macOS 上用 Hopper 最省心,Ghidra 免费且跨平台,如果你已经有 IDA 那就继续用。
1# 1. 把 REA 注册到你的 Agent(Claude Code、Codex、Cursor、Gemini CLI……)2npx rea-agents setup # 展示计划变更,写入前先询问34# 2. 深度分析提供方。Hopper 在 macOS 上最顺滑;5# setup 可以在你批准后帮你装好。Ghidra 和 IDA 需要自备。6# 3. 安装 rea CLI,用于终端操作和脚本编写7npm install --global rea-agents8rea --help910# 4. 重启你的 Agent,然后确认工具已上线11claude12> /mcp13 rea: connected14 open_binary, binary_overview, analyze_function, decompile,15 list_procedures, search, xrefs, trace, inspect_artifact,16 analyze_javascript_application, inspect_managed_artifact ...
要求不高:Node.js 22 或更新版本,加上 npm。原生分析需要三选一引擎;静态 JavaScript 和 .NET 检查则完全不需要引擎。记得保持 REA 更新,因为新版本修 bug 很频繁。
1# 逆向工程家规(CLAUDE.MD)23## 权限4- 只分析我拥有或获得授权的目标。说明一次依据即可。5- 每个结论都要打标签:观察(亲眼所见)、推断(推导得出)或未知。6- 引用证据:地址、字节、伪代码或调用点。不接受无来源的断言。78## 工作流9- 从最小的概览开始,不要一上来全量 dump。只在有明确缺口时才展开。10- 复用已打开的会话;绝不重复跑相同的分析。11- 区分静态事实与运行时事实。绝不能用静态读取暗示执行行为。1213## 重构14- 基于行为和公开规范构建,绝不复制代码或资源。15- 维护一份义务清单:每恢复一个行为,都必须通过测试才算“完成”。
Opus 5.5 提供五档 effort(思考强度):low、medium、high、xhigh 和 max。用法如下:
- Medium 用来检查和浏览
- High 用来标注普通函数
- Max 留给混淆代码和指针运算密集的地方。
在整个教程里,effort 是对质量影响最大的单一旋钮。
03. 路由器 ——20 种目标类型,每种一个工具
新手最常犯的错误,就是目标明明是个 Electron 应用、JavaScript 就摆在那儿,却偏要掏出反汇编器。
REA 会把目标路由给合适的工具,你的第一条提示词也该这么做。报出文件名,报出功能名,让 Agent 自己选入口工具。

1我想弄明白 [APP] 里的 [FEATURE] 是怎么工作的,它位于 [绝对路径]。23首先,告诉我这是什么类型的目标(native、Electron/JS、.NET、Go、APK、WASM),4并选择合适的 REA 工具打开它。先别急着做深度分析。56然后给我一段话的地图:这个应用是用什么构建的、有多大、7要找 [FEATURE] 你会先看哪里。把观察、推断和未知分开,8任何结论都要给出证据。
把 REA 指向一个 Electron 应用,几秒钟内就能拿到模块、导入和 IPC 边界,根本不用反汇编器。
把它指向原生 Mach-O 或 ELF,则会打开 Hopper 数据库,走那条更难但也更深度的原生路线。搞清楚自己处在哪条路上,能省下好几个小时。
https://x.com/_vmlops/status/2106690704244420687
04. 侦察 ——概览、字符串与调用图
先别急着看代码。第一步是让 REA 给你一张整个文件的地图。一条命令就能告诉你它跑在什么架构上、里面有多少函数、埋着哪些可读文本。
这些文本是你手里最快的线索:网址、报错信息、功能名称,能让你在读第一行代码之前就明白这个应用在干什么。
1rea.open_binary { path: "/Applications/Target.app/Contents/MacOS/Target" }2rea.binary_overview {}3 arch: arm644 functions: 1,284 identified5 segments: __TEXT __DATA __LINKEDIT6 entry: _main @ 0x1000051c078rea.search { query: "http" } # 字符串 + 代码引用9 0x10004a2c0 "https://api.target.app/v3/sync"10 0x10004a300 "Authorization: Bearer "11 0x10004a330 "offline cache miss, falling back"1213rea.xrefs { address: "0x100012ab0" } # 谁调用了它?14 147 references -> core config loader, called everywhere
REA 还会统计每个函数被调用了多少次(这个次数叫交叉引用,也就是 xrefs)。

被调用 147 次的函数是这个应用的心脏,值得你投入最大精力。只被调用两次的,是个小帮手,等它重要时再看也不迟。从列表最顶端开始,一路往下推进。
05. 反编译 ——把一个函数变成伪代码
现在挑一个最忙的函数,把它变成你能读懂的东西。反编译器会把原始机器指令重写为接近 C 的代码。
它看起来很粗糙:var_28 这种名字、缠成一团的逻辑、到处都是类型转换。但你能读懂,而对 Opus 5.5 来说,“能读懂”就够了。
可以在命令行里跑并把结果存下来,也可以在对话里直接跑。
1# 按地址反编译单个函数,输出 JSON,可管道传递或保存2rea decompile /Applications/Target.app/.../Target 0x100012ab0 \3 --provider hopper --json > fn_config_loader.json45# 或者按名称搜索函数并追踪引用6rea function /path/to/Target parseConfig --provider hopper --json7rea xrefs /path/to/Target 0x100012ab0 --provider hopper --json8rea trace /path/to/Target "sync" --provider hopper --json
1// 0x100012ab0 xrefs: 1472void sub_100012ab0(void* arg0) {3 void* var_20 = objc_msgSend(cls_NSJSONSerialization,4 sel_JSONObjectWithData_options_error, arg0, 0x0, 0x0);5 if (var_20 != 0x0) {6 void* var_28 = objc_msgSend(var_20, sel_objectForKey, @"endpoints");7 void* var_30 = objc_msgSend(var_20, sel_objectForKey, @"auth_mode");8 void* var_38 = objc_msgSend(var_20, sel_objectForKey, @"retry_count");9 objc_msgSend(g_sharedConfig, sel_setEndpoints, var_28);10 objc_msgSend(g_sharedConfig, sel_setAuthMode, var_30);11 objc_msgSend(g_sharedConfig, sel_setRetryCount,12 objc_msgSend(var_38, sel_intValue));13 }14}
REA 官方的 showcase 演示中,顺着老游戏 DX-Ball 里的一声音效,一路追到决定左右声道平衡的辅助函数,然后把半成品伪代码转成了 C。

最终结果通过了全部 3,205 个原始测试用例,并精确复现了 63 个编译字节中的每一个。

完整流程见 rea.tools/showcase。
06. 标注 ——让 Opus 给每个变量命名
那份粗糙的代码只算完成了一半。接下来把它交给 Opus 5.5,让它解释并清理干净。
它会把晦涩的变量名改成真实含义的名字,用一句话说明函数的用途,识别出它遵循的模式,甚至标出原应用遗留的 bug。
把下面这段提示词粘贴给 Claude:
1这是一个有 147 个交叉引用的函数的反编译伪代码。23针对这个函数:41. 根据使用方式,把每个变量重命名为有意义的名字。52. 用一句话说明它的用途。63. 列出它读写的数据结构。74. 指出它使用的模式(单例、工厂、状态机、观察者……)。85. 把它重写为干净、地道的 Swift(或调用约定所暗示的语言),并加上文档注释。96. 标出任何缺失的错误处理、输入校验或安全检查。1011回答前请用 xhigh effort 想清楚:在定下名字之前,先推理每个值的含义。12不确定的地方请明确标出。1314[粘贴伪代码]
反编译告诉你代码做了什么。Opus 5.5 告诉你为什么这么做,以及重构它所需的名字。
https://x.com/0x0SojalSec/status/2108389060192706674
https://x.com/0x0SojalSec/status/2108031166502896035
并不是每个目标都需要反汇编器。REA 的 Notion showcase 就在应用的 JavaScript 里找到了剪贴板功能,顺着 Electron 各层一路追到主进程,完整展示了富剪贴板的构建过程——全程零汇编。详见
07. 混淆 ——Tigress 基准测试
有些应用生来就是为了对抗你正在做的事。它们的代码被故意打乱:逻辑被重排、文本被加密、还塞进一堆假分支浪费你的时间。
这叫混淆,也是连最强模型都会吃力的地方。Elastic Security Labs 做过量化测试:让 Claude Opus 在 20 个任务上挑战 Tigress 混淆器。记住下面这些数字。

这些数字里藏着两条实战经验。
- 第一,失败尝试的成本大约是成功尝试的两倍,因为模型会在放弃前不断加大 effort,所以要给每个函数设消费上限,及时止损。
- 第二,发送前先把反编译代码里的垃圾清掉(有个叫 Caveman 的免费工具能去掉约 75%),这样模型的注意力才会花在真正的逻辑上,而不是填充物上。
你实际会遇到的五种手法,以及打开代码时它们长什么样:

1这个函数看起来被混淆了。请用 max effort 处理。231. 识别其中用到的技术(控制流平坦化、不透明谓词、4 死代码、字符串加密、函数拆分),并指出每种技术在这段代码里的具体位置。52. 解决它们:移除死分支、求值不透明谓词、解平调度分发、6 如果密钥可恢复则解密内联字符串。73. 展示清理后剩下的干净函数。84. 给你的置信度打分(1-10)。低于 6 分时,明确告诉我哪些部分不确定,9 以及需要什么相邻上下文才能确定。不要默默瞎猜。1011[粘贴混淆后的伪代码]
08. 集群 ——一个控制器带一群工人
单个对话窗口没法好好读完 500 个函数。它会忘掉看过的东西,给同一个对象起三个不同的名字,最后开始自相矛盾。
解决办法是搭个小团队:一个控制器对话负责派活,几个工人对话各领一个函数。
控制器掌握全局,再把碎片缝回整体。

你不需要为此搭建什么特殊系统,下面这两条提示词就是全部配置。
1你是一个逆向工程控制器。函数地图在 functions.json 里2(address、name、size、xref_count)。341. 按调用图邻近度对函数聚类;按 xref 数量对簇排序。52. 把每个簇分派给一个 worker。绝不要自己分析函数。63. 把已解析的结构体注入每个 worker 的任务简报,确保命名一致。74. 当 worker 返回的置信度低于 6 时,带上其相邻已解析部分的上下文,排队进行第二轮。85. 跟踪累计 token 消耗,并在每个簇完成后汇报。
1你是一个 worker。你会收到一个反编译函数和目前已解析的结构体。2严格按以下格式返回:address、purpose、confidence(1-10)、structs_used、structs_new、3clean_source、flags。复用已有结构体名称;绝不要给控制器已经给你的结构体另起新名。4一次只处理一个函数。做完就停。
https://x.com/victor_explore/status/2109466356454510612
09. 净室 ——四条守住合法性的规则
净室重制意味着你只复制应用的行为,绝不复制里面的代码。做对了,你发布的东西完全属于你;做错了,你就背上了别人的版权。

四条规则能让你待在安全区,WordCraft 团队在每次构建时都会自动检查这四项。
- 只观察,不复制。 把目标当黑盒运行,看它做什么,只截它自己的窗口。绝不读取、反汇编或粘贴它的代码。除纯功能名称外,绝不照搬文案。
- 看规范,不看源码。 文件格式来自公开标准(OOXML 是 ECMA-376 / ISO 29500,再加上公开的 RTF 和 ODF 规范),绝不来自阅读竞品的解析器或任何 GPL/LGPL 代码。
- 只用原创资源。 每个图标、字体、模板和音效,要么用代码绘制,要么是公有领域或开放许可,并在归属文件中占一行。否则 CI 检查会让构建失败。
- 把两项工作分开。 一个 Agent 负责恢复行为并撰写规范。另一个完全不同的上下文只根据规范实现,绝不回头看原始分析。这道隔离就是净室的边界。
1基于已完成的分析,为重实现撰写一份净室规范。23只描述行为。包括:每个公开接口、数据模型、每个用户可见功能对应的可测试需求、4读写的文件格式(基于观察到的行为和公开规范),以及错误处理行为。56不要包括:地址或偏移量、反编译中的变量名、汇编,7或任何从原版复制的内容。一个从未见过该二进制文件的开发者,8必须能仅凭这份文档实现出兼容版本。910输出 markdown,包含以下章节:Architecture、Data Model、Public API、File Formats、11Test Cases。
照着描述干活不只是法律护身符。它让你能为自己的语言和需求做出正确选择,而不是继承原作者几十年前拍板的决定。

WordCraft 在某些地方比 Word 更快,恰恰是因为它没有抄 Word 的内部实现。
10. 打造应用 ——十二款专业工具,一套方法
WordCraft 不是孤例。它是 ArtCraft 团队架子上十二款应用之一,每一款都是你正在付费工具的净室重制版,全部用 Rust 从零手写,并在 GitHub 上免费开源发布。
他们的口号是“Twelve apps. One craft”,而这个 craft 就是第 9 步的方法:观察原版、阅读公开规范、仅凭行为构建全新版本。

这套共用方法的回报处处相同。没有 Electron:每款应用在 macOS、Windows 和 Linux 上都是原生的,除 FilmCraft 外,其余都能通过 WebAssembly 在浏览器标签页里运行。
而且因为它们内部的每个动作都是一个具名命令,这十二款应用立刻就能被 AI Agent 驱动。
每款 Craft 应用的构建方式都一样,这套架构值得照搬。它们都分层堆叠,每一层只依赖下面那一层,从最底层的基础度量,一直到最顶层的屏幕窗口。
以下是 WordCraft 的分层:

而且每个动作只是一个具名命令,所以无论是人点击、快捷键触发,还是 AI Agent 调用,触发的都是完全相同的东西。这就是它们能被 Agent 驱动的原因。
1drive WordCraft over MCP23# 无头文档自动化4claude mcp add wordcraft -- wordcraft-cli mcp56# 或者驱动正在运行的桌面应用7wordcraft --control 7981 &8claude mcp add wordcraft-app -- wordcraft-cli mcp --connect 127.0.0.1:7981910# 工具:list_commands、execute、batch、type_text、select_text、11# inspect_document、render_page、save_document(+ 实时 screenshot/click/key)12> Open report.docx, make every heading 14pt bold, export to PDF13 ✓ select.all-headings -> 12 selected14 ✓ format.font-size 14 · format.bold15 ✓ export report.pdf (selectable text, bookmarks kept)
https://x.com/yuhasbeentaken/status/2109235513102057828
11. 验证并发布 ——证明一致性,暴露 MCP
你从来没有原版的源码,所以没法逐行对比。
你要对比的是行为:给原版和你的重制版喂同样的输入,检查它们是否产出相同的输出。
1构建一个行为测试框架,用于对比原始二进制文件和我的重制版。23生成 50 组输入:30 组正常,10 组边界(空值、最大尺寸、unicode、特殊字符),410 组错误(格式错误、字段缺失、损坏)。每组都跑一遍两者。5尽可能逐字节对比输出,否则做语义对比。报告匹配率、差异列表,6以及每项差异的严重程度(外观 / 行为 / 关键)。保存到 report.md。
这也是你能向任何人展示的最有说服力的证据(文章最开头那个 RE 片段)。

然后用 REA 和 WordCraft 的方式发布你的重制版:做成 MCP server,这样下一个人的 Agent 就能像你驱动 REA 一样驱动它。
给每个函数起个清晰的名字、写段描述,包进一个简单的命令行工具,让人一行命令就能装好。
https://x.com/0xMovez/status/2108884063515746410
而且要边做边测,别攒到最后,因为等你在上面又盖了三层才发现错误,修复成本会高得多。
六个毁掉周末的错误
- 对着 Electron 应用开反汇编器。 如果 JavaScript 就摆在那儿,直接路由到 analyze_javascript_application,彻底跳过原生路线。
- 还没读就先全量 dump。 先让 REA 给个摘要。一次性拉取整个应用,会把真正的逻辑埋在噪声里,还会让你的账单飙升。
- 按文件顺序读函数。 按交叉引用数排序。147 次 xref 的函数是架构;2 次 xref 的小帮手可以等等。
- 死磕第三阶段混淆。 基准测试显示多层混淆的解决率是 0%。设好预算,存下相邻上下文,晚点再回来。
- 让模型把代码抄进你的重制版。 这会破坏净室原则。在一个上下文里先写规范,在另一个上下文里按规范实现。
- 没有一致性报告就发布。 “我觉得它对得上”不是证据。50 个行为测试加匹配率才是。
结语:
装上 REA。读懂二进制。把它重构成你自己的。
路由目标、摸清表面、反编译热点函数、让 Opus 5.5 给一切命名、拆掉值得拆的混淆、用集群放大规模、写出干净的规范,最后通过 MCP 发布重制版。
十一步。一个模型。零行复制代码。





