gcc -pie如何影响文件作用域变量的地址?

ebdffaop  于 2023-01-17  发布在  其他
关注(0)|答案(1)|浏览(200)

请看下面的代码:

#include <stdio.h>
int gprs[32];
int main(void)
{
   printf("%p\n", (void*)&gprs);
}

使用-pie(似乎是默认值)编译会产生:

0x55c183951040

当使用-no-pie编译时,将生成:

0x404060

有人能解释一下-pie是如何影响文件作用域变量的地址的吗?
注意:默认情况下,Clang似乎有-no-pie

ux6nzvsh

ux6nzvsh1#

有人能解释一下-pie是如何影响文件作用域变量的地址的吗?
使用-pie,操作系统可以将可执行文件加载到内存中的任何地址。在Windows下,这是使用“基址重定位表”来完成的;在Linux下,这是使用“位置无关代码”来完成的。
在这种情况下,出于安全原因,许多现代操作系统将可执行文件加载到内存中的任何(随机)地址(因为如果变量gprs的地址未知,则更难编写访问该变量的病毒)。
这意味着以下示例中(static或全局)变量ab的地址之差:

printf("%p, %p\n", &a, &b);

...应为常量,但每次运行程序时a(和b)的地址可能不同。
使用-no-pie,在两种操作系统下都生成“位置相关代码”,在Windows下不生成“基址重定位表”。
这意味着可执行文件只能被加载到一个固定的内存地址中,因此,static或全局变量(但不一定是非static本地变量)的地址在多次运行程序时不应该改变。

相关问题