我试图了解以下C程序和堆栈的布局。最终目标是了解缓冲区溢出漏洞。
#include <unistd.h>
void Test()
{
char buff[4];
printf("Some input: ");
gets(buff);
puts(buff);
}
int main(int argc, char *argv[ ])
{
Test();
return 0;
}
我使用-g -fno-stack-protector -O0来编译程序。
在gdb中,当我看到Test函数的程序集时,它看起来像这样
(gdb) disass Test
Dump of assembler code for function Test:
0x0804847d <+0>: push %ebp
0x0804847e <+1>: mov %esp,%ebp
**0x08048480 <+3>: sub $0x28,%esp**
=> 0x08048483 <+6>: movl $0x8048550,(%esp)
0x0804848a <+13>: call 0x8048330 <printf@plt>
0x0804848f <+18>: lea -0xc(%ebp),%eax
0x08048492 <+21>: mov %eax,(%esp)
0x08048495 <+24>: call 0x8048340 <gets@plt>
0x0804849a <+29>: lea -0xc(%ebp),%eax
0x0804849d <+32>: mov %eax,(%esp)
0x080484a0 <+35>: call 0x8048350 <puts@plt>
0x080484a5 <+40>: leave
0x080484a6 <+41>: ret
End of assembler dump.
我注意到在汇编中,编译器保留了大约40个字节的数据。这基于上面的**0x08048480 <+3>: sub $0x28,%esp**
语句。
问题:由于分配的缓冲区只有4个字节,为什么编译器需要保留40个字节?什么是其他字节?
PS:
请注意,我正在禁用编译器中的所有优化并使用-fno-stack-protector作为参数。 上面的Test函数也没有参数。
gcc版本4.8.4(Ubuntu 4.8.4-2ubuntu1~14.04)