我禁用了ASLR。好吧,我想获取环境变量“SHELL”的地址,所以我使用C函数getenv()。
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
char* ptr = getenv("SHELL");
printf("%p\n", ptr);
}
使用getenv()
获得的地址$ ./getenv
0xbffff752
使用gdb获得的地址:
gdb> x/4000s $esp
...
(gdb) x/s 0xbffff710
0xbffff710: "SHELL=/bin/bash"
(gdb) x/s 0xbffff716
0xbffff716: "/bin/bash"
为什么地址不同?如上所述,我必须说明使用GDB获得的正确地址。
答案 0 :(得分:5)
为什么地址不同?
因为一个是在gdb
下运行而另一个不是。在不同的环境下运行会导致不同的环境。字面上。
在printf()
下运行时,gdb
语句的输出是什么?
请注意,我必须说明使用gdb获取的正确地址。
该声明基于什么信息?
答案 1 :(得分:1)
问题是,在gdb下运行并没有它时,您的环境变量列表可能会有所不同。这足以引起地址的转变。
稍微缩短了一下......(你的程序)
$ 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)
通常,您应该在原始环境中进行调试,并通过gdb -p $ PID附加到进程。如果以稍微不同的方式生成进程并且环境略有不同,则可能会看到不同的地址。
答案 2 :(得分:0)
[适用于Linux]
来自我man 3 getenv()
(斜体):
getenv()的实现不需要是可重入的。 的 getenv()的返回值指向的字符串可能是静态的 已分配,可以通过后续调用getenv()进行修改。
这意味着可以复制查询的值并返回对副本的引用,因此返回的可能的地址与存储原始env-var-tuple的地址不同。