ARTICLE · 1178602
REA爆火了:没有源码,AI怎么把软件拆明白?
一块砖被打碎,声音应该从左边传来,还是从右边传来?
这听起来像个很小的问题。可在一款老游戏里,要让它重新发出当年的声音,可能得沿着一个已经没人讲解的程序,一层层往里面找。
REA公开了这样一个案例。目标是1996年的Windows游戏DX-Ball。调查者想恢复其中一段声音计算:砖块在屏幕上的位置,怎样变成左右声道的偏移。
他们拿到的是可执行程序。第一份反编译结果却几乎没把这件事说清楚:函数看起来没有输入,里面只剩一个转换数值的调用。假如到这里就让AI照着写,得到的程序可能语法正确,却根本没有恢复那个声音效果。
调查没有停在这份答案上。
工具返回的底层指令显示,这个函数确实从外面接收了一个整数。继续追上去,调用它的代码正在计算砖块的横坐标。再读程序里的常量,乘法、减法和缩放关系才逐渐对上。那段看起来空空如也的函数,原来一直藏着一条很具体的规则。

我觉得,这比“AI一键复刻软件”更有意思。
因为它让人看见,AI开始能参与一种过去很费经验的工作:拿到一个成品,找出它为什么这样运转;初次理解有缺口,还能继续追问、查证,再把结果变成能检查的实现。
最近在GitHub受到大量关注的REA,完整名字是Reverse Engineer Anything。到2026年10月13日写这篇文章时,它的仓库已经接近19万Star。

它把AI编程助手和逆向分析工具接到了一起。
于是,我们向AI提出的问题,可以从“帮我做一个这样的界面”,向里面多走一步:这个按钮按下去之后,到底发生了什么?数据经过了哪里?这个看似不起眼的效果,是用什么规则做出来的?
AI怎么往软件里面看
平时让AI模仿一个软件,它看到的往往是外面那层东西:截图、按钮、菜单,或者我们对操作过程的描述。
这些材料足够帮它做出一个相似的外观,却不一定能解释外观下面的行为。一个“导出”按钮,可以导出当前页,也可以导出全部记录;可以保留原始精度,也可以把数字四舍五入;文件名、字符编码、空字段和异常处理,又可能各有一套细节。
你把正常情况下的界面做得再像,用户一碰到自己的旧文件,还是可能发现:它不是以前那个东西了。
逆向工程研究的,就是这些藏在成品里的规则。从程序的指令、文件、依赖关系或运行行为出发,反过来理解它的实现。以前,做这件事的人需要熟悉许多工具,还得在大量零碎线索里保持方向。
REA提供了一个让AI使用这些能力的入口。它可以通过MCP连接编程助手,也能从命令行调用。MCP在这里可以理解成一套工具接口:AI提出一个具体请求,REA把请求交给合适的分析能力,再把发现和依据返回来。
分析原生程序时,底下仍然可能用到Ghidra、Hopper或IDA这样的工具。它们负责把机器指令整理成汇编、接近源代码的伪代码,以及函数之间的调用关系。AI负责根据这些结果继续追问、组织解释,或编写新的实现。
REA让这些专业工具的发现进入AI的工作过程,而不是用一个新模型代替它们。理解一个程序需要哪些工具、某次结果还缺什么,仍然会影响AI下一步能做什么。
过去,人可能先去一个窗口里找字符串,再去另一个位置看调用者,最后把几段结果拼到脑子里。现在,AI可以沿同一个问题调用不同工具,把这些线索接起来。仍然需要判断,但人不必亲自搬运每一块材料。

