首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >打印和getenv

打印和getenv
EN

Stack Overflow用户
提问于 2011-08-22 21:41:17
回答 5查看 5.1K关注 0票数 2

Ubuntu10.04,C,gcc,x86 Intel proc:

当试图使用printf打印环境变量的地址时,打印的地址在这个玩具程序中是不正确的(这是一个有意识的反向版本,在这个版本中,我试图通过将地址值保存在堆中来隔离问题的来源,而不是在读取时直接使用指针来覆盖它,并使用直接生成相同问题的指针):

代码语言:javascript
复制
#include <stdio.h>
#include <stdlib.h>

int main(){

    const char* d = getenv("TEST");
    unsigned i = (unsigned*) malloc(sizeof(unsigned));
    i = (unsigned*) d;

    printf("%s at location 0x%8d.\n", "TEST", i);

}

编辑:与此(原件)版本相同的问题)

代码语言:javascript
复制
int main(){

    const char* d = getenv("TEST");
    printf("%s at location %p.\n", "TEST", d);

    return 0;
}

这个问题与如何打印指针无关。请继续读。

如果我将程序更改为不打印测试地址,而是将测试更改为字符串(其值),则没有问题。

但是,返回的地址不是环境变量在输入打印子例程之前实际位于的地址;通过上述设置,应该打印该地址。在eax寄存器中使用main的反汇编和测试地址,我被引用到测试变量的正确位置,这比main在我的系统上大约0 0xbffffiii的堆栈帧(i任意十六进制值)要低一些。打印的地址值为0xbfeiiii。

我不明白。这是否是一种安全防范措施,以防止环境变量被覆盖(例如,粉碎堆栈)?如果是,编译器是否真的像我上面那样跟踪地址的传输,并悄悄地调整它的值?

还是我漏掉了什么?(可能)

非常感谢。

P.S.:为了消除可想象的问题来源,我首先编译时没有任何选项,然后是: gcc -O0 -static -fno-stack- -g程序。

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2011-08-23 14:44:41

我想出来了,在R.的评论之后。他把我引向ASLR的方向。

我不熟悉ASLR堆栈保护。我描述的原因是ASLR对内存地址空间进行了加扰,以防止预测相对于它的变量的位置。一直以来,在LINUX内核中,ASLR都是默认打开的。

为了了解我的意思,获取su特权,然后输入(发送的确切整数可能会根据发行版的不同而变化;在我的发行版上,它是0,默认是2。还最好通过第一次查看文件来确认文件中只有一个整数,就像在我的系统上一样):

代码语言:javascript
复制
cd /proc/sys/kernel
export OLD=$(less randomize_va_space) // save old value to restore after
echo 0 >  randomize_va_space  // 0 == turn off ASLR

然后再运行我的小程序:它将报告我期望的地址(大约0 0xbffffiii)。之后,显然,恢复旧的保护使用

代码语言:javascript
复制
echo $OLD > randomize_va_space

非常感谢每一个花了一些时间来帮助你的人。

票数 1
EN

Stack Overflow用户

发布于 2011-08-22 21:44:35

这不是打印地址的正确方法。只需使用%p格式打印(void*)d

代码语言:javascript
复制
printf("%s at location 0x%p.\n", "TEST", (void*)d);
票数 3
EN

Stack Overflow用户

发布于 2011-08-22 21:47:17

char*指针存储在unsigned变量中可能在某些系统上工作,但不是可移植的。例如,在我的64位Ubuntu框sizeof(char*)==8sizeof(unsigned)==4上。在整数变量中存储指针的可移植方式是使用intptr_t类型。

或者,简单地打印地址,请使用%p,如下所示:

代码语言:javascript
复制
#include <stdio.h>
#include <stdlib.h>

int main() {
    const char* d = getenv("TEST");
    printf("%s at location %p.\n", "TEST", d);
}

在我的Ubuntu盒子上,这个打印出来

代码语言:javascript
复制
TEST at location (nil).

代码语言:javascript
复制
TEST at location 0x7fff8cf34628.

取决于是否设置了$TEST ( couse的地址可能有所不同)。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7153946

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档