问题描述
我对如何执行缓冲区溢出攻击以及寄存器分配在编译器中的工作原理有合理的了解。
令我困惑的是,为什么 C 程序中的堆栈中有这么多东西。 考虑这个易受攻击的程序:
#include <stdio.h>
int main() {
int a = 0;
char str[] = "ABC";
gets(str);
printf("int: %d,str: %s\n",a,str);
return a;
}
让我们运行它
> gcc run.c
> ./a.out asdfasdf
int: 1717859169,str: asdfasdf
好的,所以 str 被覆盖为 int a
。但是为什么 int a
甚至在堆栈中?
做类似 (x86 asm) 之类的事情不是最简单的吗
.global _main
.text
_main:
// omitting the gets() stuff
movq $0,%rax
retq
现在我们的内存流量减少了,因为堆栈上没有任何东西,代码也少得多。
tl;dr 为什么 int a
在堆栈中?
解决方法
根据我帖子的评论。
发生这种情况是因为我在编译时没有进行优化,而当我使用优化进行编译时 gcc -O3 run.c
我不会看到相同的行为。
这是一些优化的程序集
> gcc -o run -O3 run.c
> objdump -d run
...
// Set eax = 0
100003f5c: 31 c0 xorl %eax,%eax
100003f5e: 48 83 c4 08 addq $8,%rsp
100003f62: 5b popq %rbx
100003f63: 5d popq %rbp
// Return 0
100003f64: c3 retq
还有更复杂的未优化:
...
// put 0 on the stack
100003f33: c7 45 f8 00 00 00 00 movl $0,-8(%rbp) the stack
...
// take it off the stack and into ecx
100003f61: 8b 4d f8 movl -8(%rbp),%ecx
100003f64: 89 45 e4 movl %eax,-28(%rbp)
100003f67: 89 c8 movl %ecx,%eax
100003f69: 48 83 c4 20 addq $32,%rsp
100003f6d: 5d popq %rbp
// return 0
100003f6e: c3 retq