Search code examples
cgccbuffer-overflow

Why variables declared in different order in the C language remain an unchanged order in the stack? Is it type-related?


Pardon me for my broken English :p

I was doing an exercise of buffer overflow programming when i noticed something very strange. I initialized a 16-byte array of characters and an integer variable and I declared them in different order in two C files, and the only difference in these two files is the order of these two variables. After compiling the source code, however, when i examine the order of these two variables in the stack, I found the orders of these variables in the stack of the two different executables are exactly the same while debugging in gdb. the char pointer is at the higher address and the integer is always at the lower address.

int check_authentication(char *password) {
        int testVariable = 2;
        int auth_flag = 0;
        char password_buffer[16];

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

to make it more intuitive, i printed addresses of these variables and here are the results.

***@ubuntuserver:~/ethical/art$ gcc auth_overflow.c -o auth_overflow -m32 -g -fno-stack-protector
***@ubuntuserver:~/ethical/art$ gcc auth_overflow2.c -o auth_overflow2 -m32 -g -fno-stack-protector
***@ubuntuserver:~/ethical/art$ ./auth_overflow AAAA
&testVaraible -> 0xffffd4b4
&auth_flag -> 0xffffd4b8
password_buffer -> 0xffffd4bc

Access Denied.
***@ubuntuserver:~/ethical/art$ ./auth_overflow2 AAAA
&testVaraible -> 0xffffd4a4
password_buffer -> 0xffffd4ac
&auth_flag -> 0xffffd4a8

Access Denied.
***@ubuntuserver:~/ethical/art$ 

the testVariable is another variable that i used to test if the order of integers would change in the stack so that it can be ignored.

Can someone please tell me the reason why this would happen? Since the result of the code is different from what is described in the book Hacking: The Art Of Exploitation, 2nd Edtion and it's a pretty old book, i thought maybe someone could tell me if there are some new mechanisms within the newest version of gcc that i don't know yet.

Thank you.


Solution

  • The C standard does not require an implementation to put the objects in any particular order.

    A good compiler does not care about what order you put the declarations in. It will arrange the objects as convenient for making good use of memory. Since some objects need to be aligned, a typical arrangement is to start at some aligned location, put the objects with the strictest alignment requirements there, then put objects with progressively laxer requirements after them.

    In the case of ties for alignment requirement, there is generally little reason to care which order the objects are in. They may have been put into a tree or hash table or other internal compiler structure as the declarations were processed, and they may be assigned to memory in whichever order they happen to come out of that data structure in a traversal of it. If a hash or tree is keyed by identifier (name), then the order may be determined by name (after alignment requirement), so you might always get the same object order for the same names and types, regardless of declaration order. Or you might not, since the compiler might be designed in a different way.