0

enter image description here

#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

Lundin
  • 195,001
  • 40
  • 254
  • 396
Carol Ward
  • 699
  • 4
  • 17

2 Answers2

4

First, you should understand that the compiler/linker is free to assign any address to variables you declare in 'automatic' scope (that is, local to a function - and main is just another function, really).

As to "why" the 4 bytes of 'zeros' are there - this is almost certainly because, on the platform you are using, the compiler is aware that access to memory is more efficient (i.e. faster) when the address of that memory is aligned to an eight byte value - so it 'adds in' an extra four bytes to suitably 'align' the address of your buffer array. See here for a discussion on alignment and efficiency.

Adrian Mole
  • 49,934
  • 160
  • 51
  • 83
3

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.

walnut
  • 21,629
  • 4
  • 23
  • 59