Get the environment variable address
Solution 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?
Solution 2
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.
David
Updated on July 18, 2022Comments
-
David almost 2 years
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.
-
Ed Heal almost 9 yearsHow do you know that the correct address is with gdb? Surely both are correct
-
Ed Heal almost 9 yearsBoth are living in different environments.
-
David almost 9 years@EdHeal If I search with the address obtained with the C function: (gdb) x/s 0xbffff752 0xbffff752: <Address 0xbffff752 out of bounds>
-
user3629249 almost 9 yearsthe posted code does not even begin to compile. amongst other things, '#include <stdlib.h>' is needed for the system function; getenv(). Strongly suggest compiling with all warnings enabled. (for gcc, at a minimum use: '-Wall -Wextra -pedantid')
-
user3629249 almost 9 yearson my system (ubuntu linux 14.04) the posted code, after adding missing #include, outputs: 0x7fff2280de16 and gdb outputs: 0x7fffffffe46a Amongst other things, these are different processes, each with its' own address space, so the 'effective' address of the same environment variable are different
-
David almost 9 years@user3629249 Ok, thanks. I've added stdlib.h, but the address is the same.
-
alk almost 9 years@user3629249: Many C implementations will manage a missing prototype very well, if the function's implementation returns a value with a bitwidth of
int
. -
David almost 9 years@alk But in the printf I have "%p", no "%i". Is it not correct?
-
alk almost 9 yearsYou probably are on a 32bit platform?
-
David almost 9 years@alk Yes, on a 32-bit platform.
-
Mark Plotnick almost 9 yearsWhat method did you use to disable ASLR?
-
Roi about 2 yearsNote that the length of the name of the program being executed seems to have an effect on the address of the environment variables.
-
-
user3629249 almost 9 yearswhat does 'reentrant' have to do with the question?
-
David almost 9 yearsmm, as you and @user3629249 says, the addresses are different because my program is running under gdb. I understand a debugger debug a process, but the process is independent (it's a "normal" process) and gdb only stop, modify, etc. it. What is exactly what happened? gdb doesn't add environment variables.
-
Miroslav Franc almost 9 years@David The thing that has happened is that when doing gdb ./program gdb is the parent of your process. If you want absolute independence you need to debug in the original environment and attach to the process via gdb -p $PID.
-
David almost 9 yearsOk, ok. Can I not run the program and create the process for attach after with gdb? As a normal debug with gdb, I want say. I want test that.
-
Miroslav Franc almost 9 yearsFor a program that finishes too quickly the only way I can think of is to put getchar (); to cause it wait for you.
-
David almost 9 yearsI added a getchar at the first line in main(). Ok, $ ./getenv prints 0xbffff752, and if I use "gdb -p myPID", (gdb) x/s 0xbffff750, 0xbffff750: "/bin/bash". getenv.c prints to 0xbffff752 and gdb to 0xbffff750. It's not the correct address anyway.
-
Miroslav Franc almost 9 years@David Which does not make much sense, since the addresses differ by 2 bytes. Sorry, I'm not entirely sure what, but you must be doing something wrong. It works for me.
-
Employed Russian almost 9 years@alk While the man page does say that, and some really ancient OSes did do that, no OS currently in use ever does. This answer is not the reason for observed behavior.
-
David almost 9 yearsusing a source in a book I bought, I obtain the correct addres. I don't see the logic. argv[1] must be "SHELL" and argv[2] is the name of the executable to debug. Source: ptr = getenv(argv[1]); ptr += (strlen(argv[0]) - strlen(argv[2])) * 2;