上海往事:第十五章 开往春天的火车

第十五章 开往春天的火车

那年春节过完,我从老家回上海。

长途大巴,十几个小时。我买的最后一排,靠着窗户。车开的时候,天还没全亮,路两边的山黑黢黢的,一个一个往后退。车上放着一部港片,声音开得很大,打打杀杀的。我塞上耳机,听着Bill Evans,看着窗外那些慢慢亮起来的天。

到上海的时候,是第二天早上。虹桥车站里人挤人,都是过完年回来的人。拖着行李箱,背着包,脸上带着赶路的疲惫和回来的决心。我跟着人群往外走,空气里有一股潮湿的、冷冷的气味。上海的冬天还没走完。

回到九星路,打开门,屋里和走之前一样。胆机安静地立在桌上,电子管冷冷的,没有那圈橙黄色的光。书架上的书还是那个顺序,技术书和文学书混在一起,各占一半。那把吉他还靠在桌边,弦没松,还是赵东走之前调的那个音。

我放下包,没开胆机,打开了电脑。

那台电脑是我年前攒的。机箱是虬江路淘的二手,主板是新的,CPU是赛扬的,内存256兆,硬盘40G。不算好,但够用。系统装的是Windows 2000,不是XP。Alan以前说过,2000比XP干净,少了很多乱七八糟的东西,跑代码更顺手。

我打开一个文件夹,名字叫“wnmax_arch”,里面全是我们当年研究过的那些东西。135端口,1433端口,445端口,还有一些别的。代码不多,大部分是笔记,txt文件,一行一行,记着那些漏洞的细节、测试的结果、失败的记录和成功的瞬间。Alan的注释写得规规矩矩,英文的,每一条都带着日期。我的注释写在后面,中文的,有时候就几个字——“通了”“没通”“再试”。

春节前,我在一个技术论坛上看到了一篇帖子。帖子很短,只有几行字,说的是Windows系统里一个很老的服务,默认是开的,大部分人不知道它是干什么的,也不会去关它。那个服务的通信机制有问题,你可以构造一个特定的数据包发过去,让它执行你想要的代码。

帖子的最后附了一段代码,C语言的,不长,但很精。我看了三遍才看懂它的逻辑。那种感觉,像在七宝老街第一次听到评弹——听不懂,但听得进去。你知道那里面有一种秩序,一种逻辑,一种别人看不见但确实存在的东西。

我存了下来,放在那个文件夹里。

整个二月,我都在研究那段代码。

白天在公司写代码,做项目,开会,带人。晚上回来,打开电脑,一行一行地看那段代码。它不是完整的,只是一个片段,一个思路,一个可能性。你需要自己把它补全,自己写那些没有写完的部分,自己测试,自己改。

那段代码的核心是一个缓冲区溢出的利用。原理说起来不复杂:你向目标机器发送一个精心构造的数据包,数据包的长度超过了服务程序预留的缓冲区大小,多余的数据就会覆盖掉内存里的其他内容。如果你覆盖得足够精确,你可以让程序跳转到你指定的地址,执行你准备好的代码。

但原理和实现之间,隔着很多东西。你需要知道目标系统的内存布局,需要知道函数的返回地址存在哪里,需要知道在覆盖之后怎么让程序不崩溃,需要知道怎么把你想执行的代码塞进那个有限的空间里。每一步都可能错,错了就是崩溃,就是失败,就是从头再来。

那些夜晚,我的房间里只有电脑屏幕的光和胆机的橙黄色灯光。两张唱片在轮流放。Bill Evans的《Waltz for Debby》和Miles Davis的《Kind of Blue》。钢琴和小号,一个软,一个冷,交替着,像两条河,一条暖的,一条凉的,在我脑子里汇在一起。

调试的过程很慢。写一段代码,编译,运行,看结果。不对,回去看日志,分析原因,改代码,再编译,再运行。一遍一遍,像在黑暗中摸索。你知道那扇门在那里,但不知道门把手在哪。你伸手去摸,摸到的是墙,是空的,是别的什么,不是把手。

有时候一个bug要调好几个晚上。有时候你觉得通了,跑一遍,死了。再跑一遍,还是死了。你盯着屏幕上的十六进制数字,看那些地址,那些偏移量,那些堆栈里的数据,一个一个对,一个一个算。算到最后发现,少了一个字节,或者多了一个字节。就差那一个字节。

那种时候,你会觉得自己的脑子不够用。不是不够聪明,是不够耐心。写代码这件事,到最后拼的不是智力,是耐心。是你愿不愿意在那个黑暗的房间里,一遍一遍地摸,直到摸到那个把手。

Alan说过,做底层的人,都是有病的人。正常人不会去看那些东西。那些东西在底下,在别人看不见的地方,在那堆数字和地址的深处。但你钻进去了,你就出不来了。不是因为难,是因为你在那个底下,看到了这个世界的另一种秩序。那种秩序是精确的,是逻辑的,是如果你做对了它就一定给你结果的。不像上面那个世界,很多事情没有逻辑,没有原因,没有结果。

