我搞砸了Aleph One的"Smash the Stack for Fun and Profit",发现在为64位处理器编译代码时,堆栈内存没有使用通常的"sub $VALUE, %REG "分配。
这是函数源代码:
void function() {
char buffer1[5];
char buffer2[10];
int *ret;
ret = buffer1 + 32;
(*ret) +=8;
}
这是编译版本
function:
.LFB0:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
movl $1868654947, -16(%rbp)
movb $0, -12(%rbp)
leaq -16(%rbp), %rax
addq $32, %rax
movq %rax, -8(%rbp)
movq -8(%rbp), %rax
movl (%rax), %eax
leal 8(%rax), %edx
movq -8(%rbp), %rax
movl %edx, (%rax)
nop
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
为什么没有标准的堆栈分配,而如果我使用-m32选项与gcc它出现?
amd64 SysV ABI包含一个称为红色区域的概念。红色区域是堆栈指针下面128字节的区域。它的目的是允许函数在必须递减堆栈指针的情况下分配少量的堆栈。这就是为什么你没有看到堆栈指针递减。
使用-mno-red-zone
编译以关闭此功能。