我检查了是否启用了 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/