I am trying to implement a buffer overflow attack and I need to know the address of my buffer that I am trying to overflow.
The address that is displayed using GDB is different than if I just did this in the code:
Exact code:
#include<stdio.h>
int main() {
char buffer[20];
printf("%p\n", buffer); // 0xbffff320
return 0;
}
However, in gdb if I do:
p &buffer
I get: 0xbffff330
Why is there a difference and will it mess up my buffer overflow attack?
I have ALSR and stack guard disabled.
Thanks.
EDIT 1: Even when I step through gdb and it encounters the print line, I get 0xbffff320 as the address
EDIT 2:
Environment: Ubuntu Linux 9 image running in virtual box on windows 7.
The gdb version: 6.8-debian
Compiled using GCC such as: gcc -g -fno-stack-protector filename.c
execute immediately: ./a.out
address printed: 0xbffff320
Then open in debugger like this: gdb ./a.out
then enter b main
then run
then p &buffer
Then address is 0xbffff330
Edit 3:
This is the gdb log to reproduce behavior:
$ gdb ./a.out
b main
run
p &buffer /* address here is different than what is shown if I run executable */
step through program to printf statement /* address here is same as p &buffer but different than what is printed when program is ran */
For the moment, the only reasons I can imagine are :
print &buffer
after your program terminated. Solution: try setting a breakpoint onmain
,run
,next
to executeprintf
, andprint &buffer
.printf
line withnext
.Found out that this is expected behavior in old versions of GDB (mine is 6.8-debian), and if you construct your buffer overflow attack properly you can work around this behavior and it won't be a problem.
Your array object in your system is stored in the stack. At the top of your stack there is, among other, the environment. When you run your program with
gdb
,gdb
will provide a different environment (the env var and their value) which explains the addresses difference.You can check the difference by running
show environment
ingdb
and by comparing the output withset
command in your shell.The question, as I understand it, is why the address of a local variable in
main
is different when the program is started from the shell versus when it is started from gdb.Here's a sample program to show the difference:
We'll run it in a clean environment. (I also disabled ASLR).
The output from gdb's
print &buffer
command is the same as the program's idea of the address, but they're both different from when the program was run in the shell.There are a couple of things contributing to the difference:
readline/shell.c:sh_set_lines_and_columns()
. So the environ array is bigger.To remove those two variables from the environment, you can use unset environment, or set exec-wrapper to run
env -u ...
. That way, the program's addresses under gdb are the same as when it's run in the shell (if we use an absolute pathname).