返回资讯中心
外部精选
软件工程
#开发者实时流

开发者逆向工程儿童相机固件,成功移植运行《Doom》

来源标题:Reverse Engineering a Children's Camera and Making It Run Doom

一名开发者逆向工程了一款廉价儿童相机,成功将《Doom》移植到其未公开的SoC上,在仅891K可用内存下实现约30fps运行,且相机功能保持正常。除游戏外,声音、芯片音乐、存档读档均可正常使用,操控映射也足以实际游玩。整个过程耗时两天,开发者还为此自建了SDK、本地模拟器和自定义编译器。

Hacker News 最新speckx2026/11/4 · 今天30 分钟阅读

以下正文由 AI 翻译自 Hacker News 最新(原文版权归原站所有),可能存在偏差,重要内容请以原文为准。

拆解、分析并重写一台廉价儿童相机的固件——它用的是一颗没有任何文档的 SoC,然后把 Doom 移植上去,在不到 1MB 可用 RAM 里实现完整音效、音乐和 30fps 的游戏画面。

一开始只是好奇“这相机跑的是什么固件?”,结果变成了两天外加几个深夜的反向工程:拆解一颗完全没有文档的 SoC(system on a chip),搭建 SDK、本地模拟器、自制编译器,还完整移植了 Doom,让它在只有 891K 可用 RAM 的相机上跑起来——同时相机本身的功能依然完好。

先说清楚,这不是为了移植 Doom 而移植 Doom。按键映射做得足够好,你真的能玩,所有音效都在,有 chiptune 音乐,能存档读档,帧率大约 30fps。这是装进口袋里的 Doom。

这事以前有人做过吗?问“Doom 还没被移植到什么上”可能更容易回答,但我能找到的类似例子只有两个:一个是 Ilya Kurdyukov 的视频,他用的芯片(Spreadtrum SC6531)有 4-8MB RAM,而且他没有透露任何实现细节;另一个是 LGR 的视频,那基本就是一台完整电脑,同样有充足的 RAM 和完整的软件开发 SDK。相比之下,我们这次的挑战要大得多。

我选择把所有东西完整记录在 GitHub 上——固件和芯片工作原理的详细分析、一个能通过 USB 从你自己的相机里导出固件的工具、SDK、编译器补丁,以及 Doom 移植。所以你可以自己动手做,或者把同样的技术用到类似设备上。这篇文章讲的是我们怎么走到那一步的——repo 则是你自己走一遍的路径。

这就是那台相机。包装盒上什么信息都没有——没有厂商、没有地址、没有名字,UI 里也什么都没有。它就像是为了能贴上各种品牌卖出去、而没人需要为它负责一样。唯一的标识是说明书里的型号:X9S。

USB ID 也查不到任何东西。这东西在网上几乎隐形,除了 AliExpress 上有人在卖。

然后我看了它拍的一张照片,EXIF 数据里有发现——制造商写的是“HX-Tech”——这把我引到了 Sprite_tm(Jeroen Domburg)写的一篇文章,叫 Kid-cam firmware modding。那是另一台略有不同的相机,跑的固件也相当不同,他想做的改动也很小。不过他的工作给了我们一些不错的起点信息(比如该预期什么样的 CPU),但这还不够,如果我想继续推进,就得把设备拆开。

我本来不太想拆,因为我女儿很喜欢它,我真不想弄坏,但到这一步我已经投入太多了。拿出烙铁,拆掉电池,这样就能安全操作。

里面我找到了芯片型号(HX3302B),哪里都查不到其他参考资料,还有一颗 8 脚 flash 存储芯片。读出那颗芯片是解开一切的关键,幸好我手头有合适的工具——XGecu T48 编程器,我修主板时经常用它。你会惊讶于 20 年以上的板子上 bitrot 有多常见。

我有一个夹子可以扣在芯片顶上,这样就不用把它从板上焊下来,但这种夹子很难对准,而且经常固定不住。这次我不得不用双手按住它,再用小指去点鼠标读内存。试了好几次,直到连续三次读取结果完全一致,我才相信没有读取出错。

拿到这份 dump,真正的工作才刚开始。

最近我花了不少时间,帮 OpenJones 项目做《Indiana Jones and the Infernal Machine》的 100% 字节匹配反编译,所以我很清楚 AI 在反编译和逆向工程上有多强——但也清楚它的短板,以及怎么让它发挥最大作用。

这些经验派上了用场,没多久 Claude 和我就把 Ghidra 跑起来,把固件拆解成了各个组成部分。这要感谢 Sprite,他已经搞清楚了 CPU,并发布了对应的 Ghidra 处理器定义。我们很快发现,尽管芯片相似,我们的固件却非常不同——比如升级文件叫 Xly100s.bin,而不是 Sprite 的 hx330x_sdk.bin。

从 Sprite 的文章里我们已经知道,这些相机可以从 SD 卡上的文件自我升级。读固件代码时,关于这个过程我们学到的第一件新事情是它的写入方式,具体来说就是它做的是部分更新——从 flash 开头开始写,你文件有多长就写多长。所以如果你给一个 1MB 的文件,它就刷写前 1MB,剩下 3MB 不动。这很重要,因为这意味着我们可以做小而精准的改动,只重写必须的那部分 flash,后面的内容原封不动。

手头有 T48 意味着我们总有一条应急回家的路——可以直接把原始固件刷回去——但那是很麻烦的活,我们想尽量避免。从 SD 卡升级要容易得多。

另外,虽然文件头里有校验和,但相机从来不检查它是否正确。你只需要把头部的时间戳改一秒,理论上就足以触发刷写。根据代码,每次开机都会执行升级检查。

所以我们从完全没有实际改动开始——只改 flash 的前几 KB,把头部时间戳动一下。目的是触发刷写、看到升级界面,确认我们走在正确的路上,而且因为只改了时间戳,这大概是刷写能做到的最安全的情况了。

我们本以为版本界面会显示新的时间戳,但没有,而且就我们能看出来的,什么都没发生。于是我们花了不少时间去找隐藏的触发条件。

(原文较长,此处译出前 6000 字,完整内容请点「打开原文」。)

正文由 探How 从来源站点 RSS 同步,内容未经改写;遇到排版缺失或需要图片、视频时请以原文为准。

打开原文
去社区讨论 →