而且,不同软件需要不同的“看法”。
一个JavaScript或Electron应用,安装包里可能还保留着脚本,只是被打包、压缩,或者藏进ASAR这样的归档文件。分析它时,可以恢复模块和导入关系,定位页面与桌面进程之间的通信;这类静态分析不需要先装一个原生反编译引擎。
换成编译好的原生程序,原来的变量名、注释和工程组织方式可能早已消失。工具能读出指令,再推导出接近源代码的表达,但那不是把作者当年的整个工程原样找回来。一个可读的新变量名,也可能是分析者后来为了理解而起的。
浏览器页面又不同。能看见页面脚本和一次网络请求,不意味着已经看见服务器里的实现。某个AI应用的客户端如果只是把请求送到云端,拆开客户端也不会把云端模型的权重和训练方法一起拆出来。
这几种情况放在一起,才能理解REA的用途:它帮AI找到眼前这个目标里实际可观察的东西,再围绕这些东西调查。能观察到多深,仍然取决于目标本身、可用工具和你提出的问题。
老游戏里的一个小函数,比一张漂亮界面更有说服力
回到那块被打碎的砖。
DX-Ball案例最后恢复出的声音规则并不长。把横坐标乘以1.5625,减去500,再乘以一个声像缩放值,最后转成整数。缩放值为1时,横坐标0对应-500,320对应0,640对应500。

不懂代码也能读出它的意思:左边的砖、正中间的砖和右边的砖,会得到不同的左右偏移。游戏用位置决定声音应该往哪一边走。
有趣的是,最初的伪代码没有把这条关系直接交出来。调查者要看到外部输入,要追到是谁把它传进来,还得确认内存里的数值到底是什么。每补上一块依据,才有理由把下一行代码写进去。
这也解释了为什么,给AI一份反编译文本,再问“这个函数干什么”,并不总是够用。
反编译结果已经是工具对机器指令的一次解释。解释可能漏掉东西,也可能把某种操作整理得不够准确。AI如果只读这一层,就可能认真地解释一个不完整的结果。反过来,当它还能查看底层指令、调用关系和实际常量,就有机会发现:刚才那个理解不对,得继续查。
查到之后,还要验证。
根据这个重建项目公开的记录,声音函数通过了3,205组原始x86函数与新实现的行为比较:横坐标从0到640,在五种缩放值下逐一对照。项目还使用固定的VC4.0工具链编译重建函数,在处理已核对的重定位并检查相关常量后,匹配了整个函数的63个字节。
核对的是这个函数的输入、计算和返回。它还需要和游戏的声音后端接起来,才能参与完整的游戏体验。
一个函数有两种不同的检查,尤其值得留意。
行为比较问的是:给相同输入,是否得到相同输出?编译字节比较问的是:在确定的历史编译条件下,新代码能否产生对应的机器指令?两者都通过,给这段恢复出的计算增加了很强的支撑。
但如果只看到一句“测试通过”,我们仍然不知道它测了什么。只试一次屏幕中央的位置,可能完全碰不到左右偏移的错误;只看新程序能启动,也无法证明碰撞、声音和存档都和旧版一致。
这里最值得学的,是把一个大目标拆成可以检验的小问题。先恢复一段计算,再把它放回更大的系统。问题变得具体,成功和失败才有清楚的落点。
官方页面列出的10月7日项目进度,也保留了这种尺度:已经有55个维护中的C函数、45,380次与原代码的比较、33个编译字节匹配的函数,能玩的完整游戏仍在继续推进。球和挡板的物理、道具以及Windows集成,还有工作要做。

读到这个进度,我反而更愿意相信它。
它没有把一段漂亮演示包装成整个项目完成。很多软件的难度,就藏在把各部分重新接回去的过程中:单个函数对了,调用时机可能不对;参数对了,状态的初始化可能不对;正常路径对了,异常路径还可能把之前的成果推翻。
复制一段文字,怎么会经过这么多地方
如果老游戏离你的生活有点远,Notion的案例就熟悉多了。
我们在文档里复制一块内容,动作只需要一下。但桌面应用里,这件事可能从页面接口出发,经过预加载脚本的包装,再通过进程间通信送到桌面主进程,最后才交给系统剪贴板。
页面和桌面主进程不是同一个地方。页面负责展示和编辑,主进程能接触更多系统能力。中间需要一条受控制的通道,让页面提出请求,又不至于把所有系统权限直接放给它。
REA的公开案例追踪了Notion Desktop 7.6.1中的这条路径:页面暴露的clipboard接口,经包装函数调用ipcRenderer.invoke;主进程通过ipcMain.handle注册接收者,检查发送来源,再把文字和HTML写入剪贴板。连接两边的是同一个消息通道名称。

