printf和GETENV [英] printf and getenv

查看:146
本文介绍了printf和GETENV的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

的Ubuntu 10.04,C,GCC,英特尔的x86 PROC:

Ubuntu 10.04, C, gcc, x86 Intel proc:

当尝试打印用printf环境变量的地址,打印的地址不在这个玩具程序正确(这是我试图通过保存的地址值到问题的根源隔离自觉地向后版本堆,不能直接使用指针,因为我读它可以被覆盖,使用指针直线上升产生同样的问题):

When trying to print the address of an environmental variable using printf, the address printed is not correct in this toy program (this is a consciously backward version in which I tried to isolate the source of the problem by saving the address value on the heap, not using a pointer directly as I read it can be overwritten, and using a pointer straight up produced the same issue):

#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);

}


编辑:这个(原)版本同样的问题)


same issue with this (the original) version)

int main(){

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

    return 0;
}

这个问题有没有关系如何打印指针。请接着往下看。

如果我修改程序不打印测试的地址,但测试作为字符串(其值),没有问题。

This question has nothing to do with how to print a pointer. Kindly read on.

If I change the program to not print TEST's address, but TEST as a string (its value), no problem.

然而,返回的地址不是在该环境变量实际位于进入打印子程序之前的地址;并且,通过上述的设置,应该打印。使用的主要的拆卸和EAX寄存器测试的演讲中,我提到了测试变量,这是一个小进一步下跌比主要的堆栈帧在我的系统(我的十六进制值)上关于0xbffffiii的正确位置。打印的地址值是0xbfeiiiii的顺序

However, the address returned is not the address at which the environmental variable is actually located before entering the print sub-routine; and which, by the above set-up, should be printed. Using main's disassembly and TEST's address in the eax register, I am referred to the proper location of the TEST variable, which is a little further down than main's stack frame at about 0xbffffiii on my system (i any hex value). The address value printed is on the order of 0xbfeiiiii.

我不明白。这是一个安全precaution至prevent环境变量被覆盖(例如,破坏堆栈)?如果是,那么编译器真的跟踪传输的地址如我上面做的,默默的调整它的价值?

I don't understand. Is this a security precaution to prevent environmental variables from being overwritten (eg, to smash the stack)? If yes, does the compiler really keep track of transferring the address as I do above, and silently adjusting its value?

还是我失去了一些东西? (可能)

Or am I missing something? (probably)

非常感谢。

P.S:要删除的问题可想而知来源,我先编译不带任何选项,则:
GCC -O0 -static -fno-堆栈保护-g program.c

P.S.: To remove imaginable sources of issues, I compiled first with no options, then: gcc -O0 -static -fno-stack-protector -g program.c

推荐答案

我想通了,由R评论如下..上面进一步指出谁我ASLR的方向。

I figured it out, following a comment by R.. further above who pointed me in the direction of ASLR.

我不熟悉ASLR堆栈保护。我形容是由于ASLR争先恐后的内存地址空间,相对于它的变量的位置prevent prediction。 ASLR早已默认看来Linux内核开启。

I was unfamiliar with ASLR stack protection. What I describe is due to ASLR scrambling the memory address space to prevent prediction of the location of variables relative to it. ASLR has long been default switched on in LINUX kernels it appears.

要明白我的意思,让苏特权,然后输入(在precise整数可能会有所不同根据您的发行版发送;对矿井是0,而默认2.也更好地确认文件只包含1通过第一次的整数看着它,因为它在我的系统):

To see what I meant, get su privileges, then enter (the precise integer to send might vary based on your distro; on mine it is 0, and the default 2. Also better confirm the file only contains 1 integer by first looking at it, as it does on my system):

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

然后再次运行我的小程序:它会报到我的预期地址(约0xbffffiii)。之后,很明显,使用还原旧的保护

Then run my little program again: it will report back the address I expected (around 0xbffffiii). After, obviously, restore old protection using

echo $OLD > randomize_va_space

大家非常感谢谁花了一些时间试图帮助。

Many thanks for everyone who spend some of their time trying to help.

这篇关于printf和GETENV的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