显微镜下的斯蒂姆皮的发明(世嘉Genesis版)

一些16位时代的游戏卡带附带备份芯片。这些系统允许玩家保存进度。但相比纯软件替代方案——会话密码,它们价格昂贵。

除了更便宜,会话密码还可以共享。玩家们热切地订阅了印刷这些信息的游戏杂志。在90年代,拥有一本装满世嘉创世纪代码的笔记本是提升你在操场上地位的好方法。

最好的密码系统使用的字符串要(a)足够长,可以编码游戏状态中所有重要信息,(b)足够短,方便中学生轻松交换。

这就引出了任与Stimpy秀呈现:Stimpy的发明,1993年改编版尼克国际儿童频道动画为Genesis。它使用14字符的密码,密码来自受限的字母表:

01234567 89BCDFGH JKLMNPQR STUVWXYZ

这个字母表省略了像这样的容易混淆的字符I以及O所以它优化了笔记。它有32个符号,2的幂,方便编程。

当你在密码输入界面选择字符时,其索引会被用来更新值ffff050c.每新增一个条目都会使之前的值移动5位。5位可以代表32个不同的字符,因为2^5=32。

这些操作由函数执行00042272.它的逻辑看起来像这个伪Python:

new_accumulator_value = (old_accumulator_value << 5) | new_character_index 

密码如下0123456789BCDF看起来是记忆中的:

函数在000420dc检查密码是否有效。在从字符串中提取游戏状态参数之前,它会做一些特殊的比较:

  • 密码的前32位是否匹配到密码的数值0x54b43c47?
  • 完成第二个32位匹配吗0xca968788?
  • 做最后8位的匹配0xf8?

这是摩托罗拉 68k检查九字节值0x54b43c47ca968788f8.

为了弄清楚该值对应什么,我们可以反过来推理上述逻辑:

char_index = old_accumulator_value & 0x1f  # Extract 5 bits
new_accumulator_value = old_accumulator_value >> 5 # Shift by 5 bits

但我们还得先多做一步。我们的9字节目标是72位,但密码是70位(14个字符 × 每个字符5位)。所以我们需要先丢弃2位。完整解码如下:

ALPHABET = "0123456789BCDFGHJKLMNPQRSTUVWXYZ"
accumulator_value = 0x54b43c47ca968788f8 >> 2
for _ in range(14):
    char_index = accumulator_value & 0x1F
    accumulator_value >>= 5
    print(ALPHABET[char_index], end='')

输出为YKS3ULBYKS3ULB.这是反过来的,因为上面的代码是从右到左工作的。目标密码是BLU3SKYBLU3SKY.

一旦加入,工作人员字幕就开始播放了!

密码当然指向BlueSky 软件,开发该游戏的工作室。这是整个过程的视频:

我觉得这个密码以前从未被报告过,这也是我发现的最古老的作弊码!游戏识别的其他密码已经被记录下来——这个GameFAQs 指南用户Zachary1021拥有完整套装。

其他

这就是我们关于16位游戏的第一篇逆向工程文章。我对Genesis 游戏的 Ghidra 加载器我相信这不会是最后一次。

感谢阅读!土星环将很快带来更多内容。

添加评论
点赞收藏
点踩分享查看原文
评论
?
参与讨论