Chinaunix首页 | 论坛 | 博客
  • 博客访问: 614105
  • 博文数量: 105
  • 博客积分: 5389
  • 博客等级: 准将
  • 技术积分: 1290
  • 用 户 组: 普通用户
  • 注册时间: 2008-02-29 11:13
文章分类

全部博文(105)

文章存档

2010年(23)

2009年(20)

2008年(62)

分类: LINUX

2008-05-10 13:12:19

一 导言

有这么一段bufbomb.c代码,进行实验:

[root@loaclhost buf_bomb]# gcc-o bufbomb.c
[root@loaclhost buf_bomb]# ./a.out
11111111111
11111111111
Segmentation 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.out
11111111111
11111111111
Segmentation 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   
阅读(3878) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~