user3488903
user3488903

Reputation: 131

Why address of local array variable changes in each invocation (ASLR diabled)?

I was doing a buffer-overflow test. In function foo(), since buffer[256] is an array, I was expecting it to be present in stack at the same address (irrespective of how many bytes are strcpy to it). But, the address of buffer seems to be changed based on how much data is copied to it. I could not understand why it is happening. Can somebody please explain this? I thought disabling ASLR should be sufficient.

└─$ cat a.c
#include <stdio.h>
#include <string.h>

void foo(char *input);

int main(int argc, char *argv[])
{
        foo(argv[1]);
}

void foo(char *input)
{
        char buffer[256];
        printf ("%p\n", &buffer[0]);
        strcpy(buffer, input);
}

└─$ gcc -g -no-pie -fno-stack-protector a.c -o a -z execstack -D_FORTIFY_SOURCE=0

└─$ cat /proc/sys/kernel/randomize_va_space
0

└─$ ./a AA
0x7fffffffde50

└─$ ./a AAAAAAAA
0x7fffffffde40                          <<-- why it is changed now??

└─$ ./a AAAAAAAAAAAAAAAAAAAAAAAA
0x7fffffffde30                          <<-- why it is changed again??

Upvotes: 0

Views: 56

Answers (1)

ElderBug
ElderBug

Reputation: 6145

main is not the first function called in a program, it's usually a function called __start, which does a few things, including initializing the C runtime, and in this implementation, probably retrieving the main arguments and copying them onto the stack before passing them. To save space, these particular buffers are probably allocated with alloca or similar. You could check the address of input to see if it is on the stack.

EDIT: Actually, in the case of linux/ELF format, it seems the arguments are already on the stack when __start is executed. The arguments are setup there by the sytem ELF loader, and __start just pass them to main (see a nice picture there https://lwn.net/Articles/631631/). But in any case, it is up to the system how it is done. Some platforms could that differently.

Upvotes: 2

Related Questions