1

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

#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)

所以 A(41 十六进制)应该写在 EPI 上,但那没有发生

linux 是否有办法保护自己免受缓冲区溢出,从而使缓冲区溢出失败?还是我做错了什么?

4

2 回答 2

3

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

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

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

了你你的段错误。


(1) 完全获得 SEGV 将表明您或您的发行版正在使用-fno-stack-protector.

于 2010-12-25T01:05:05.503 回答
0

是的,CPU 将内存段和页面标记为可写和可执行。如果您尝试执行操作系统不允许的操作(未标记为可执行或可写),它将使 CPU 引发将由操作系统处理的中断。在类 UNIX 操作系统的情况下,操作系统将向发生访问冲突的进程发送 SIGSEGV 信号(可处理,但无法从中恢复)。

看起来你已经溢出堆栈帧的末尾了。

于 2010-12-25T01:00:52.160 回答