一个按钮,从页面走到系统,原来不是一条随便画出来的箭头。
案例中的初始静态结果,定位到了暴露接口和发送请求的代码,却没有自动解开所有动态包装。那条完整路径还需要继续阅读包里的包装函数,把通道名称和接收者接起来。
所以,REA能帮你找到入口、减少搜索范围;它返回的某个关系图,也不保证已经替你回答了全部问题。一个动态拼出来的通道名,和一个直接写在代码里的通道名,分析起来就是不同的难度。
我也用REA做了一个小的静态测试:自己写了一个只有五个文件的Electron受控样例,让页面通过预加载接口向主进程发出复制请求。
它识别出了窗口里明确设置的预加载文件、暴露给页面的copy方法,以及两边同名的sample:copy通道。返回记录还附上了对应文件的行列位置。看着这些结果,再回到样例代码,能够找到它具体在指哪里。
但这个样例是我自己编写的,代码清楚、通道名直接,没有真实商业软件的规模和混淆。我没有启动Electron去验证复制动作,因此这个测试说明的是静态识别能力,不能拿来宣布它已经可靠复刻了某个桌面应用。
即便只做到这一步,它也比一段没有出处的解释有用。你可以继续追问某个接口,检查特定文件,或者把尚未证明的运行行为单独拿出来测试。
而如果目标是做一个兼容的文档工具,只恢复“把HTML写入剪贴板”仍然不够。
一块内容看起来还是原来的样子,不代表它的内部结构已经保住。假如原文里有表格、嵌套列表或者特殊块,另一个编辑器需要知道如何读懂这些结构,不能只把它们变成一张漂亮的外壳。消息传过去之后的格式和状态,才是下一步要调查的内容。
这就是我觉得REA最有用的提问方式:不要一上来就说“把Notion重做一遍”,而是先问清一个你确实需要兼容的动作。复制怎样工作?哪些数据被保留?接收端如何识别?哪个环节存在版本差异?
同样是让AI做事,问题一旦这么具体,得到的结果就更容易检查,也更容易真正用上。
一个能帮你查证的AI,和一个很会解释的AI
这种工作方式还有一层不那么显眼的工程设计。
REA返回的发现,不只是几段文字。它的Evidence记录会带上分析对象的身份、工具信息、操作参数、来源位置,以及限制。有些关系是直接从文件中观察到的,有些是根据结构推出来的,二者可以分别记录。
这能解决一个非常实际的麻烦:软件换了版本,昨天的结论还适用于今天吗?
假如一个桌面程序把预加载脚本换了,接口名称没变,权限检查却改了。只留一份“这个接口很安全”的说明,后来的维护者可能看不出它说的是哪个版本。保留目标文件的指纹和证据位置,才能知道这份结论究竟依赖哪一份程序。
文件指纹可以理解成对文件内容算出的识别码。它帮助我们发现拿到的东西是否相同,却不会替我们判断软件是否可靠。文件完全相同,也可能有漏洞;证据记录完整,也可能只覆盖了一小段行为。
这两件事容易混在一起,因为它们看起来都像某种“通过认证”的标记。
REA当前源码里的完成记录,就把通过、失败、不支持、截断和未知分开列出。所有列明的项目都通过,才把那份记录标成完成。这是程序中可核对的记录规则,不是一个替所有软件担保的质量证书。
未知没有消失,只是没有被一句顺畅的回答吞掉。
在逆向工作里,这一点尤其重要。AI很容易把几条线索讲成一个完整故事,人也容易因为故事讲得通,就误以为事情已经被证明。源码里找到一个发送函数,并不能证明它在当前版本里真的被调用;看到一条权限检查,也不能证明所有入口都会经过它。
要回答运行时的问题,往往还需要实际观察:触发那个操作,看看走了哪条路径,生成了什么文件,失败时留下什么状态。能检查代码、能观察运行、能验证新实现,是彼此连接但不能互相冒充的三份工作。
REA的另一款老游戏案例TH04,也把这个差别做得很直观。游戏把一整圈角度表示为256个单位;16颗子弹组成一个圆环时,各颗子弹的方向等距展开,再叠加朝向玩家的角度,就让整圈攻击一起转过去。

