鱼羊 萧箫 发自 凹非寺
量子位 报道 | 公众号 QbitAI

又到了考(bao)验(lu)阅(nian)历(ling)的时候了。

盆友,你可识得此物?

在80年代90年代,可是有不少宝贵的代码数据,都是存储在这样的载体之中的,比如DOS版的仙剑1。

辣么,如果现在有一张存储古早代码的软盘到了你手里,你该如何解开其中的历史秘密?要知道,在今天,你可能连读取软盘的设备都很难找到……

要是再磕了碰了,那就更完蛋了。

最近,vsftpd作者、Google Project Zero创始人Chris Evans大佬就遇到了这样的难题:

在和Phil Pemberton一起恢复存储在软盘中的几个古早游戏代码时,他们发现,部分软盘出现了不同程度的损坏,以致于直接用Greaseweazle这样的设备是无法读取的。

Greaseweazle F7 Plus

怎么办?大佬决心要搞出一个船新的方案,抢救宝贵历史代码。

设备也简单,就用万能的示波器

没错,就是那种用来测试电路、显示波形的仪器。

恢复出来的游戏代码竟然还能玩,而且界面显示清晰:

这波操作,看得网友直呼:数据考古不要太酷。

手敲0和1,100%恢复古早代码

软盘通常以模拟信号的方式存储数据。

这里面存储的模拟信号,用的是最原始的FM调制(频率调制)。

也就是说,它所存储的信号01,分别会以不同的波形频率表示。

这代表的是00101100

以下面这段波形为例,单位周期下,在信号为0时,输出的频率是比较的;而当信号变成1时,频率就会突然变

因此,只需要找到周期规律,就能判断一个周期里,信号代表的是0还是1。

但也不能仅仅看峰值来判断信号是否为1。例如,在这个周期里,就出现了一个“假峰值”,然而人工解读的结果还是0。

因为这个峰值其实是一个噪音,信号的整体趋势仍然是下降的,波形的频率本质上并没有变化。(但信号为1时,波形会呈现一个完整的周期,起始点和终点的值是非常接近的)

有网友给出了简单的判断方法:一个周期过去,如果信号值变化很大,则代表0;如果信号值几乎不变,则代表1。

据Chris Evans介绍,代表0的正弦波信号,是8μs一个周期;而代表1的正弦波信号,则是4μs一个周期。

这种情况下,用Greaseweazle等“现代设备”直接读取数据,会出现一个问题。

如果软盘中的数据,由于各种外部原因(时间久远、使用次数过多)出现了损坏,那么仅凭机器,是无法从这些带有大量噪音的数据中完成解读的。

就像这样,有一个扇区出现了问题

但人却可以轻易看出这些数据中的“规律”,从而判断信号的状态。

因此,用示波器将软盘中传输的模拟信号展示出来,再由人工进行解读,会是个更好的方法。

于是Evans和Pemberton将示波器直接连上了软盘驱动器的测试点,看看软盘到底都输出了些什么信号。

其中,输入信号会呈现一正一负两个波形,用来消除一部分噪声。

从各种“年代久远”的软盘解读出的信号来看,难怪Greaseweazle这些设备读不出来……(连人也得仔细分辨一会儿)

接下来,就是处理这些神奇的波形了。

为了更好地处理噪音、绘制信号图像,Evans和Pemberton还用上了Audacity来处理模拟信号。

Audacity是一个免费开源的音频分析和编辑工具,能够快速放大和检查波形,还具有多功能低通滤波器,以及直接绘图的功能。

另外,Audacity也支持CSV文件的导入。

Evans和他的小伙伴还利用这样的音频工具搞出了新的衍生玩法……

比如将速度放慢100倍,听一听软盘记录的声音(软盘每转一次时间为0.2秒,该样本为20秒):

恢复出来的数据,效果还不错。

但上面这些,还只能用于数据比较正常的信号。

