Hacker News 中文摘要

RSS订阅

84天反编译一款Nintendo 64游戏 -- Decompiling a Nintendo 64 game in 84 days

作者宣布成功完成了N64游戏《Snowboard Kids》的完全反编译,所有函数均实现了与原版机器码一致的C语言代码。项目由多位贡献者合作完成,旨在帮助速通玩家和模组社区深入理解游戏机制。

正文

很高兴宣布,《滑雪小子》初代现已实现100%反编译!这意味着游戏中的所有函数都已拥有对应的C语言实现,编译后能生成与原版完全一致的机器码。

这一成果绝非一人之功。特别感谢inspectredc、Bl00D4NGEL和queueRAM为项目做出的重大贡献,任何人工智能都无法替代他们的作用。同时也要感谢iFuzzle、JamesBLewis和douglasjv提供的代币支持。

希望完整的反编译能对《滑雪小子》社区有所帮助。速通玩家尤其关注初代作品,可用的源代码有助于揭示外部观察到的现象,如CPU路径规划和影响玩家速度的具体因素。完整理解源代码也将为未来的静态重编译和更雄心勃勃的模组制作提供便利。

项目的完成速度同样值得关注。《滑雪小子》仅用84天完成反编译,而《滑雪小子2》耗时596天,前者约为后者的七分之一。

是什么造成了这种差异?2026年的今天,答案至少部分归功于人工智能。但将差异完全归因于大语言模型,未免过于简单化。

不同之处

显而易见,我并非从零开始。此时我已在一个类似项目上投入近两年时间,效率远高于起步阶段。这一优势难以量化,且在一定程度上被新挑战(如使用不同的编译器)所抵消。

总体而言,约4.8%的匹配提交涉及专家干预。我已多次感谢这些杰出人士,但值得重申:没有反编译社区的大力帮助,尤其是inspectredc、queueRAM和Bl00D4NGEL,这个项目不可能完成。

困难通常不在于理解函数的功能,而在于理解该逻辑如何在C语言中表达以及结果代码如何编译。《滑雪小子》使用IDO 5.3编译器编译,而非《滑雪小子2》使用的GCC 2.7.2。

大多数程序员熟悉GCC,这是一款广泛使用的开源编译器,至今仍在积极开发。而IDO是SGI开发的专有编译器,其故事与任天堂64紧密相连。其源代码不可用,原始开发环境依赖于过时的SGI硬件和软件。为了在当今使用并正确理解它,反编译社区不得不逆向工程并反编译部分编译器工具链,并在现代硬件上静态重编译IDO 5.3和7.1套件。这种封闭的历史使得IDO比GCC等开源编译器更难理解。

IDO将优化和代码生成分散到多个不同阶段,在此过程中对代码进行相当激进的转换。C语言中的微小改动可能在这些阶段中产生连锁反应,导致完全不同的寄存器分配。

社区在理解IDO及其特性方面取得了长足进步,但这仍是一门艺术而非科学。大语言模型和我都不太擅长重现其输出。通常的工作流程是:先弄清楚函数的功能,然后编写接近该目的的C代码。之后,借助permuter进行微调,以捕捉任何剩余差异。但并非所有情况下都能通过permuter实现匹配,尤其是当底层结构错误时。IDO的行为使这一工作流程变得难以预测。

一支具备适当专业知识和直觉的积极人类团队,可以达到甚至超越《滑雪小子》反编译的速度。《Pilotwings 64》的反编译仅用74天完成。该游戏函数数量比《滑雪小子》少16%,但整体编译代码更多,因此这并非一个干净的比较。

《滑雪小子》也比其续作规模小,包含2145个函数,而《滑雪小子2》有2995个。函数数量是衡量难度的粗略指标,但确实需要反编译的函数更少。

智能体的帮助之处

我已另文介绍过使用智能体反编译函数的方法。这里采用的基本流程相同,因此我将重点放在变化上。与之前的项目不同,本项目从一开始就能访问前沿模型和功能强大的智能体工具。

库代码及其他易处理部分

