Reputation: 131
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
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