小编0x0*_*x00的帖子

今天和20年前的记忆对齐

在着名的论文"Smashing the Stack for Fun and Profit"中,它的作者采用了C函数

void function(int a, int b, int c) {
  char buffer1[5];
  char buffer2[10];
}
Run Code Online (Sandbox Code Playgroud)

并生成相应的汇编代码输出

pushl %ebp
movl %esp,%ebp
subl $20,%esp
Run Code Online (Sandbox Code Playgroud)

作者解释说,由于计算机以字大小的倍数对存储器进行寻址,因此编译器在堆栈上保留了20个字节(缓冲区1为8个字节,缓冲区2为12个字节).

我试图重新创建这个例子并获得以下内容

pushl   %ebp
movl    %esp, %ebp
subl    $16, %esp
Run Code Online (Sandbox Code Playgroud)

不同的结果!我尝试了缓冲区1和缓冲区2的各种大小组合,似乎现代的gcc不再将缓冲区大小填充到字大小的倍数.相反,它遵守-mpreferred-stack-boundary选项.

作为一个例子 - 使用纸张的算术规则,对于buffer1 [5]和buffer2 [13],我会在堆栈上保留8 + 16 = 24个字节.但实际上我有32个字节.

这篇论文很古老,自那以后发生了很多事情.我想知道,究竟是什么推动了这种行为的改变?这是向64位机器的转变吗?或者是其他东西?

编辑

代码使用gcc版本4.8.2(Ubuntu 4.8.2-19ubuntu1)在x86_64机器上编译,如下所示:

$ gcc -S -o example1.s example1.c -fno-stack-protector -m32

c x86 assembly gcc

13
推荐指数
1
解决办法
251
查看次数

标签 统计

assembly ×1

c ×1

gcc ×1

x86 ×1