画面里的弹幕看着复杂,里面可以藏着一条很简洁的规则。可恢复规则之后,还得继续确认坐标、整数运算和其他发射模式,才能把它放回游戏。懂得一个环为什么转,并不等于已经重建了整部作品。
这也改变了我们评价AI的角度。以前,一段流畅解释容易让人觉得它懂了;现在,值得追下去的是,它能否把解释接到一个位置、一个输入和一个可以重复的检查上。
如果真要用,它最先帮上忙的可能是旧系统
设想一家企业要迁移一个自己有权分析的旧系统。系统还在运行,原来的开发团队已经散了,文档不完整。一份导出文件里的某些字段到底怎么算,大家只知道“以前一直这样用”。
这时,最困难的部分未必是用新语言写代码。难的是把已经运行多年的业务习惯找出来,尤其是那些文档没有写、用户却依赖的细节。
REA这类工具,可以帮助调查者从现有成品里定位文件格式、字段处理或某个功能的调用路径,再把关键行为整理成测试。迁移团队不必凭着几次手工操作猜一个近似版本,至少能围绕一个明确问题找到更多依据。
不过,这类迁移仍然需要业务人员。
某个程序为什么把空日期写成特殊值,可能是历史上另一个系统只能这样接收。工具能找到处理过程,业务人员才知道这个约定现在是否还需要保留。把所有历史行为照搬过去,可能把旧问题也搬进去;随手改掉一个看似古怪的细节,又可能让依赖它的部门突然无法工作。
逆向调查让选择更有根据,却不会替我们决定哪些历史值得留下。
软件保存也有类似的意义。一款老游戏不只是几个数学函数,它的资源、显示方式、输入响应和声音时序,一起构成了当年的体验。能读懂其中的规则,会让保存和研究多一条路,但重新拼成可维护的作品,仍然是一项需要耐心的工程。
对于做安全审计的人,分析链路则可能帮助他们定位不恰当的权限暴露和数据处理。这里需要的是明确授权和可核对的发现,而不是让AI拿着一份猜测去攻击任何看得见的服务。
这三类工作有一个共同点:原来的成品已经在那里,里面确实藏着值得理解的东西。AI不是从空白页面自由发挥,它得不断回到那个成品,接受它的约束。
这和一般的代码生成相比,是一种挺有力量的变化。任务开始有了一个可以反驳AI的对象。你说这个函数这样工作,我可以拿原程序来对照;你说新版本已经兼容,我可以拿旧文件来检验。
当“做一个差不多的”变容易,差在哪里反而更贵了
当然,人们对REA的兴奋,不会只停在迁移旧系统上。
看见一个喜欢的功能,希望自己的产品里也有;看到一个复杂交互,想弄懂它怎样实现。这些想法很自然。AI能减少调查和实现的手工劳动,某些原本不值得投入的小功能,可能因此有机会被做出来。
但拆开软件,不会把它所有价值都拆出来。
一个在线产品的客户端,可能只是整个服务的一部分。背后的数据、运营、服务器状态和团队积累,并不都在你手里的安装包中。读出了界面逻辑,距离接住真实用户的账号、历史数据和协作关系,还很远。
就算是完全本地的软件,也一样存在这些距离。原来那个编辑器在大文件上怎么表现,用户升级之后旧文档能不能打开,某台机器上的字体为什么导致错位,这些问题都需要在真实条件下继续验证。
从商业上看,我更愿意把这种变化理解成:一部分实现方法会更容易被研究,产品之间的竞争会更快碰到那些不容易用一次演示交付的东西。
你做出的功能,用户愿不愿意用?出了问题,能不能修?积累了几年的文件,敢不敢交给它?一个团队长期协作的习惯,换过去之后会不会被打断?这些问题并不会因为某个界面可以迅速生成,就变得廉价。
反过来,已有厂商也不能只依赖“别人看不懂我怎么做”来维持优势。某个细节若能被更容易地理解,竞争者就更有机会做出自己的替代方案。真正需要持续投入的,会是那些让用户每天用着省心、离开时又确实舍不得的体验。
写出一段代码、理解一个功能、把一项产品长期做好,各有不同的成本。功能能更快做出来,后两件事仍然决定着用户最后愿意把工作交给谁。
REA降低其中一部分成本的潜力,值得认真看。但到目前为止,几个公开案例和接近19万颗Star,都不能替所有目标软件给出省时比例,也不能直接证明一个商业模式会被替代。
真要安排一个项目,我会把最初的目标缩小到一项能验收的行为:例如在授权范围内兼容一个导出格式。拿到正确版本,选好适用的分析工具,确认原软件对典型输入和边界输入的处理,再让AI编写新实现,逐项对照。
这样的项目不一定显得惊天动地,却比较有机会在结束时说清楚:我们恢复了什么,还有什么没有恢复。
最后那段路,仍然需要人把它走稳
实际使用还有两件事,值得在动手前认真想一想。
第一件是资源。原生分析需要对应引擎和合适的运行环境,有的工具需要商业许可;大型应用的分析结果也可能非常大。项目的CLI文档就举过一个例子:一份Obsidian应用Evidence文件达到334MB,而针对它生成的摘要视图大约10KB。