对于软盘本身有轻微损坏的信号,想要恢复就变得更困难了。

软盘坏了怎么办?

要是软盘上有划痕,这部分的信号就会变得非常难以辨认。

这是Evans和Pemberton还原的其中一个凹痕的信号,显然中间那部分,信号振幅(图中信号的强度)丢失得非常厉害,还自带噪音

其中一种方法是,多用几种不同的软盘驱动器试试。

先用MF504C软盘驱动器过滤一下噪音:

好像效果不大。

换上另一个TEAC软盘驱动器后,显示的信号更加给力了,但强度还是很小:

用肉眼分辨的话,难度还是太高了。

鉴于此,Evans和Pemberton又换上了TEC软盘驱动器,效果好多了,峰值也变得清晰可辨。

除此之外,应对这类信号振幅丢失的情况,还有另一种方法:手工绘制修复。

由于峰值缺失得实在太厉害,只能通过人为修复,绘制部分峰值信号,来解决强度过低的问题。

但无论如何,这些信号都可以被修复。

据作者介绍,上面这些办法100%可以恢复软盘中的数据。

除非真的出现了不可抗力。

例如,软盘的一部分被损坏得很彻底

这种情况下,软盘数据就彻底没办法恢复了。

所以,家里有“上古宝物”的小伙伴,一定要保护好自己的软盘!

关于作者

这个项目的作者之一,是最受欢迎的Linux发行版FTP服务器程序vsftpd作者、著名黑客Chris Evans

他毕业于牛津大学,毕业后进入甲骨文工作,其后又在谷歌工作了9年时间,是Chrome浏览器安全团队和谷歌黑客团队Project Zero的创建者。

据报道,Project Zero团队由谷歌内部顶尖安全工程师组成,使命是找出全球范围内高价值的安全漏洞,并将其彻底消除。

2015年,特斯拉把这位黑客大神揽入麾下,负责领导安全工作。2016年,Evans从特斯拉离职。

Evans还是漏洞赏金平台HackerOne的成立顾问。

现在,据老哥自己说,他处在“半退休”状态。

最后的最后,你是否也对80年代的游戏代码长啥样产生了好奇?

Evans表示,这些恢复出来的源代码已经交给游戏原作者,是否开源就要看原作者的意思了,如果你感兴趣,不妨蹲个后续~

不过,此前量子位还介绍过另一个从21张软盘中被“抢救”出来的红白机游戏,代码已在GitHub上开源:

https://github.com/DickBlackshack/Days-of-Thunder-NES-Unpublished/

参考链接:
[1]https://scarybeastsecurity.blogspot.com/2021/05/recovering-lost-treasure-filled-floppy.html
[2]https://news.ycombinator.com/item?id=27187435

