一 导言
有这么一段bufbomb.c代码,进行实验:[root@loaclhost buf_bomb]# gcc-o bufbomb.c[root@loaclhost buf_bomb]# ./a.out1111111111111111111111Segmentation fault[root@loaclhost buf_bomb]#本文详细记录了Segmentation fault产生的过程并详细地分析了其产生的原因:1、缓冲区怎么溢出的,溢出到了哪里?2、溢出的缓冲区改变了程序中的那些寄存器、数据、结构?3、在哪里,改变的是谁的数据,其带来的错误会是在什么情况下爆发?4、溢出带来的这些错误,又是是怎么使得程序运行最终崩溃的?
二 实验代码
为避免繁杂的代码对分析产生影响,将代码附于本文最后。
三 分析
我直接给出main对getline调用、而getline再对gets调用的栈帧图。
我们可以看到,调用者与被调用者的组织结构是严格嵌套的,按调用的一条线下来,我们可以完整地画出所有过程的堆栈结构。无论getline与gets之间传送的只是buf值,也就是内容的指针,对buf的溢出写,只会影响到buf实际所指的空间。而buf实际上是在getline中作为模块内部数组分配的,理应位于getline模块的局部栈内,如图所示,也表示出了这一点。所以无论怎么破坏,也不会破坏被调用者的堆栈结构。
实际的过程中,我们对bug进行getchar时,写到了地址0xbffff8b0起始的内存位置处。从图中可以看到,模块为buf分配了8bytes的空间,而这个空间之后紧接着的就是为main保存的栈帧值,以及main调用getline模块的返回地址。于是,我们可以猜测,当写溢出之后,main的%ebp值将首先被改变,ret值也很可能随之改变。
例如,我们输入“
11111111111”,可以看到我们main和getline的帧栈被破坏后的样子:
此时,仅main的%ebp值被破坏,程序仍能正常返回,于是会出现导言中的结果:[root@loaclhost buf_bomb]# ./a.out1111111111111111111111Segmentation fault[root@loaclhost buf_bomb]#
若是输入12个1,则main函数则不能继续进行打印操作,程序直接死在getline的ret指令中:
[root@loaclhost buf_bomb]# ./a.out
111111111111
Segmentation fault
[root@loaclhost buf_bomb]#
四 结论
1、缓冲区怎么溢出的,溢出到了哪里?
缓冲区溢出主要是由于对有限内存进行无约束的写操作而产生的。对于定长内存块的操作,一定要注意其长度。
对于溢出到了哪里,我们分析的时候可以跳过实际做写操作的模块,只用关心这片内存实际是由谁,以那种形式分配的。
2、溢出的缓冲区改变了程序中的那些寄存器、数据、结构?
在这一例中,对调用者的%ebp,甚至返回地址都产生了直接的威胁。改变%ebp的值,getline仍可正常返回,但是main函数就不能正常返回到其调用者了;至于要是改变了返回地址,则getline执行完毕之后,欲返回的地方完全是未知的,什么情况都可能发生。
3、在哪里,改变的是谁的数据,其带来的错误会是在什么情况下爆发? 我们可以认为,是在被调用者的模块中,把调用者的数据给改变了。而产生这样的错误所在,并不处在这两个模块中,而在gets模块中。只是说他们相互作用埋下了隐患。
4、溢出带来的这些错误,又是是怎么使得程序运行最终崩溃的?
%ebp、ret控制了代码严格有序地进行,对他们的破坏,当然是致命的。
附 代码/* buffer_overflow.c */#include"stdio.h"
char *gets(char *s)
{
int c;
char *dest = s;
while ((c = getchar()) != '\n' && c !=EOF)
*dest++ = c;
*dest++ = '\0'; /* Terminate String */
if (c == EOF)
return NULL;
return s;
}
char *getline()
{
char buf[8];
char *result;
gets(buf);
result = (char*)malloc(strlen(buf));
strcpy(result, buf);
return(result);
}
main()
{
printf("%s\n", getline());
}
使用objdump -d a.out得出的反汇编代码,摘其要点如下:
a.out: file format elf32-i386
08048434 :
8048434: 55 push %ebp
8048435: 89 e5 mov %esp,%ebp
8048437: 83 ec 18 sub $0x18,%esp
804843a: 8b 45 08 mov 0x8(%ebp),%eax
804843d: 89 45 f8 mov %eax,0xfffffff8(%ebp)
8048440: e8 df fe ff ff call 8048324 <_init+0x28>
8048445: 89 45 fc mov %eax,0xfffffffc(%ebp)
8048448: 83 7d fc 0a cmpl $0xa,0xfffffffc(%ebp)
804844c: 74 19 je 8048467
804844e: 83 7d fc ff cmpl $0xffffffff,0xfffffffc(%ebp)
8048452: 75 02 jne 8048456
8048454: eb 11 jmp 8048467
8048456: 8b 45 f8 mov 0xfffffff8(%ebp),%eax
8048459: 89 c2 mov %eax,%edx
804845b: 8a 45 fc mov 0xfffffffc(%ebp),%al
804845e: 88 02 mov %al,(%edx)
8048460: 8d 45 f8 lea 0xfffffff8(%ebp),%eax
8048463: ff 00 incl (%eax)
8048465: eb d9 jmp 8048440
8048467: 8b 45 f8 mov 0xfffffff8(%ebp),%eax
804846a: c6 00 00 movb $0x0,(%eax)
804846d: 8d 45 f8 lea 0xfffffff8(%ebp),%eax
8048470: ff 00 incl (%eax)
8048472: 83 7d fc ff cmpl $0xffffffff,0xfffffffc(%ebp)
8048476: 75 09 jne 8048481
8048478: c7 45 f4 00 00 00 00 movl $0x0,0xfffffff4(%ebp)
804847f: eb 06 jmp 8048487
8048481: 8b 45 08 mov 0x8(%ebp),%eax
8048484: 89 45 f4 mov %eax,0xfffffff4(%ebp)
8048487: 8b 45 f4 mov 0xfffffff4(%ebp),%eax
804848a: c9 leave
804848b: c3 ret
0804848c :
804848c: 55 push %ebp
804848d: 89 e5 mov %esp,%ebp
804848f: 83 ec 18 sub $0x18,%esp
8048492: 83 ec 0c sub $0xc,%esp
8048495: 8d 45 f8 lea 0xfffffff8(%ebp),%eax
8048498: 50 push %eax
8048499: e8 96 ff ff ff call 8048434
804849e: 83 c4 10 add $0x10,%esp
80484a1: 83 ec 0c sub $0xc,%esp
80484a4: 8d 45 f8 lea 0xfffffff8(%ebp),%eax
80484a7: 50 push %eax
80484a8: e8 97 fe ff ff call 8048344 <_init+0x48>
80484ad: 83 c4 04 add $0x4,%esp
80484b0: 50 push %eax
80484b1: e8 7e fe ff ff call 8048334 <_init+0x38>
80484b6: 83 c4 10 add $0x10,%esp
80484b9: 89 45 f4 mov %eax,0xfffffff4(%ebp)
80484bc: 83 ec 08 sub $0x8,%esp
80484bf: 8d 45 f8 lea 0xfffffff8(%ebp),%eax
80484c2: 50 push %eax
80484c3: ff 75 f4 pushl 0xfffffff4(%ebp)
80484c6: e8 a9 fe ff ff call 8048374 <_init+0x78>
80484cb: 83 c4 10 add $0x10,%esp
80484ce: 8b 45 f4 mov 0xfffffff4(%ebp),%eax
80484d1: c9 leave
80484d2: c3 ret
080484d3 :
80484d3: 55 push %ebp
80484d4: 89 e5 mov %esp,%ebp
80484d6: 83 ec 08 sub $0x8,%esp
80484d9: 83 e4 f0 and $0xfffffff0,%esp
80484dc: b8 00 00 00 00 mov $0x0,%eax
80484e1: 29 c4 sub %eax,%esp
80484e3: 83 ec 08 sub $0x8,%esp
80484e6: 83 ec 08 sub $0x8,%esp
80484e9: e8 9e ff ff ff call 804848c
80484ee: 83 c4 08 add $0x8,%esp
80484f1: 50 push %eax
80484f2: 68 b0 85 04 08 push $0x80485b0
80484f7: e8 68 fe ff ff call 8048364 <_init+0x68>
80484fc: 83 c4 10 add $0x10,%esp
80484ff: c9 leave
8048500: c3 ret
8048501: 90 nop
8048502: 90 nop
8048503: 90 nop
阅读(4123) | 评论(0) | 转发(0) |