我很想看看智能体在项目早期阶段的表现。它们擅长的领域之一是匹配标准库代码。理论上,这是几乎所有任天堂64反编译项目中最明显的部分。这些代码并非游戏独有,其版本可在网上找到。《滑雪小子》包含来自任天堂libultra的百余个源代码段,以及libmus音频库中的函数。N64Sym等工具可以识别ROM中可能的库函数。

这一过程相当成功。主要障碍是说服智能体依赖现有库源代码,而不是从头开始重新反编译相同的函数。这需要更强的提示。一旦识别出可能的库函数,智能体就被指示将该源代码作为起点,并在尝试自己的实现之前,穷尽可能的SDK版本、编译器选项和条件编译路径。

另一个优化是让智能体编写一个脚本,对每个未匹配的函数运行m2c,并自动集成任何精确匹配,而不是依赖智能体逐个尝试这些函数。该脚本仅匹配了1830个函数中的17个,成功率低至0.93%,但任何以此方式匹配的函数都比消耗智能体代币更便宜。

IDO工具与技能

IDO很奇怪,但它的奇怪之处往往有规律可循。成功匹配一个函数可能会揭示一个适用于许多其他函数的编译器特性。Codex通过本地记忆等功能,在任务之间传递经验教训的能力有所提升。为了使这些经验教训超越单个智能体,我提示智能体将观察到的IDO行为记录在DECOMPILATION_LEARNINGS.md文件中。当智能体发现一个可推广的编译器特性时,它可以将证据记录在那里,供后续尝试使用。这创建了一个有用的反馈循环:智能体帮助记录IDO,而生成的文档使后续智能体更擅长匹配IDO代码。

但最有用的资源是N64 Decomp Workbench,这是一套用于调试后期MIPS反编译不匹配问题的工具和文档。它可以对不匹配进行分类、解释重定位、重放单个编译器阶段,并帮助区分结构性问题与寄存器分配问题。重放阶段需要相关的编译器二进制文件和项目特定设置,但一旦配置好,它就能提供原始汇编差异无法揭示的信息。原始差异告诉你两个函数不同,而Workbench能让智能体更好地了解它们为何不同以及何种修改可能修复它们。

工作树与同步

对于这个项目,我在四个Git工作树上运行反编译框架。每个工作树为智能体提供一个独立的仓库副本,允许多个函数并行尝试。

一个虽小但有用的改进是:为每个任务设定明确的截止时间,并将该截止时间暴露给智能体。在《滑雪小子2》项目中,智能体常常难以有效使用permuter,因为它会一直运行直到找到100%匹配或被手动停止。明确的截止时间允许智能体设置合理的超时时间,并在permuting时间与其他形式的解决问题之间进行权衡。根据经验,这也有助于它们判断在困难函数上应继续工作多久再放弃。随着简单函数消失、剩余工作变得更加困难,我可以增加时间配额。

另一个在《滑雪小子2》中就已存在、但在添加工作树后变得更加明显的问题是同步。如我之前文章所述,每个智能体被分配一个要反编译的函数,以及一组已匹配的相似函数作为参考。这些参考点有助于重现特定的IDO指令模式。使用Nigel的--shard选项在工作树之间分配工作,该选项通过基本哈希在指定数量的工作进程之间划分候选函数。

这允许更多工作并行进行而无需重复,但引入了新的问题:随着工作树的分歧。例如,一个工作树可能成功反编译了一个与另一工作树正在尝试的函数99%相似的函数,但该新参考在更改合并之前对另一个智能体保持不可见。定期将所有内容合并到主分支并重新同步工作树可以解决这个问题,但同步所有四个工作树可能需要一个多小时。持续同步浪费时间,而等待太久则会增加分歧。

为了降低同步的关键性,我更新了相似性搜索,使其检查每个工作树。一个新匹配的函数可以立即成为另一个智能体的参考,而无需等待它到达主分支。框架会生成类似以下的消息:

1✓ Candidate ["func_80094A94", "func_80094FF4 (../sbk-c)", 2 "func_80094808", "func_8009491C (../sbk-a)", 3 "func_8009469C (../sbk-c)", "func_80093144"] was fixed!

