我正在玩一个堆栈溢出的例子。此示例如下所示:Dillema与缓冲区溢出
void return_input (void){
char array[30];
gets (array);
printf("%s\n", array);
}
main() {
return_input();
return 0;
}
所有此代码位于名为overflow.c的文件中。我们有脆弱的函数叫做return_input,特别是它是30字节的char数组。我编译它,并在GDB打开漏洞的功能,得到了以下的输出:
(gdb) disas return_input
0x08048464 <+0>: push %ebp
0x08048465 <+1>: mov %esp,%ebp
0x08048467 <+3>: sub $0x48,%esp
0x0804846a <+6>: mov %gs:0x14,%eax
0x08048470 <+12>: mov %eax,-0xc(%ebp)
0x08048473 <+15>: xor %eax,%eax
0x08048475 <+17>: lea -0x2a(%ebp),%eax
0x08048478 <+20>: mov %eax,(%esp)
0x0804847b <+23>: call 0x8048360 <[email protected]>
0x08048480 <+28>: lea -0x2a(%ebp),%eax
0x08048483 <+31>: mov %eax,(%esp)
0x08048486 <+34>: call 0x8048380 <[email protected]>
0x0804848b <+39>: mov -0xc(%ebp),%eax
0x0804848e <+42>: xor %gs:0x14,%eax
0x08048495 <+49>: je 0x804849c <return_input+56>
0x08048497 <+51>: call 0x8048370 <[email protected]>
0x0804849c <+56>: leave
0x0804849d <+57>: ret
End of assembler dump.
正如你从函数序言我们保留hex48(DEC 72)查看堆栈局部变量的字节。首先,我试图找到我们易受攻击的数组在栈上开始的地址。我认为它是-0x2a(%ebp),对吗? Hex2a是十进制42。据我所知,这意味着我们可以安全地写入42个字节,然后我们开始覆盖保存在堆栈上的EBP。但是,当我运行这个例子足以权只有37个字节得到分段错误:
[email protected]:~/temp/ELF_reader$ ./overflow
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Segmentation fault (core dumped)
如何37个字节,足以溢出缓冲区?如果我们的本地字符数组是-42字节从保存的EBP
无关,但[此问题](http://stackoverflow.com/questions/9249315/what-is-gs-in-assembly)*非常相似。 – huon
在C中,向一个30字节数组写入31个字节足以使该数组溢出(并导致未定义行为)。 – pmg