Linux中的缓冲区溢出失败?

时间:2010-12-25 00:57:05

标签: linux security assembly buffer-overflow

我有一个关于缓冲区溢出的问题,在这个程序中:

#include <stdio.h>
#include <string.h>


int main(int argc, char **argv) {

char buf[10];

if(argc < 2) return 1;

strcpy(buf, argv[1]);

printf("%s\n", buf);

return 0;
}

当我尝试让这个程序在内存中流动时:

[Barakat/at/System ~]$ gdb buff 
GNU gdb (GDB) Fedora (7.1-34.fc13)
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-redhat-linux-gnu".
For bug reporting instructions, please see:
<>...
Reading symbols from /home/Barakat/buff...(no debugging symbols found)...done.
(gdb) run AAAAAAAAAAAAAAAAAAAAAAAAAAAA
Starting program: /home/Barakat/buff AAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAA

Program received signal SIGSEGV, Segmentation fault.
0x08048434 in main ()
Missing separate debuginfos, use: debuginfo-install glibc-2.12.1-4.i686
(gdb) info registers 
eax            0x0    0
ecx            0xbcd4e0    12375264
edx            0xbce340    12378944
ebx            0xbccff4    12374004
esp            0xbffff26c    0xbffff26c
ebp            0x41414141    0x41414141
esi            0x0    0
edi            0x0    0
eip            0x8048434    0x8048434 <main+64>
eflags         0x210246    [ PF ZF IF RF ID ]
cs             0x73    115
ss             0x7b    123
ds             0x7b    123
es             0x7b    123
fs             0x0    0
gs             0x33    51
(gdb)

它应该是这样的:

**Program received signal SIGSEGV, Segmentation fault. 
0x41414141 in ?? ()**
(gdb) info registers 
eax 0x0 0 
ecx 0x1000 4096 
edx 0xd1c448 13747272 
ebx 0xd1aff4 13742068 
esp 0xbfffdcd0 0xbfffdcd0 
**ebp 0x41414141 0x41414141** 
esi 0x0 0 
edi 0xa38cc0 10718400 
[COLOR="Red"][B]eip 0x41414141 0x41414141 [/B][/COLOR]
eflags 0x210286 [ PF SF IF RF ID ] 
cs 0x73 115 
ss 0x7b 123 
ds 0x7b 123 
es 0x7b 123 
fs 0x0 0 
gs 0x33 51 
(gdb)

所以应该在EPI上写一个A(十六进制为41)但是没有发生

linux是否有办法保护自己免受缓冲区溢出的影响 这样缓冲区溢出失败了?或者我做错了什么?

2 个答案:

答案 0 :(得分:3)

您似乎期待在EIP中使用AAA ...以及随后的指令获取错误。

但该程序似乎实际失败(1),试图加载AAA ... 作为数据。

实际上,我的猜测是,它从损坏的堆栈“恢复”了EBP,然后尝试加载AAA ... +(小偏移)以恢复其他一些寄存器。

给了你segfault。


(1)获取SEGV会表明您或您的发行版正在使用-fno-stack-protector进行编译。

答案 1 :(得分:0)

是的,CPU将内存段和页面标记为可写和可执行。如果您尝试执行操作系统不允许的操作(未标记为可执行或可写),则会使CPU引发将由操作系统处理的中断。对于像操作系统这样的UNIX,操作系统会向发生访问冲突的进程发送一个SIGSEGV信号(可以处理,但无法恢复)。

好像你在堆栈框架的末尾溢出了很多。