gpt4 book ai didi

c - 为什么指令在内存用户空间顶部的地址与linux进程内存布局相反?

转载 作者:行者123 更新时间:2023-12-02 09:37:24 24 4
gpt4 key购买 nike

#include <stdio.h>
void func() {}

int main() {
printf("%p", &func);

return 0;
}
该程序输出了 0x55c4cda9464a假设 func将存储在 .text部分中,并且根据此图,来自 CS:APP: enter image description here
我想 func的地址应该在 .text节的起始地址附近,但是这个地址应该在中间。为什么会这样呢?存储在堆栈中的局部变量的地址接近2 ^ 48-1,但是我试图反汇编不同的C代码,并且指令始终位于 0x55...地址周围。

最佳答案

gcc--enable-default-pie 1(默认设置)一起配置时,会生成Position Independent Executables(PIE)。这意味着装入地址与在编译时指定的链接器不同(x86_64为0x400000)。这是一种安全机制,因此可以启用Address Space Layout Randomization(ASLR)2。也就是说,默认情况下,gcc使用 -pie 选项进行编译。
如果使用-no-pie选项(gcc -no-pie file.c)进行编译,则可以看到func的地址更接近0x400000。
在我的系统上,我得到:

$ gcc -no-pie t.c
$ ./a.out
0x401132
您还可以使用 readelf 检查加载地址:
$ readelf -Wl a.out | grep LOAD
LOAD 0x000000 0x0000000000400000 0x0000000000400000 0x000478 0x000478 R 0x1000
LOAD 0x001000 0x0000000000401000 0x0000000000401000 0x0001f5 0x0001f5 R E 0x1000
LOAD 0x002000 0x0000000000402000 0x0000000000402000 0x000158 0x000158 R 0x1000
LOAD 0x002e10 0x0000000000403e10 0x0000000000403e10 0x000228 0x000230 RW 0x1000

1您可以使用 gcc --verbose进行检查。
2您可能还会注意到,程序每次打印的地址都不同。那是因为ASLR。您可以使用以下方法禁用它:
$ echo 0 | sudo tee /proc/sys/kernel/randomize_va_space
默认情况下,Linux上启用了ASLR。

关于c - 为什么指令在内存用户空间顶部的地址与linux进程内存布局相反?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63465933/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com