IT之家 09-18
《毁灭战士》连续运行两年后崩溃,源于数值溢出漏洞
index_new5.html
../../../zaker_core/zaker_tpl_static/wap/tpl_keji1.html

 

IT 之家 9 月 18 日消息,1993 年 12 月《毁灭战士》(Doom)正式发布,该游戏不仅奠定了新兴的第一人称射击(FPS)游戏类型的标准,其受欢迎程度更是达到了 " 毁灭战士克隆品 "(Doom clone)一词在发布后的数年里成为描述所有第一人称射击游戏代名词的地步。自上线以来的近 32 年间,得益于海量的 Mod 和玩家自制关卡,玩家在这款游戏上投入的时长肯定是个惊人的数字,但几乎没人会让游戏连续运行两年以上。不过,还真有人这么做了,而结果是…… 游戏崩溃了。

在 LenOwO 网站上,管理员明基(Minki)发文称,他通过在一台 2003 年款华硕 MyPal A620 掌上电脑(Pocket PC)上运行 WinDOOM,复现了这场 " 预期中的崩溃 "。该设备搭载当时刚推出的 Windows Mobile 系统,核心为英特尔 XScale ARMv5 架构的系统级芯片(SoC)。明基表示,他对这台设备进行了改装,为其配备了 " 基于 18650 锂电池的 DIY 不间断电源(UPS)",该电源通过路由器的 USB 接口供电,以确保稳定的 5V 电压输入。之后他让系统一直运行,后来几乎忘了这回事,直到昨天,他才发现设备屏幕上弹出了一条应用程序崩溃的提示。

据 IT 之家了解,和同时代大多数基于源代码移植的版本一样,WinDOOM 源于 1997 年发布的《毁灭战士》原始源代码,因此其不仅复现了原版游戏的大部分功能,也保留了多数漏洞。与多数大型商业软件项目类似,即便是最终的 1.9 版本,《毁灭战士》仍存在诸多已知漏洞。其中一个奇特的缺陷与游戏内部 " 演示文件 "(demo)的播放机制有关:通常在游戏 " 吸引模式 "(attract loop,指无人操作时自动播放演示画面的模式)下,每次开始播放新的演示文件时,"gametic"(游戏计时单位)数值并不会重置。该数值用于追踪游戏多方面的计时信息,其递增频率为 35 赫兹(即每秒 35 次),且与游戏的渲染循环相互独立。

可以很容易算出,gametic 数值不重置,久而久之必然会累积成一个极大的数。《毁灭战士》引擎的核心程序员约翰・卡马克(John Carmack)在编写这段代码时,肯定注意到了这一点,但他或许认为这无关紧要 —— 因为该数值被存储为 32 位有符号整数。这意味着它的最大值为 2147483647 个计时单位,达到该数值后便会发生 " 溢出 "。在 C 语言中,整数溢出的行为并无明确定义,但在 x86 架构的电脑上,溢出后数值总会跳转为最大负值 - 2147483647。不出所料,游戏无法妥善处理这种情况,结果便是崩溃,至少在 Windows Mobile 2003 系统上是如此。

按照每秒 35 个计时单位计算,gametic 数值溢出大约需要 1.95 年。这比明基的预估时间略短,但没人知道这台华硕掌上电脑在他发现屏幕上的错误提示前,已经保持这种状态多久了;从照片来看,这台已有 22 年历史的掌上电脑显然不常被关注。另一种可能性是,明基使用的 WinDOOM Windows CE 移植版本(即 Doom4CE)为了实现更稳定的帧率和降低硬件负载,将游戏计时频率降至了 30 赫兹,这种做法在《毁灭战士》的主机移植版中很常见,比如雅达利 Jaguar 和超级任天堂(Super NES)版本。若情况属实,gametic 数值溢出则需要约 2.26 年,与明基所说的 " 两年半 " 更为接近。

无论具体原因如何,这场实验带来的启示很明确:不要让《毁灭战士》连续运行两年。

宙世代

宙世代

ZAKER旗下Web3.0元宇宙平台

一起剪

一起剪

ZAKER旗下免费视频剪辑工具

相关标签

明基 源代码 it之家 锂电池 程序员
相关文章
评论
没有更多评论了
取消

登录后才可以发布评论哦

打开小程序可以发布评论哦

12 我来说两句…
打开 ZAKER 参与讨论