Appearance
本文是视频《实测 AI 克隆软件:结果比你想的糟糕得多》(作者:Dave's Garage)的精读笔记,配套中配视频观看效果更佳。
实测 AI 克隆软件:结果比你想的糟糕得多
只给 AI 一个 Windows 计算器的成品 exe,不给一行源码,它能不能用 Rust 造出一模一样的程序?微软退休工程师 Dave 真做了这个实验——克隆确实跑起来了,但真正值得看的是他随后的追问:这算不算盗版?这条视频一半是硬核逆向工程演示,一半是对 AI 时代“软件所有权”的清醒思考,标题里说的“糟糕”,恰恰在于它成功得让人不安。
图:Dave 在他的“车间”开场,身后是几十年的 Windows 时代记忆
全景:一条主线看懂
全片是一条“实验→结论→追问”的链:Dave 用美国国安局开源的逆向工具 Ghidra 把 calc.exe 反编译成伪代码,让 AI 读懂后翻译成 Rust 并编译运行,证明 AI 能产出“能用的重建”——但因为 AI 需要返工修补,这个克隆注定接近而不完美。技术惊叹之后他话锋一转,用版权法、经典判例和自己用 AI 开发软件的经历论证:换种编程语言抹不掉作品的“血统”,未经授权克隆他人专有软件应当被认定为违法。
图:全片主线——成品 exe → 反编译分析 → AI 翻译成 Rust → 新程序 → 法律与伦理拷问
一、为什么拿计算器开刀:一场设计好的压力测试
动因来自新闻:已经有人用 AI“克隆”了整个 Photoshop,随后又克隆了 Office。Dave 的判断是,这像上世纪 50 年代人们梦想核电“便宜到不用计量”一样——软件正在被 AI 推向“便宜到不要钱”。他这期要做两件事:给出对“AI 克隆应用”的犀利观点,并精确演示克隆到底是怎么做的。
核心实验问题定义得非常严格:只给一个成品 Windows 程序,不提供任何源码和符号,让 AI 用 Rust 完全重写出一模一样的程序——本质上是把别人程序里的控件、计算和行为,从旧 exe 搬进一个干同样活的新 exe。
选计算器有两层考虑。一是法律安全:它是 Windows 中少见的以 MIT 许可证开源的组件,怎么折腾都不会有人找上门。二是 Dave 本人在微软时“拥有”过计算器这个产品——他特意澄清,酷的代码不是他写的,他只是带开发团队的负责人,因此最清楚这东西水有多深。
“它是少见的 MIT 开源组件,我乱动它没人来踹门。” ——Dave 解释为何选 Windows 计算器当实验对象:合法,且知根知底。
计算器远比表面复杂:算术之外有标准、程序员、会计等多种模式,支持多种进制,还内置无限精度数学运算例程——这些是藏在表面之下的“硬货”。Dave 由此设定判定标准:这些东西 AI 光靠看界面、查公开资料推不出来;尤其是那些古怪(quirky)的行为,只有真正消化了二进制里的代码才可能复现——它能复现怪癖,就证明它“读过菜谱”。而成功的秘诀摆在明面上:可执行文件里包含指令,程序做的每一个决定,都必然对应某处某个人写下的代码。哪怕原始源码文件已经消失,仍有东西可查。
本节要点:实验前提是“零源码、零符号”;选计算器图的是 MIT 开源带来的合法性和 Dave 的知根知底;能否复现古怪行为,是检验 AI 是否真读懂二进制的试金石。
图:Windows 计算器——看似简单,内藏程序员模式、会计模式与无限精度运算
二、NSA 的工具,如何让二进制“开口说话”
Dave 的手术刀是 Ghidra——美国国家安全局(NSA)发布的逆向工程框架,他自嘲这期视频“多亏国安局帮忙”。Ghidra 能反汇编机器指令,并据此构建类 C 的高层描述。但必须记住一个限定:它的输出不是还原的原始源码——它不知道任何变量名和符号,所有命名只是“最佳猜测”,是从二进制逻辑倒推出的“能编译出同样逻辑的 C 代码”。内部机制上,Ghidra 把各家处理器指令统一翻译成更简单的 P-code 微指令(加载一个值、执行算术、取出结果、选择分支),为“处理器正在做什么”提供统一词汇——顺带一提,老版 Office 当年正是用类似的 p-code 方式编写的。不过在 Dave 看来,用什么中间格式并不重要,路线是固定的:可执行文件 → 分析其操作 → 重写为 Rust → 产出新程序。
AI 的真正难点不是算术,而是状态机:计算器收到一位数字时,要判断它是接续屏幕上正在输入的数,还是另起一个新数;要记住有没有挂起的运算符;按完等号后,下一位数字可能开启新算式——这些机制全部编码在编译后的程序里。AI 要做的,是把一次内存读取读成结构体的一个字段,把一团缠绕的分支整理成 Rust 的 match;还原出的代码外观可以和原版很不一样,但行为必须一致。同时也要认清固有限制:变量名和注释在编译时就永久丢失,拿不回来,能得到的只是一个能运行、但有点难读的工程。
像样的复刻还得兼顾代码之外的部分:可执行文件里的资源(对话框布局、字符串、图标)、导入表(程序调用了哪些外部组件),以及快捷键是否生效、清除按钮是否重置到正确状态这类细节。这正是计算器作为样本的巧妙之处——“皮”人人会做,在编辑器里摆几个按钮、实现加减法,门槛很低;难的是重现按钮背后长期积累的设计决定。失败方式很多:反编译阶段搞错函数含义,或状态变更逻辑实现错误——界面看着一样,行为却完全不同。
本节要点:Ghidra 给的是“最佳猜测版”伪代码而非原源码;克隆的本质是翻译行为而非翻译文本——状态机逻辑决定成败,变量名和注释永久丢失,资源、导入表与细节行为同样必须还原。
图:Ghidra 界面——左侧是恢复出的函数列表,右侧是它“猜”出来的类 C 伪代码
三、实测:AI 跑通了,但“能跑”不等于“克隆成功”
实操分三步:把可执行文件变成 AI 可用的信息;把信息变成 Rust 编译器能接受的源码;启动克隆结果,与原版对比验证。Dave 的提示词核心是:用 Rust 重写 calc,先把二进制反编译成中间格式,再把逻辑完整准确地翻译成 Rust,编译出一个名为 AI-calc 的新程序,功能必须与原版 C 语言 calc 完全一致——并不断迭代,直到所有测试通过、行为一致、像素级还原。他把这定位为一个没有源码访问权限的 C 到 Rust 翻译项目。AI 询问是处理整个程序还是只做启动器,他选了整个程序,连带所有依赖的 DLL。
跑出来的数字相当惊人:
| 指标 | 数字 | 说明 |
|---|---|---|
| 计算 DLL 恢复函数 | 10,195 个 | Ghidra 从核心逻辑库中恢复 |
| UI DLL 恢复函数 | 18,959 个 | 界面层同样被完整分析 |
| 命令分类 | 131,077 种 | AI 对输入命令的归类 |
| 自动生成的测试 | 8,201 个 | AI 自建的验证体系 |
| 测试命令序列 | 357 种 | 覆盖组合操作路径 |
| 中间显示状态 | 8,032 种 | 全部与原版引擎一致 |
AI 不开界面就验证了 2+3=5;357 种命令序列、8,032 种中间显示状态与原版引擎完全一致。但请注意一个关键细节:AI 在自测中发现了若干错误,回头修改代码才让测试全部通过。Dave 认为这件事本身就说明问题——它不是完美的确定性复刻;它在过程中做出各种假设、“瞎填空白”,直到结果不对才发现自己错了。既然必须回头修补,就不能假定克隆完全准确。他的结论是:可能很接近,但不会完美。
实测环节,他输入 123+456,还另拿一个计算器交叉验证——结果正确,得到一个能运行的 Rust 应用。但他随即给成果“降级”用词:所谓一句话完成任务(one shot)只描述人机交互方式,不代表内部全自动、无需人工修改;程序员总让人后悔用“完美”这个词,这次展示的只是**“能用的重建”(working reconstruction)**。要声称与原版完全等价,得覆盖冷门输入——比如“1997 年以后没人按过的组合键”后面可能还藏着差异。AI 的测试套件确实跑了数万种计算,但 Dave 提醒:当年 Intel 对奔腾 II 的数学测试也很强,连 Intel 都不敢保证无错——测试再多,也没有绝对保证。
本节要点:AI 确实从零造出了能跑的 Rust 计算器,近三万个函数被恢复、八千多个测试通过;但“需要返工”这一事实本身就宣告了它是近似复刻——接近原版,不等于原版。
图:AI 的工作报告——恢复的函数数、测试数量密密麻麻排满一屏
图:克隆版计算器与原版同框对比,肉眼几乎无法区分
四、灵魂拷问:到底谁创造了什么
实验成功之后,第二个问题浮出水面:**谁创造了什么?**Dave 先铺背景:他整个职业生涯都在做 Windows 软件,传统观念里编程必须从源码正向书写;这次却是从流水线末端(成品)倒着走,让机器逆向推回源码——如果恢复的是自己的程序,这像一种实用的恢复技术;但对别人的程序做同样的事,就是另一回事了。
他先科普程序出厂流程:开发者写源码 → 编译器把源码变成机器码 → 链接器把各部分与库、系统服务拼成可执行文件。这条流程不可逆地丢失信息:好用的变量名消失;注释运行时并不需要;你精心从一个函数里拆出的另一个函数,可能被编译器内联合并回去;同一操作的不同写法优化后可能生成完全相同的指令。所以逆向拿不到原始源码——程序里有变量叫 total,可执行文件里并不会藏着它等你解开;编译器只保留电脑需要的东西,几乎从不含程序员“喝完咖啡后的想法”。
由此引出全片第一个重要认识:**不同的源码文本,可以描述同一种计算。**可以换语言、重命名所有变量、重新组织函数,同时与原程序保持实质性联系——所以在编辑器里看到 Rust,并不能说明这个程序是独立设计的。
接着他拆解那句让人安心的话——“没用原始代码”:原始源码文件他确实没有,也没交给 AI,甚至核查过 AI 没把外部代码当样本抄袭。但可执行文件本身就是编译后的代码——把编译产物重新组装,并不等于变成一组无关的事实。
“把分析翻译成 Rust,也抹不掉分析的来源。” ——Dave 在回应“没用原始代码就算独立创作”的说法时强调:可执行文件本身就是编译后的代码,翻译改变不了分析的出处。
图:Dave 推演“翻译能否创造独立性”的关键论证段落
态度在此发生明确转折:作为工程演示,这一切令他震撼(blows my mind);但作为拿别人专有商业产品制造未经授权替代品的方式,他认为这应该是违法的。他的直觉是称其为盗版——换一种编程语言,也不改变性质。他补了一句免责声明:这是他的道德判断,他不是律师,仅供参考。
“作为工程演示,这一切让我震撼;但作为制造未经授权替代品的方式,我认为它应该是违法的。” ——Dave 全片态度的转折点:惊叹留给技术,批评留给用途。
本节要点:编译天然丢失变量名、注释与函数结构;“不同源码文本可以描述同一种计算”意味着看到 Rust 不代表独立设计——克隆的“血统”藏在分析来源里,换语言抹不掉。
五、法律的现实:版权保护表达,不保护功能
道德判断之外,法律层面更复杂,Dave 给出了清晰框架。美国《版权法》第 102 条明确把思想、流程和操作方法排除在保护之外。具体例子:微软不能因为计算器会做加法就拥有加法——任何人都可以写计算器,写得再好也不需要微软批准。但表达这些功能的代码可以受版权保护,而且保护可以延伸到字面源码文本之外——所以“改掉所有变量名”不是万能的法律豁免。法律分析的核心任务,是把受保护的表达与不受保护的功能需求区分开来;而对一个几乎完全为完成任务而写的程序,这是件难事。
他反复使用的类比是翻译:把小说翻成另一种语言,你得到了新词,但你不是原作者——不能声称它是自己的作品,因为它依赖了另一个人的创造性投入。软件让这个类比更复杂:版权不拥有底层的计算逻辑,仅仅换一种新语言,并不能说明受保护的表达是否在转换中保留了下来。
当然,研究二进制有许多正当理由——从分析恶意软件到构建兼容替代品,法院此前也允许过某些逆向工程。两个经典判例:Sega 诉 Accolade 案,法院允许在特定情况下反汇编,以获取兼容所需的非保护功能元素;Sony 诉 Connectix 案,开发模拟器过程中对 PlayStation BIOS 的中间拷贝被认定为合理使用。也就是说,开发中用过原程序不自动导致败诉,但这些判例并不颁发“复制商业软件的通用许可”——Sega 案明确保留了对成品侵权追诉的权利。
历史正面案例是 Phoenix 公司:几十年前它为 PC 克隆厂商制作了自己的 IBM PC BIOS 版本,IBM 愤而起诉,Phoenix 最终胜诉——靠的是净室工程:一名工程师只撰写 API 文档、绝不查看实现代码,另一个团队严格按规范实现;正确执行的净室工程能产生完美替代品,即使实现完全不同。但注意规模差距:原始 PC BIOS 只有约 12 个入口点,而 Photoshop 这样的应用有数千个接口点——理论上可以净室重写,仅写规格说明的工作量就已极其庞大。另一条路是用自动化工具实时驱动原始应用、摸清所有行为细节,Dave 认为目前尚不可行,但终有一天会实现。他还提醒一个容易忽略的坑:微软 2019 年确实以 MIT 许可证开源了新版计算器,但这确定不了每个历史 calc.exe 的许可状态;AI 训练时是否接触过这些公开源码,问了模型它说没有——但你无法确证。把专有软件喂给自动翻译器、换种语言就声称是全新独立作品,这件事值得比目前所受的严格得多的审查。
本节要点:版权不保护功能(加法不属于微软),但保护表达且可超出字面源码;Sega、Connectix 判例与 Phoenix 净室工程证明逆向有合法路径,但每条路都有严格前提——判例不是复制许可,开源仓库也覆盖不了全部历史版本。
图:净室工程示意——写文档的人与写代码的人严格隔离,从流程上杜绝抄袭
六、底线与未来:能力会扩散,规矩要先立好
Dave 用自己的项目示范“正确的打开方式”。他开发任务管理器改造版 Tmog 时,特意没有把任何现成软件喂进去做“翻译”:先写了一份 107 页的规格说明书描述想要的产品,之后又花了 400–500 个 GitHub PR 打磨到位——先自己做设计决策,再表达这些决策让 AI 实现。但他也冷静提醒:规格书并不天然清白,你可以在里面塞进他人受保护的表达来掩盖抄袭;从提示词开始,也不能证明合法性。真正有意义的分界线是:自己设计想要的行为,和拿别人的实现当原材料,是完完全全不同的。
图:Dave 展示他用 107 页规格书“喂”出来的 Tmog——先设计,再让 AI 实现
由此他提出标识原则:当流程是“现成二进制 → 分析 → 最终替换”,产物就应标注为“衍生自该应用的克隆”——即便获得权利人授权、完全合法,它依然有一个“祖先”。他反对的从来不是移植或重写本身,而是借“翻译”这一步宣称占有原作、抹杀原作的价值。伦理原则一句话:如果流程依赖别人的软件或任何创作性输入,就应当承认并拥抱这份依赖。法律上同理——复刻受保护的表达,输出叫 Rust 也没获得授权。
“编译器只产出可执行文件,它开不出‘独立创作’的证书。” ——Dave 反驳“换个语言重写即算独立创作”的核心论据。
对技术边界他也毫不夸大:把克隆对象换成 Photoshop、或把 Mac 的 Final Cut 移植到 Windows,工程量大得多——大型应用依赖各种库、素材、文件格式、插件和系统服务,这些组件不会因为被“礼貌地请求”就自动变成可移植的 Rust。计算器实验证明不了明天就能移植 Final Cut,任何具体时间表都只能是猜测。实验真正的价值,是说明了为什么我们应该关注这个技术的发展方向:逆向工程传统上高度专业化,而 AI 能协助解读证据并转化为另一种实现;一旦这个过程更快、更可靠,即使法律原则不变,制作“授权替代品”的经济账也会随之改变。正面用途也很实在:开发者可以用它找回丢失的代码、在授权前提下用可维护的语言重建老软件。但当同一种能力被用在“软件所有者被当成麻烦”的情境里,它就变了味。
回扣开篇之问:AI 能否从 Windows 可执行文件反向推导、再正向生成一个 Rust 应用?本次实验中它确实产出了能运行的复刻——但“完全等价”仍待验证,“合法性”取决于比目标语言多得多的因素。他的最终表态毫不含糊:把别人的专有应用喂给自动化重写系统、制造未经授权的替代品,应当违法;现行法律可能已禁止其中某些情形,而仅仅换一种编程语言,不足以说服他“原作对该过程毫无贡献”。
“看完整个过程,想想如果这软件是你的,你会怎么想?” ——Dave 的收尾之问:技术评判之外,最终考验的是每个观众的立场。
本节要点:合法与越界的分水岭在“谁做的设计决策”;AI 时代的正确姿势是“我的需求→AI 实现”,而非“别人的二进制→克隆替换”;能力扩散的速度一定快于立法,伦理自觉必须先走一步。
总结要点
- 实验结论:只凭一个 exe,AI 真的造出了能运行的 Rust 版计算器——近三万个函数被恢复、8,201 个测试通过、123+456 算对;但 AI 需要返工修补这件事本身说明,它是“能用的重建”,接近而不完美。
- 技术原理:NSA 开源的 Ghidra 把机器码反编译成“最佳猜测”的伪代码;变量名和注释在编译时就永久丢失——克隆能保住行为,保不住原貌。
- 关键认识:不同源码文本可以描述同一种计算;“换了语言”不等于“独立创作”,编译器抹不掉分析的来源,也开不出独立创作证书。
- 法律框架:版权不保护功能(微软不拥有加法),但保护表达且可超出字面源码;Sega、Connectix 判例和 Phoenix 净室工程说明逆向有合法路径,但都有严格前提。
- Dave 的底线:依赖他人成果就要公开承认;“我的需求→AI 实现”与“别人的二进制→克隆替换”是两回事,后者应当违法。
迁移与启发
- **职场:做“写规格书的人”,而不是“点生成键的人”。**Dave 用 AI 开发 Tmog 的方式是先写 107 页规格书、再改 400–500 轮。放到日常工作里:接到任务先把“要什么、验收标准是什么”写清楚,再让 AI 干活,你审它改。AI 时代最不容易被替代的,是把需求和标准定义清楚的能力,以及对产出负责的判断力。
- **投资与消费:看 AI 产品,先问原料从哪来。**技术上能跑通,不等于法律上站得住。无论是采购选型还是评估一家“AI 速成”公司,先分清它的核心竞争力是“自己设计+AI 实现”,还是“搬运别人成果再换皮”——后者省下的成本,可能变成将来的诉讼与下架风险。个人用 AI 也一样:别把受版权保护的素材喂进去,再把产出当原创发布。
- **生活决策:对“接近”保持警惕,重要材料留原始底。**AI 需要返工,说明它在用假设填空白——用它给的健康、法律、财务建议时,学 Dave 拿第二个计算器交叉验证,找独立信源再核一遍。另外,编译会永久丢失变量名和注释,这提醒我们:合同、聊天记录、重要笔记自己留原始件,别只存转发或摘要——信息一旦被“压缩”,丢掉的细节就拿不回来了。
一句话升华
AI 能把软件翻成任何一种语言,却翻不掉它的来处——承认自己站在谁的肩膀上,才是一个创造者真正的体面。
