64-bit Linux stack smashing tutorial: Part 1 uses Get environment variable address gist to get environment variable address. The prerequisite is to first disable ASLR via echo 0 > /proc/sys/kernel/randomize_va_space
.
The content of the gist is:
/*
* I'm not the author of this code, and I'm not sure who is.
* There are several variants floating around on the Internet,
* but this is the one I use.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[]) {
char *ptr;
if(argc < 3) {
printf("Usage: %s <environment variable> <target program name>\n", argv[0]);
exit(0);
}
ptr = getenv(argv[1]); /* get env var location */
ptr += (strlen(argv[0]) - strlen(argv[2]))*2; /* adjust for program name */
printf("%s will be at %p\n", argv[1], ptr);
}
Why *2
is used to adjust for program name?
My guess is that the program name is saved twice above the stack.
The following diagram from https://lwn.net/Articles/631631/ gives more details:
------------------------------------------------------------- 0x7fff6c845000
0x7fff6c844ff8: 0x0000000000000000
_ 4fec: './stackdump\0' <------+
env / 4fe2: 'ENVVAR2=2\0' | <----+
\_ 4fd8: 'ENVVAR1=1\0' | <---+ |
/ 4fd4: 'two\0' | | | <----+
args | 4fd0: 'one\0' | | | <---+ |
\_ 4fcb: 'zero\0' | | | <--+ | |
3020: random gap padded to 16B boundary | | | | | |
In this diagram, ./stackdump
is used to execute the program. So I can see that the program name ./stackdump
is saved once above environment strings. And if ./stackdump
is launched from Bash shell, Bashell will save it in environment strings with key _
:
_
(An underscore.) At shell startup, set to the absolute pathname used to invoke the shell or shell script being executed as passed in the environment or argument list. Subsequently, expands to the last argument to the previous command, after expansion. Also set to the full pathname used to invoke each command executed and placed in the environment exported to that command. When checking mail, this parameter holds the name of the mail file.
Environment strings are above the stack. So the program name is saved another time above the stack.