#include <stdlib.h> #include <unistd.h> #include <stdio.h> int main(int argc, char **argv) { int modified; char buffer[64]; modified = 0; gets(buffer); if(modified != 0) printf("Changed!"); else printf("Not changed!"); }
I’m trying to play around with a buffer overflow.
When the program counter gets to if(modified != 0), the base pointer is 0x00007fffffffdfe0.
Right below the base pointer, I see 4 bytes that contains integer 0 which makes sense.
However, the buffer is not right below the int modified.
It looks like 4 bytes of 0s then 0x00007fff are in the stack then 64 bytes of As that I entered follows after.
Why doesn’t char buffer[64] come right after the int modified? why is there a “gap”?
I compiled it with gcc -g -fno-stack-protector test1.c -o test1
Thanks
Advertisement
Answer
You already have a general answer. Specifically for your platform (GCC/Linux/x86_64) the relevant ABI (System V x86-64) specifies that arrays of size 16 bytes or larger are always at least 16 byte aligned. This is, as @AdrianMole eplained in his answer, intended for performance benefits, in particular to allow use of SSE instructions on the array.
See page 15 of the System V x86-64 psABI version 1.0 linked here.
If you make the array size smaller than 16 bytes, this wont happen. There was however also a GCC bug that accidentally applied this rule to all arrays larger than 16 bits, i.e. 2 bytes. This has been fixed with GCC 7.1.