为什么ASLR似乎不起作用

Bar*_*uch 2 c linux aslr

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

[user@localhost test]$ cat /proc/sys/kernel/randomize_va_space
2
Run Code Online (Sandbox Code Playgroud)

我试过用以下程序测试它:

test.c:

#include <stdio.h>
int main(void)
{
    printf("%p\n", main);
    return 1;
}
Run Code Online (Sandbox Code Playgroud)

如果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
Run Code Online (Sandbox Code Playgroud)

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

ars*_*rsv 7

您的可执行文件必须与位置无关才能允许.

gcc -pie -fPIE -o test test.c
Run Code Online (Sandbox Code Playgroud)

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

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

在任何其他地址加载非PI可执行文件会使所有这些绝对引用无效,从而最多导致SIGSEGV和最差运行的一些随机代码.地址main不能安全随机化,因为允许编译器认为它不会,所以即使启用了ASLR也不会这样做.

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

哪些选项是要实现依赖于工具链配置了不少,-fpie,-fPIE,-fpic,-fPIC,有些人可能会默认生成的PI代码.安全的赌注是编译-fPIE和链接-pie -fPIE.