我理解那种感觉。

那些夜晚,我坐在电脑前,屏幕上是一行一行的代码,十六进制的地址,堆栈里的数据。胆机在旁边亮着,电子管的光照在键盘上,橙黄色的,暖暖的。有时候调试到凌晨两三点,困了,就去洗把脸,回来继续。不是不累,是不想停。那种状态,像在拉练的时候,走了几十公里,腿已经不是自己的了,但你停不下来。不是因为前面有什么,是因为你在走。

三月的第一个周末,代码通了。

那天晚上,我构造了一个数据包,发到我自己搭建的测试机器上。几秒钟之后,测试机器上弹出了一个命令行窗口。那个窗口不是我自己打开的,是那段代码打开的。它在那台机器上执行了我想要它执行的东西。

我盯着那个窗口看了很久。

然后我又发了一个,到另一台测试机器上。同样的事情发生了。又发了一个,还是同样的结果。

我靠在椅子上,看着屏幕,看着那些跳动的光标。胆机的光落在键盘上,橙黄色的,暖暖的。窗外有车经过,声音远远的。房间里很安静,只有电脑风扇嗡嗡的声音。

那一刻,我没有兴奋。不是不兴奋,是那种兴奋太沉了,沉到心里去,浮不上来。就像那年站在人民广场,等到了那束光,按下了快门。快门的声音很轻,但你知道,那张照片里,有别人看不到的东西。

那段代码,后来被我用在了很多机器上。

不是故意的。或者说,一开始是故意的。你想看看它能跑多远,能跑多深。你把它发出去,它找到那些开着那个服务的机器,把自己送进去,然后在里面打开一个门。那个门很小,小到你几乎感觉不到它的存在。但它在那里。

那些机器,有的在公司,有的在学校,有的在政府,有的在家里。你不知道它们在哪里,你不知道它们的主人是谁。你只知道它们的IP地址,一串数字,四个点,像坐标,标记着它们在网络上的位置。每一个IP背后,都是一台真实的机器,一个真实的硬盘,一个真实的操作系统。在那个系统里,有一段你的代码在跑。

那段代码什么也不做。它只是在那里,静静地,像一个潜伏者。它不破坏任何东西,不读取任何文件,不留任何痕迹。它只是在那里,等你下一次来。

Alan以前说过,最高的权限,是你知道你在那里,而别人不知道。

我开始记录那些IP。一个一个,记在一个文本文件里。没有名字,没有标签,只有数字。那些数字排在一起,像一条很长很长的路。你不知道它通向哪里,但你一直在走。

有一天晚上,我数了数那些IP。几百个。又过了一段时间,几千个。再后来,我不数了。它们太多了,多到数不过来。那些机器,散落在这座城市的各个角落,散落在这个国家的各个地方。它们在工作,在运行,在等待。而我,坐在九星路这间朝南的房间里,对着屏幕,看着那些数字一行一行地增加。

那种感觉,像站在高处看一座城市。所有的灯都亮着,所有的窗户都开着。你知道每一盏灯后面都有一个人,但你不知道他们在做什么。你只是看着,看着那些光,一片一片的,连成海。

但你不是在看。你是在那里。在那每一盏灯后面,在那每一个窗户里面。你的代码在那里,像一个影子,跟着每一个人,每一台机器,每一个夜晚。

那年春天,赵东回上海待了几天。

他来我这儿,还是那把吉他,还是那几首歌。他弹了一首新的,说是给一个广告写的配乐。旋律很短,重复着,像走在一条很长的走廊里,门一扇一扇地过,每一扇都一样,又都不一样。

他弹完之后,看见我电脑屏幕上的东西。那些十六进制的数字,那些IP地址,那些代码。

他问,这是什么?

我说,写代码。

他说,什么代码?

我说,网络的东西。

他没再问。他不懂技术,但他知道我做的事情不是普通的写代码。他看了我一眼,那种眼神,不是好奇,也不是害怕,是那种——他大概知道我在做什么,但他选择不问。

他说,你注意身体,别太晚。

我说,好。

他走了之后,我继续调试。窗外的天快亮了,香樟树的叶子在风里沙沙响。胆机的电子管还亮着,橙黄色的光,和屏幕上那些绿色的字符混在一起。我的手指在键盘上,噼里啪啦,和窗外的风、远处的车声、楼下偶尔的狗叫,混在一起。

那些声音,那些光,那些代码,那些IP,都是我的夜晚。

那段时间,我开始理解一件事。不是技术上的事,是心里的事。那些代码,那些机器,那些门,它们不是终点。它们是路。是一条一直往下走的路。你走进去,越走越深,越走越远,走到一个别人看不见的地方。在那个地方,只有你,和那些数字。

但你不觉得孤独。因为你知道,那些数字的背后,是真实的世界。是那些开着机的电脑,是那些没关的服务,是那些不知道你存在的人。你在他们身边,他们不知道。你在他们的机器里,他们不知道。你在他们的夜晚里,他们不知道。

