Is gcc reordering local variables at compile time?

I am currently reading (second time) "Hacking: The Art of Exploitation" and stumbled upon something.

The book offers two different ways to use these two similar programs: auth_overflow and auth_overflow2

In the first, there is a password verification function, laid out as follows

int check_authentication(char *password) { int auth_flag = 0; char password_buffer[16]; strcpy(password_buffer, password); ... } 

Entering more than 16 ASCII characters will change the auth_flag value to something greater than 0, thus bypassing the check, as shown in this gdb output:

 gdb$ x/12x $esp 0xbffff400: 0xffffffff 0x0000002f 0xb7e0fd24 0x41414141 0xbffff410: 0x41414141 0x41414141 0x41414141 0x00000001 0xbffff420: 0x00000002 0xbffff4f4 0xbffff448 0x08048556 password_buffer @ 0xbffff40c auth_flag @ 0xbffff41c 

The second program inverts two variables:

 int check_authentication(char *password) { char password_buffer[16]; int auth_flag = 0; strcpy(password_buffer, password); ... } 

The author then suggests that it is impossible to overflow in auth_flag, which I really believed. Then I went over to the buffer overflow and, to my surprise, it was still working. The auth_flag variable was still sitting after the buffer, as you can see on this gdb output:

 gdb$ x/12x $esp 0xbffff400: 0xffffffff 0x0000002f 0xb7e0fd24 0x41414141 0xbffff410: 0x41414141 0x41414141 0x41414141 0x00000001 0xbffff420: 0x00000002 0xbffff4f4 0xbffff448 0x08048556 password_buffer @ 0xbffff40c auth_flag @ 0xbffff41c 

I am wondering if gcc does not reorder local variables for alignment / optimization purposes.

I tried to compile using the -O0 flag, but the result is the same.

Do any of you know why this is happening?

Thanks in advance.

+8
c gcc reverse-engineering buffer-overflow gdb
source share
1 answer

The compiler authors can fully implement any distribution scheme for local variables with automatic storage. auth_flag can be set before or after password_buffer on the stack, it can be in a register, it could be completely excluded if this allows you to correctly analyze the code. There may not even be a stack ... The only guarantee that the Standard gives is this:

strcpy(password_buffer, password); causes undefined behavior if the source string containing its null delimiter is longer than the password_buffer destination array. Whether this undefined behavior matches your needs is completely outside the language specification.

In fact, some developers intentionally complicate the task of hackers by randomizing behavior in cases such as published code.

+11
source share

All Articles