这两个数字说的是资料体积,不是模型费用下降了多少。但它们提醒我们,给AI很多工具之后,还需要决定让它看什么。把所有结果一股脑塞进对话,可能更慢、更贵,也更难保持方向。保留完整资料,按当前问题取摘要或具体模块,通常比反复重读整座仓库更有条理。
第二件是信任。
REA在本地分析目标,不代表所有东西都永远留在本地。AI助手收到工具结果之后,相关片段仍可能进入它所使用模型的上下文,具体如何处理,要看助手和模型服务的数据政策。分析公司的软件和客户数据时,需要在这一步就想清楚什么能发送、什么不能。
本地运行也不等于安全隔离。项目的安全文档明确提醒,它不是一个沙箱。打开未知二进制,会把解析工作交给本地分析工具;某些运行时调查还会启动程序、连接调试接口或进行交互。这些动作需要合适的环境,不能把不可信程序当成普通文本随便打开。
授权同样不能省略。REA自己的代码使用MIT许可,不代表被分析的软件、素材和其他商业工具也一起变成了自由使用的东西。项目把合法研究、互操作和软件保存列为用途,也明确反对未授权绕过保护和复制受保护代码、素材。能拿到一个文件,和有权把它的内容做成商品,是两回事。
这些并不会让REA失去吸引力。恰恰是弄清这些条件之后,我们才知道它应该被放在哪里。
我最后还是想回到DX-Ball那块砖。
让它从左边发出声音,或者从右边发出声音,看起来远没有“一键复刻大软件”壮观。但当一段失去原始解释的程序,能被重新找到输入、读懂计算,再拿原来的指令验证,新工具就已经触到了一个很有价值的地方。
我们保存的不只是一个运行文件,也在尝试保存里面那些曾经被人认真设计过的行为。
REA让我感兴趣的,是AI多了一种靠近这些行为的方法:带着问题进去,找到依据,遇到解释不通的地方再往下查。接下来,它能让多少原本无人敢动的旧系统重新被理解,能让多少小团队在明确授权下做好兼容和维护,比“任何软件都能一键复制”的口号,更值得持续看下去。
/ / / /
人工智能前沿动态,商业科技一手信息
👇真诚推荐关注👇















































































