我检查了是否启用了 ASLR,如下所示,我认为是:

[user@localhost test]$ cat /proc/sys/kernel/randomize_va_space
2

我尝试使用以下程序对其进行测试:

test.c :
#include <stdio.h>
int main(void)
{
    printf("%p\n", main);
    return 1;
}

我预计,如果 ASLR 处于事件状态,每次运行都会有不同的地址,对吗?但我每次都一样。我测试了 64 位和 32 位可执行文件。我正在使用 64 位 Arch Linux 系统来测试这个:
[user@localhost test]$ gcc test.c -o test
[user@localhost test]$ ./test
0x4004c6
[user@localhost test]$ ./test
0x4004c6
[user@localhost test]$ ./test
0x4004c6
[user@localhost test]$ ./test
0x4004c6
[user@localhost test]$ gcc -m32 test.c -o test
[user@localhost test]$ ./test
0x80483eb
[user@localhost test]$ ./test
0x80483eb
[user@localhost test]$ ./test
0x80483eb
[user@localhost test]$ ./test
0x80483eb

如您所见,每次运行的地址都是相同的。这不是意味着ASLR关闭了吗?

最佳答案

您的可执行文件必须与位置无关才能允许这样做。

gcc -pie -fPIE -o test test.c

尝试以这种方式运行它,每次运行时地址都应该明显改变。

非 PI 可执行文件旨在加载到存储在其 ELF header 中的固定、明确的非随机地址。这种假设允许编译器和链接器将绝对地址硬编码到输出中,使其在某些目标上更小、更快。

在任何其他地址加载非 PI 可执行文件会使所有这些绝对引用无效,结果最好是 SIGSEGV,而在最坏情况下会运行一些随机代码。 main 的地址不能安全地随机化,因为编译器被允许假设它不会被随机化,所以即使启用了 ASLR,它也永远不会完成。

为了允许随机化,必须告诉编译器生成位置无关代码 ( -fPIE ),并且生成的可执行文件必须标记为位置无关 ( -pie ),以便内核知道在任何地址加载都是安全的。

需要哪些选项来实现这在很大程度上取决于工具链配置, -fpie-fPIE-fpic-fPIC ,有些可能会默认生成 PI 代码。安全的选择是使用 -fPIE 编译并与 -pie -fPIE 链接。

关于c - 为什么 ASLR 似乎不起作用,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/38818084/

10-09 17:27