这有助于在简单函数消失后保持流程高效。同步仍然是整合和推送更改所必需的,但不再是智能体相互学习的必要条件。

模型选择

我尝试了GPT-5.5和5.6、Claude 4.5和Fable,以及GLM 5.2。这完全不科学。这些模型是在一组不断变化的困难函数上进行测试的,有时是在另一个模型已经取得部分进展之后。但总体而言,Codex继续优于Claude,就像上一个项目末期一样。Sol xhigh在可用后尤其有效。

由z.ai提供的GLM 5.2非常令人失望。我之前是GLM的忠实粉丝。它很有效,即使不是前沿模型,其慷慨的使用限制也弥补了这一差距。随着限制变得不那么慷慨,而延迟仍然糟糕,这种权衡变得不那么有吸引力。反馈周期如此之长,以至于我停止给它分配工作,并最终取消了订阅。

下一步计划

当务之急是更好地记录游戏。100%匹配意味着我们拥有每个函数的C代码,但这并不意味着我们理解每个函数的功能。仍有生成的名称需要替换、未知的结构字段需要识别、笨拙的匹配需要清理,以及大量数据需要描述。

《滑雪小子》的重编译工作也在进行中。幸运的是,初代游戏共享了《滑雪小子2:重编译》中补丁解决的许多特性。

我正在研究将初代游戏的关卡和其他内容移植到二代游戏的引擎中,尽管我还不知道这需要多少工作。

除此之外,我对反编译PlayStation上的《滑雪小子Plus》感兴趣,这是初代游戏的日本独占扩展版,包含额外的关卡和角色。

如果你读到了这里,你可能对反编译和《滑雪小子》感兴趣。请查看《滑雪小子》反编译项目。仍有大量的清理和文档工作需要完成,欢迎贡献。

评论

根据评论内容,总结主要观点如下:

1. AI辅助反编译的积极影响 - 提高效率:AI使开发者能快速完成反编译项目,突破人力限制。
- 引用:“You become a machine with your workflow, once again limited only by your time/energy, tokens, and your discretion on how to spend it.”
- 引用:“I’m currently working solo on a Tales of Symphonia gamecube decomp. My aim is to let AI do everything of substance.”
- 复兴老游戏:AI反编译让经典游戏重获新生,如《Snowboard Kids》《Legend of Dragoon》。
- 引用:“Its really great how we can breathe new life into older games like this.”
- 引用:“Huge props to the writer for this, Snowboard Kids is a real gem.”

2. 社区对AI反编译的争议 - 反对声音:部分游戏社区强烈抵制AI,认为其“懒惰”或“污染项目”。
- 引用:“The gaming community is very anti-AI... accepting a PR from someone using Claude taints the project irrevocably.”
- 引用:“Unfortunately, the community will not accept an AI-assisted decomp. Gotta do it for real.”
- 支持观点:AI是逻辑起点,能帮助非程序员参与反编译。
- 引用:“LLMs/agents are a logical starting point for decompiling old games.”

3. 法律与商业考量 - 法律模糊性:AI反编译是否合法存在争议,尤其是“干净室”原则与直接翻译代码的界限。
- 引用:“What's the legal status of these? Historically there was a notion of 'clean room' reimplementation.”
- 商业潜力:游戏公司可能错失通过反编译老游戏获利的机遇。
- 引用:“Seems like easy money to just decompile a retro game, add some quality of life improvements and stick it on steam.”

4. 技术细节与个人体验 - 工作流程优化:设置明确截止日期可提升AI代理效率。
- 引用:“One small but useful improvement was to give every task an explicit deadline and expose that deadline to the agent.”
- 个人挑战:手动反编译耗时巨大,如《Monster Hunter2》两个月仅完成5%。
- 引用:“I worked on it for about two months and got maybe 5% done.”

总结:评论围绕AI反编译的利弊展开,支持者强调效率与游戏复兴,反对者担忧社区接受度与法律风险。技术细节显示AI可优化流程,但手动反编译仍具挑战性。