太阳快落山了!快看看夕阳吧!

编程开发

程序员最恐怖的梦魇是什么?

2015年12月08日 12:03:56 · 本文共 1,948 字阅读时间约 7分钟 · 4,188 次浏览
程序员最恐怖的梦魇是什么?

这是Quora上的一个问题,其中Mick的回答获得了13.5k“赞同”,他如此回忆道:

曾经有位心理学的博士雇我查一个BUG,程序是他的一个学生写的,经常会出现奇怪的输出。程序的功能是,从文件中读取数据,提出50个问题,进行一系列计算,然后基于这位博士的研究来得出一个分数。程序跑在大学的一台3B2上。他给我演示了程序,确认这个Bug可以重现——每次在问题之间切换的时候,总会闪出一些奇怪的字符。我觉得这应该很简单,所以答应了他,并且我们同意按小时付费。

Day1

我来到这台3B2面前,用那个学生的帐号登录,找到了用C写的源代码,并开始测试。代码可读性非常差,所有的代码都写在了一行,变量名都是三个字母,而且还是随机组合的!真庆幸我当初选择按小时收费。我把代码格式化为习惯的风格,这样看起来多少还能读。

做完之后,我用curses库移到屏幕上一个点,打印一个问题和答案,然后等待回应。但是在打印出第一行之后,出现了一些乱码,过了大约1/2秒之后,乱码被问题覆盖掉。这个问题应该很容易解决,只有五个地方需要打印信息,所有的地方都出现了一闪而过的乱码。小意思,只要删掉mvpwintw()应该就ok了。我删掉之后开始编译,觉得问题差不多解决了。但是运行的时候,干扰信息又出现了!只是乱码变了,但是症状还是一样!

我检查了一下代码,发现竟然回到了我改之前的样子!15个文件,混乱的格式,三个字母的变量。当初为什么不备份一下代码呢,真想射自己一枪。我再一次格式化它们,这次把代码放到三个文件中,以不同的名字命名。然后备份了整个文件夹,并且将权限设置为只读。编译之后,一切正常。一运行,这个文件夹中又出现了15个文件!我改过之后的源代码没有被删除,然后干扰信息又回来了。

我明白了,这一定是在硬盘的某个地方的代码,在编译的时候会将程序添加到我修改的代码中去。所以我准备搜索一下include区域(/usr/include),因为我们用的是研究的版本,所以除了kernel别的代码都在机器上。头文件太多了,所以在3B2上搜索需要花一些时间。以上,就是第一天的工作了。

Day2

从磁盘的搜索中没有得到什么结果,这说明这些乱码要么是被加密了,要么就是在lib中的某个地方。但是我没有搜到,我决定搜索所有的文本文件,这次花的时间比昨天更长,第二天就这这样过去了。

Day3

没有结果。字符串是加密的。我只好根据所有的头文件来一点一点查了。这会花费相当多的时间,我们同时还警告了学校,可能有人得到了Phelps博士计算机的root权限。但他们却对此并不关心,可能只是一台实验室的计算机吧。

我打开#include文件,却没有发现代码。后来发现这些都被编译成一个文件了。也没什么关系,毕竟我们有源代码,大不了就重新编译所有的库。

Days4-6

接下来是最难的部分了,我们好不容易向学校的书呆子说明了问题。然后让Mark(我觉得他能做Unix管理员完全是因为娶了Dean的女儿)开始学习编译。最后他终于同意交给我来做,因为他什么都不会。在第6天最后,编译工作终于完成了。

我拿出修改之后的代码,重新开始编译。一切正常,然后我运行了一下,天呐!这问题又出现了。源代码分成了15个文件,干扰信息又出来了。简直跟魔法一样,我觉得自己被打败了,问题肯定不在源代码里。Phelps博士也有点不乐意了,他觉得这么长时间,即使重新写一个也该完成了。“当然”,我失落地说,“你是对的,说不定重写比较好。”“好的,我们明天开始重写。”博士说。

Day7

见鬼去吧,我不会认输的!我跟Phelps博士说:“你不用付给我钱了,只要给我时间,我一定要找到这个bug。”

Days8-14

我学聪明了,他一定是修改了一些库,我开始研究编译出来的汇编(虽然我之前根本就不懂汇编),从开始学习,到最后看懂汇编代码,花了六天。虽然根本没发现什么异常,完全就是在浪费时间。

Day 15

突然,我意识到,问题可能出在编译器上,一定是。每次编译代码的时候,编译器就会往源代码中添加干扰信息。我以前也听说过这种情况。

啊耶!我找到了!我们也有编译器的源代码,我查了一下,谢天谢地,终于找到了。编译器链接器中的代码是这样的:

1)检测所有对fopen()的调用,在打开的文件中查找Phelps博士的问题,如果找到 2)编译的时候,重写15个文件 3)使用这15个文件编译博士的程序,在链接的时候会输出-o形式的名字

编译器被这个学生修改了,以便往Phelps博士的程序中添加代码。

几天之后,AT&T的技术支持提供了原版的编译器和链接器代码,我们重新编译,替换了被修改的编译器和链接器。

但是,问题还没有解决。编译器被其他我们没有的源代码污染了。这些代码存在于现在可执行的编译器中,在编译编译器的时候,会加入污染代码。但是它并不修改/usr/src中的代码,而是将其复制到一个隐藏文件夹,修改编译器源代码,编译,最后删除隐藏文件夹。AT&T发现这个问题花了好长时间。这个学生修改了编译器,让编译器重新编译的时候加入污染代码。最后我们不得不从另一台3B2机器上复制过来编译器的字节码文件版本,才终于解决这个问题。

通过编译器的代码我们还发现,如果编译/sbin/login的话会加入一些后门代码,可以允许任何人使用特定的密码来登入root。这台电脑可以通过调制解调器或Tymnet接入。终于,这件事引起了校方注意。

这人真是个天才,不过,也太恐怖了!

商业用途请联系作者获得授权。
版权声明:本文为博主「任霏」原创文章,遵循 CC BY-NC-SA 4.0 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.renfei.net/posts/1003251
评论与留言

以下内容均由网友提交发布,版权与真实性无法查证,请自行辨别。

微信搜一搜:任霏博客