时间倒回到2011年5月的一天,大学的最后一门课《计算机信息安全技术》,讲到《缓冲区溢出》这一章,并且给出了一段示例代码来演示缓冲区溢出,回到宿舍后出于好奇我运行了一下这段代码,发现结果并不是书上所说的那样,当时在人人网也发过一篇吐槽的日志,但是一直拖到现在都没有仔细的去研究过,正好现在十一放假没事,就花点时间搞搞啦。

书第136页-137页。代码如下,出于简单考虑(其实书上的C++代码格式也是错的),我除去了头文件和cout函数,这样就跟纯C语言代码是一样了。

01 void function(int a)
02 {
03     char buffer[5];
04     char *ret;
05     ret=buffer+12;
06     *ret+=8;
07 }
08 int main()
09 {
10     int x;
11     x=10;
12     function(7);
13     x=1;
14     return 0;
15 }

书上说最后x的值是10,不是1,而我的结果恰恰相反。

接着用gcc产生汇编代码,在这里用 gcc -O0 -S 命令告诉编译器不采用任何优化措施,产生最原始的汇编代码,这样有利于我们分析,即使是采用-O1级优化的时候,汇编代码已经很难读了,大家可以试一试。

01 function:
02     pushl %ebp
03     movl %esp, %ebp
04     subl $16, %esp
05     leal -9(%ebp), %eax
06     addl $12, %eax
07     movl %eax, -4(%ebp)
08     movl -4(%ebp), %eax
09     movzbl (%eax), %eax
10     addl $8, %eax
11     movl %eax, %edx
12     movl -4(%ebp), %eax
13     movb %dl, (%eax)
14     leave
15 
16 main:
17     pushl %ebp
18     movl %esp, %ebp
19     subl $20, %esp
20     movl $10, -4(%ebp)
21     movl $7, (%esp)
22     call function
23     movl $1, -4(%ebp)
24     leave
25     ret

书上详细的解释了为什么结果是10,下面我来逐条分析。首先画一张内存图,同样处于简洁考虑,只画function函数附近的内存分布,不影响分析。

1、书上说:“为char buffer[5]分配内存时,由于32位存储器需要4字节对齐,因此一共为buffer分配了8个字节”。

由 leal -9(%ebp), %eax 代码可以看出,编译器实际上没有为buffer分配8个字节,而是只分配了5个字节,还有4个字节给了 char *ret,因此正好是9个字节,见图中0xEB – 0xE3部分。

2、书上说:“执行 ret=buffer+12后,ret指向返回地址”
实际上,从图上看出加12后指向的是%ebp的最高字节0xEF。

3、书上说:“执行 ret+=8后,返回地址的值加上了8个字节,而x=1这条语句占有8个字节,因此正好跳过,执行下一条语句 cout<<x ”。

实际上是把%ebp=0x00000108 的最高有效位 0x00加8了,因此运行时会产生“段错误”(是这个原因吗?求指教)

因此,书上长篇大论的分析在我的机器上是行不通的,不过还要注意2点:

1、现代的编译器通常都引入了“栈随机化”、“破坏检测”等多种手段来阻止缓冲区溢出的攻击,像书中所说的那样通过把某个指针+8,程序就从某条特定语句开始执行并不是那么简单就能实现的。

2、即使是相同的OS和gcc版本,在不同的CPU上生成的汇编代码是不一样的,运行的结果也不一样。例如,Core i5和 奔腾双核,在Core i5上运行结果是1,甚至都不会产生“Segmentation fault”的错误,而在奔腾CPU上结果为1,产生“段错误”提示。

总之,书上的代码也许在某个特定的、老版本的编译器环境下会发生,但是结果是不可重复的,而且,在不同机器上也会表现出不同结果。

最后,这篇文章的分析过程是我根据实际运行结果结合汇编代码猜测出来的,我对这方面也不是很懂,所以,如果哪位读者看出了其中有什么错误,非常诚恳的欢迎你指出,我也很想知道错误的原因,Thanks~

Tags: ,. 9,880 views
Home

13 Comments so far

Trackbacks/Pingbacks

Leave a comment

Name(required)
Mail (required),(will not be published)
Website(recommended)

Fields in bold are required. Email addresses are never published or distributed.

Some HTML code is allowed:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>
URLs must be fully qualified (eg: http://blog.nlogn.cn),and all tags must be properly closed.

Line breaks and paragraphs are automatically converted.

Please keep comments relevant. Off-topic, offensive or inappropriate comments may be edited or removed.