用示波器恢复软盘里的游戏,这个程序员大神的操作太硬核了相关推荐

  1. 程序员大神,C++编程制作不一样的五子棋小游戏

    五子棋是世界智力运动会竞技项目之一,是一种两人对弈的 纯策略 型棋类游戏,是世界智力运动会竞技项目之一,通常双方分别使用黑白两色的棋子,下在棋盘直线与横线的交叉点上,先形成5子连线者获胜. 本五子棋运 ...

  2. 程序员大神教你用C++开发纸牌游戏,小白也能学会!

    A每个目标牌叠必须从 A 开始.如果没有,则必须在列之间移动纸牌,直到翻开一个为止.但是,不能在列之间随机移动纸牌.必须按降序(从 K 到 A)构建列.因此,您可以在 J 上而不能在 3 上放 10. ...

  3. 不会玩游戏的程序员不是好作家,《深入理解Java虚拟机》周志明来了!

    嘉宾:周志明.杨福川 采访.撰文:Satoh_AI 这次采访起源来自于我和豆瓣的一位读者有同样的好奇心,为什么网上搜不到周志明老师的更多信息?为什么"80后玩家"可以把本本书都维持 ...

  4. UE3 供游戏性程序员的使用的性能最优化方法

    供游戏性程序员的使用的性能最优化方法 概述 广泛性能调查 游戏和渲染性能 游戏线程分析 渲染线程分析 常见性能问题 概述 为追踪虚幻3游戏的内容或特定的游戏表现,有一系列有帮助的工具. 一个被用于 I ...

  5. 游戏是程序员的深坑?

    作者 | 我不想种地 责编 | 胡巍巍 笔者曾在游戏行业摸爬滚打八载有余,自孤身一人翩翩少年,至拖家带口大腹便便,一事无成,两手空空. 昨日惊闻全程参与研发四年之久的saint关服停运,回忆起那些加班 ...

  6. 专访王博,国内资深游戏3D角色美术大神

    王博简介 原Massive Black (Shang Hai) 3Dartist, 原网龙U3美术组资深角色设计师,原金山西山居成都研发中心3D角色指导, 现就职于腾讯游戏天美工作室. 曾参与制作&l ...

  7. 成为游戏开发程序员,要学些什么

    一.游戏程序开发的工作主要包括哪些方面 游戏开发中的程序开发主要由如下几个方面组成:  1.图形引擎  2.声音引擎  3.物理引擎  4.游戏引擎  5.人工智能或游戏逻辑  6.游戏GUI界面(菜 ...

  8. 如何成为一名游戏开发程序员

    一.游戏程序开发的工作主要包括哪些方面 游戏开发中的程序开发主要由如下几个方面组成: 1.图形引擎 2.声音引擎 3.物理引擎 4.游戏引擎 5.人工智能或游戏逻辑 6.游戏GUI界面(菜单) 7.游 ...

  9. 不要困在自己建造的盒子里――写给.net程序员

    不要困在自己建造的盒子里――写给.net程序员 2011年02月26日 此文章的主旨是希望过于专注.NET程序员在做好工作.写好.NET程序的同时,能分拨出一点时间接触一下.NET之外的东西(例如10 ...

最新文章

  1. Spark技术栈有哪些组件,每个组件都有什么功能,适合什么应用场景?
  2. 解决编译twrp3.0.3遇到的问题
  3. JavaFX即将推出您附近的Android或iOS设备吗?
  4. 【TensorFlow】TensorFlow函数精讲之tf.nn.conv2d()
  5. JS中,如何判断一个被转换的数是否是NaN
  6. 物体非等比缩放后的法线处理
  7. 蜗牛学习正则表达式 教程 工具一网打尽
  8. MyBatis--动态插入多条数据
  9. HTML 基础和实例
  10. 电脑qq游戏程序更改计算机,电脑怎么把qq游戏快捷到桌面
  11. N76E003 驱动 UC1705并口屏(8080)
  12. JS实现星星评分系统
  13. STM32驱动AD7366-5/AD7367-5芯片
  14. srand和rand函数使用
  15. 【云贝学院】揭秘TDSQL分布式实例扩容的逻辑流程
  16. mysql score表_MySQL连表查询练习题
  17. 《云计算服务安全能力要求》与《云计算服务安全指南》标准
  18. 【ARC101E】Ribbons on Tree(树形DP,容斥原理)
  19. Rootkit 真刀真枪的权限保卫战
  20. 自己开发的一个抢票软件客户端

热门文章

  1. 正则表达式中的非捕获组是什么?
  2. JavaScript数据类型
  3. 你知道数据中心宕机的真正成本吗?
  4. c语言中fflush的运用为什么没有效果呢,测试平台linux
  5. 3116 高精度练习之加法
  6. hadoop : hdfs的心跳时间设置及心跳检测算法
  7. 学习搭建Hadoop+HBase+ZooKeeper分布式集群环境
  8. 谈谈Ext JS的组件——布局的使用方法续一
  9. VirtualBox快照(Snapshot)功能使用及注意事项
  10. Lambda表达式【转】