Reputation: 443
The following code contains an 8 bytes buffer.
void vuln() {
char buffer[8];
gets(buffer);
printf("%s",buffer);
}
int main() {
vuln();
return 0;
}
So, only 8 bytes of stack is expected to be reserved for this buffer. But the disassembly shows 16 bytes being reserved.
(gdb)
Dump of assembler code for function vuln:
0x000000000040057d <+0>: push %rbp
0x000000000040057e <+1>: mov %rsp,%rbp
0x0000000000400581 <+4>: sub $0x10,%rsp
0x0000000000400585 <+8>: lea -0x10(%rbp),%rax
0x0000000000400589 <+12>: mov %rax,%rdi
0x000000000040058c <+15>: callq 0x400480 <gets@plt>
0x0000000000400591 <+20>: lea -0x10(%rbp),%rax
0x0000000000400595 <+24>: mov %rax,%rsi
0x0000000000400598 <+27>: mov $0x400644,%edi
0x000000000040059d <+32>: mov $0x0,%eax
0x00000000004005a2 <+37>: callq 0x400450 <printf@plt>
0x00000000004005a7 <+42>: leaveq
0x00000000004005a8 <+43>: retq
End of assembler dump.
Some actions are to be perform based on the expected size of the buffer on the stack in an automated script. But this crippled the script. May I know the reason why 16 bytes were allocated for the buffer so that I can incorporate it in the script ?
Upvotes: 2
Views: 142
Reputation: 145839
As @Zack put in his answer, x86-64 ABI requires 16 bytes stack alignment. If you are using gcc
on x86 or x86_64 by default stack is 16 bytes aligned.
From gcc
documentation:
-mpreferred-stack-boundary=num Attempt to keep the stack boundary aligned to a 2 raised to num byte boundary. If -mpreferred-stack-boundary is not specified, the default is 4 (16 bytes or 128 bits).
https://gcc.gnu.org/onlinedocs/gcc/i386-and-x86-64-Options.html
See the documentation further, if SSE is disabled gcc
may align stack to 8 bytes (and thus violate ABI requirements).
Upvotes: 1
Reputation: 140589
The x86-64 ELF psABI requires the stack pointer to be aligned: section 3.2.2 ("The Stack Frame") says
... The end of the input argument area shall be aligned on a 16 byte boundary. In other words, the value (
%rsp
− 8) is always a multiple of 16 when control is transferred to the function entry point. The stack pointer,%rsp
, always points to the end of the latest allocated stack frame.
Your function allocates 8 bytes on the stack and then calls a one-argument function, gets
; that function's one argument is passed in registers, so to maintain the ABI requirement, the compiler has to move the stack pointer down an additional 8 bytes before it makes the function call.
Upvotes: 2
Reputation: 2731
You can't control what the compiler will do on the stack. You also can't control the order of variables on the stack. The compiler is also allowed to introduce padding so to better align things in memory (although not inside arrays: this is strictly forbidden). In certain cases it won't even allocate variables on stack, but in registers instead.
If you has specific needs on assembly level, do it in assembly.
Upvotes: 0