[作者:豆瓣网友laoar,博客laoar's complaints。经作者同意转发,原文在此,豆瓣地址在此。]

对于苦逼的IT男而言,对下面这个场景应该感到亲切。发出去的软件版本出现了bug,事情很紧急,于是大佬召集所谓一堆专家头脑风暴寻求解bug的思路,各路专家你一言我一语各抒己见,最终在众人齐心协力下,终于在最后关头定位出了根因。没有解不了的bug,只有不努力的coder。

然而这个世界上还有另外一种人,他们也是解bug,只不过是找别人软件中的bug,他们通常被我们称之为hacker。

同样是解bug,主动去找的就被称为黑客,被称作漏洞攻击,是人人都崇拜的行为艺术,就像街头弹吉他的青年歌手一样;而被动去定位的则被称为IT码农,被称作问题攻关,是人人都摇头的养家糊口,就像路边上拉二胡的老人一样。所以,不同的心态就会有不同的境界。凡事都要主动的好,这跟追女孩子是一个道理,美女身边有那么多人在追她,你不努力,美女怎么可能会想起你来哪?当然,你努力了,美女也未必会想起你来 :)

《捉虫日记》这本书的作者Tobias Klein就是那种可以被称之为hacker的人。作者热衷于找各个os的bug,这本书描述了作者找到的7个bug,他详细的记录了如何去寻找bug,以及如何利用这个bug,当然他也给出了每个bug的解决方案。像作者这种hacker,或者说geeker,应该会有twitter的,于是我翻墙搜了下,他的确开通了twitter,twitter账号是 @ tobiklein ,虽然作者是德国人,可是所发推文都是英文。可见,要想在twitter这个世界混的好,就得学会用英文,否则就只能在自己那个狭窄的母语圈来混了。而中文推特圈,则以狭隘、偏激而著称,至于原因,你懂的。Tobias Klein在10年3月31日发了一条推文“My new book just got released!”,指的就是这本书。至今为止Tobias Klein所发推文不多,从他的推文可以看出,他现在应该主要在研究iOS的bug。

下面是作者这本书里面7个例子的大致介绍。

作者讲的第一个例子是个典型的栈缓冲区溢出(stack overflow)的例子。下面是个简单的stackoverflow示例程序。

/*stackoverflow.c*/
void overflow(char *argc)
{
    char buff[8];
    strcpy(buff, argc);
}
int main(int argc, char *argv[])
{
    if(argc > 1){
        overflow(argv[1]);
    }
    return 0;
}

对于上面这个简单的程序,如果我们输入的数据长度大于8,就会发生栈缓冲区溢出。这里涉及的知识点有栈桢、数组。注意在linux下使用gcc来编译时要禁用gcc的堆栈保护才会stackoverflow,使用-fno-stack-protector编译选项。作者在twitter上也提到了几个stack overflow的bug,是iOS和MacOS的。看来栈缓冲区溢出这个bug太容易犯了,因为字符串操作函数strcpy()和strcat()很容易导致出错。这也是很多hacker热衷于寻找的一类bug。

作者讲的第二个例子是solaris内核中内核态和用户态接口的一个bug。作者一直喜欢寻找操作系统内核漏洞,所以就拿solaris来开刀了,为什么不选择linux kernel哪?linux使用的人多,影响又大,而solaris则日薄西山了。对于操作系统而言,内核/用户态接口是最容易产生漏洞的地方。这些接口主要是以下几种:

  1. ioctl
  2. syscall
  3. 文件系统网络协议栈
  4. 第三方ko注册的钩子

作者发现的一个bug是ioctl的bug。

作者讲的第三个例子是空指针的一个bug。对于空指针,我想起一些工作上的事。有些新手经常问如何简单的让linux内核panic,我告诉他们访问一个null指针就好了。过了会,他们给我说,访问空指针的结果是segment fault,不是panic。我只好无奈的再解释,要写个ko,在内核态往null地址写数据就panic了,用户态出错,最多进程被杀死,是不会导致系统崩溃的。

作者讲的第四个例子是浏览器ActiveX控件的一个bug。我对windows编程不太熟悉,此例不多言。

作者讲的第五个例子是windows驱动的bug。用作者自己的话说,他想看看能不能在非开源的系统(比如windows)上找到bug。作者还特意把枪口瞄向了杀毒软件,真是大水冲龙王庙,自家人不认自家人啊。最终作者还真找到了bug,并通知给了杀毒软件厂商,他们及时的做了修复。

第六个例子是MacOS的一个bug,看来作者是要通吃所有的操作系统啊。怪不得作者不找linux的麻烦,是嫌降低自己的身份啊!这个MacOS的bug依然是ioctl的bug,看来作者认定了所有os的ioctl都会有bug。

最后一个例子是作者寻找iPhoneOS的bug,好吧,你赢了,你是真正的内核hacker。我只是一个内核码农,还只略微懂点linux的。

虽然作者针对的是每个os的bug,但是这些bug都是最基础的编程问题。一招鲜吃遍天,只要你编程能力强,通吃所有的os只是你愿不愿意的问题。

至于这本书的翻译,张伸,他也有twitter账号(@loveisbug),他竟然也是个足球迷。看在他是足球迷的份上,好吧,这本书翻译的挺好的。

本来我是打算follow一下这位译者的,后来看到了它的一个推文,就不打算follow他了。他的推文是:“请教,a backtrace of all stack frames是什么意思?backtrace是函数调用栈吗?”。在这里回答译者一下:

一个函数调用可以称之为一个栈帧,backtrace就是栈帧的集合,也就是函数调用栈。而缓冲区溢出(stack overflow)利用的的基本原理就是栈帧。使用gdb的bt命令就能够看出当前函数的调用栈。