Reputation: 91
I have ASLR disabled. Well, I want obtain the address of the environment variable "SHELL", so I use the C function getenv().
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
char* ptr = getenv("SHELL");
printf("%p\n", ptr);
}
The address obtained with getenv()
$ ./getenv
0xbffff752
The address obtained with gdb:
gdb> x/4000s $esp
...
(gdb) x/s 0xbffff710
0xbffff710: "SHELL=/bin/bash"
(gdb) x/s 0xbffff716
0xbffff716: "/bin/bash"
Why are the addresses different? As noted, I must say the correct address in the obtained with GDB.
Upvotes: 9
Views: 14279
Reputation: 592
Both addresses are correct for their memory at that time in their process. It's usually the environment size as GDB adds couple items.
But what you can try is to "unset environment LINES" and I think "unset environment COLUMNS" -- and then your env should be the same as the shell that started it.
It's usually off by those two variables when either is launched, not at the same time, from the same shell with ASLR "OFF".
Also, compile with to turn off some protections as well if you're attempting buffer overflow exploits.
gcc -g -z execstack -fno-stack-protector -o main main.c
Upvotes: 0
Reputation: 1
Why the addresses are different?
Because one is run under gdb
and one isn't. Running under a different environment results in a different environment. Literally.
What's the output of the printf()
statement when running under gdb
?
As note, I must say the correct address in the obtained with gdb.
What information is that statement based on?
Upvotes: 7
Reputation: 1352
The trouble is that your list of environment variables can differ when running under gdb and without it. And that is enough to cause the shift in address.
Somewhat shortened listing... (your program)
$ gdb ./a.out
(gdb) r
Starting program: /home/mfranc/a.out
0x7fffffffdd37
(gdb) r
Starting program: /home/mfranc/a.out
0x7fffffffdd37
(gdb) set environment a="hello world"
(gdb) r
Starting program: /home/mfranc/a.out
0x7fffffffdd27
(gdb) r
Starting program: /home/mfranc/a.out
0x7fffffffdd27
(gdb) unset environment a
(gdb) r
Starting program: /home/mfranc/a.out
0x7fffffffdd37
(gdb)
Generally you should debug in the original environment and attach to the process via gdb -p $PID. If you spawn process in a slightly different way and the environment will differ slightly you might see different addresses.
Upvotes: 2
Reputation: 70971
[For Linux]
From man 3 getenv()
(italics by me):
The implementation of getenv() is not required to be reentrant. The string pointed to by the return value of getenv() may be statically allocated, and can be modified by a subsequent call to getenv().
This implies that the value queried may be copied and a reference to the copy is returned, so the address returned might differ from the address where the original env-var-tuple is stored.
Upvotes: 0