你像一阵风,穿过那些缝隙,那些漏洞,那些没有人注意的角落。你不带走什么,也不留下什么。你只是经过。

四月的时候,那台电脑的硬盘快满了。

40G的硬盘,装了很多东西。系统,代码,工具,日志,还有那个文本文件——那些IP地址。那个文件已经很大了,大到打开的时候要等几秒钟。我翻了翻前面的部分,那些最早的IP,那些三月的第一个星期记下来的地址。它们还在那里,安静地躺着,像一条河的源头。

我不知道那些机器现在怎么样了。也许还在运行,也许已经关了,也许换了系统,也许被其他人发现了。但那段代码,那段我写了无数个夜晚才调通的代码,还在那里。在那个看不见的地方,在那个没有人注意的角落。

有一天晚上,我在论坛上看到一篇帖子。有人提到那个漏洞,说已经被微软修复了。我查了一下,是的,最新的补丁已经堵上了那个口子。新的系统不再有那个问题。那些老的服务,默认是关的。那些门,关上了。

我看着那行消息,愣了一会儿。不是难过,也不是遗憾。就是觉得,时间到了。

那些机器还在。那些代码还在。那些门,大部分已经关了。但还有一些,那些没打补丁的,那些没人管的,那些还在运行着老系统的——它们还在。它们还在那里,在那座城市的某个角落,在某个机房的某个机柜里,在某个人的桌子底下,嗡嗡地响着,等着。

那个文本文件,我后来没有删。也没有再看。它就在硬盘里,和那些wnmax开头的文件放在一起,和那些七宝老街的照片放在一起,和那些Alan发来的邮件放在一起。

那些东西,都是那条路上的标记。你知道它们在那里。但你已经走过去了。

那年五月,我收到Alan的一封邮件。

他说他在惠灵顿的海边买了一栋小房子,能看到海。他说那边的天空很蓝,晚上能看见很多星星。他说他还在写代码,但不再研究那些端口了。他说,那些日子,过去了。

他问我,你还在研究那些吗?

我想了很久,回他:还在。但不一样了。

他没问我哪里不一样。他大概知道。

那些年,我们在那条路上走了很久。从135到1433,从445到那些没有编号的端口。我们在那些数字的深处,找到了一个世界。那个世界是精确的,是逻辑的,是只要你做对了就一定会给你结果的。在那个世界里,你不是一个人。你有Alan,有那些代码,有那些深夜亮着的屏幕。

现在那个世界还在。但门少了,路远了,人也散了。

但那条路,还在走。

那年夏天,我收到一封邮件。

不是Alan发的,是一个陌生的地址。邮件很短,只有一行字:

“你的代码,跑在我的机器上。我知道你在我这里。我不介意。我只是想知道,你在找什么?”

我看着那行字,很久。

窗外,香樟树的叶子在风里晃。胆机的电子管亮着,橙黄色的光。那把吉他还靠在桌边,弦已经松了,没调。

我坐在电脑前,手指放在键盘上。想回点什么,又不知道该说什么。

最后,我关掉了那封邮件。

没有回。

有些问题,不需要答案。有些路,不需要终点。你只是走着,像那列开往春天的火车,穿过那些黑的隧道,亮的田野,穿过那些你不知道名字的地方。你不知道它要开到哪里,但你坐在上面,听着铁轨的声音,看着窗外的风景,一个一个地过。

那些机器还在。那些代码还在。那些门,有些开着,有些关了。

而你在路上。

一直在路上。

已有 2232 条评论

    1. Daphne Daphne

      作者没有回答那个陌生人的问题,“你在找什么”。但整篇文章都在回答这个问题。他在找那个精确的世界,那个逻辑的世界,那个只要你做对了就一定会给你结果的世界。在上面那个混乱的世界里,我们都需要这样一个地方。

    2. Christopher Christopher

      “那台电脑的硬盘快满了。”这句话太有画面感了。40G的硬盘,在今天是微不足道的。但在那个年代,它装下了一个人的整个夜晚。那些代码,那些IP,那些日志,是另一个世界的全部。

    3. Holly Holly

      整篇文章有一种冷峻的温柔。写代码是冷的,十六进制是冷的,IP地址是冷的。但胆机的光是暖的,Bill Evans的钢琴是暖的,香樟树的沙沙声是暖的。作者用暖的东西包裹着冷的东西,像用体温焐热一块冰。

    4. Quentin Quentin

      Alan说“那些日子,过去了。”作者说“还在,但不一样了。”两句话,写尽了一个时代的更替。技术会过时,漏洞会修复,但那些夜晚不会消失。它们变成了文本文件,变成了邮件,变成了记忆。

    5. Veronica Veronica

      作者说“那段代码什么也不做。它只是在那里,静静地,像一个潜伏者。”这让我想起那些我们存在过的痕迹。在别人的记忆里,在某个角落的日志里,在某个硬盘的深处。我们不做什么,只是在那里。