I am trying to do an exploit, which spawns a shell, the shellcode is inside an environment variable and I launch the program or GDB with a clean environment so the variable is at the top.

env -i MYVAR=10 gdb ./prog

The thing is, inside GDB there are variables called COLUMNS and LINES and removing them using:

unset env COLUMNS
unset env LINES

and then printing the env with:

x/20s *((char **)environ)

Still produces an output where those variables are visible and with the same addresses. I know I have deleted them because using

show env COLUMNS

Produces an error stating that the variable is not defined.

How can I show the newly updated environment without those that have been deleted?

My goal is finding the address of MYVAR outside of GDB, but I cannot tamper with the program, so by replicating the environment inside GDB without the variables set by it I can get the address.

Thank you, Josh

1 Answer 1


The environment is the second array of strings that is passed as the third "envp" argument to the execve() system call when a process executes a command, the first one being the arguments ("argv").

By convention, those strings are in the var=value format.

execve("/path/to/cmd", ["cmd", "arg1", "arg2"], ["var1=value1", "var2=value2"])

By convention, when executing other commands, often in a child process of theirs, commands pass along the environment strings that they received when they were executed to the command they execute. The execvp() function in the C library, itself a wrapper around the execve() system call does that by default. In the C library (which commands may or may not be linked against but generally are), the environ variable is populated based on the envp array that was received upon execution. That variable is what is passed as envp in further execve()s by execvp() / execlp() / system() / popen()... and putenv() / setenv() / unsetenv() update that environ array.

unset env var in gdb just does the equivalent of that unsetenv() (possibly even call it), and just means that all the strings starting with var= that gdb received when it started won't be included in the envp array that is passed to the commands that gdb will execute from now on.

Once a command is executed, they can do whatever they want with the envp array they received (which will be at the bottom of their stack) including populating environ the variable like applications using the libc do or like perl mapping it to its %ENV associative array or shells that typically create a shell variable for most of the env vars whose name is compatible with a shell variable name.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .