我创建了一个简单的 C 程序,每次将其加载到 GDB 中时,我都会看到分配给程序指令的相同内存地址。例如,函数what()
始终加载到内存位置 0x000055555555472d。事实上,每次执行的堆栈都是完全相同的(不仅仅是堆栈的内容,还有 rsp 指向的内存地址。
我知道可以通过将“/proc/sys/kernel/randomize_va_space”设置为 0 来在 Linux 中禁用 ASLR,但我的 Debian 系统中的值为 2。
root@Sierra ~ % cat /proc/sys/kernel/randomize_va_space
2
根据我对 ASLR 的理解,这些地址应该在每次运行时随机化。我的问题是为什么会发生这种情况?我是不是搞错了什么?
答案1
默认情况下,gdb 在 Linux 上禁用地址空间随机化,覆盖kernel.randomize_va_space
sysctl 变量可能具有的任何值。
gdb命令set disable-randomization off
将关闭此功能,并且随后 gdb 创建的任何调试目标都将根据 的值打开或关闭 ASLR kernel.randomize_va_space
。
答案2
程序是如何编译的?在 Centos 7 系统上blah.c
并安装了开发 foo
#include <stdio.h>
int whereisthis(void) { return 42; }
int main(void) {
printf("%p\n", whereisthis);
return 0;
}
的地址whereisthis
可以取决于编译标志
% rm blah
% CFLAGS='-pipe' make blah
cc -pipe blah.c -o blah
% repeat 3 ./blah
0x40054c
0x40054c
0x40054c
% rm blah
% CFLAGS='-fstack-protector-all -fPIE -pie -pipe' make blah
cc -fstack-protector-all -fPIE -pie -pipe blah.c -o blah
% repeat 3 ./blah
0x7f0e9d3ba82f
0x7fd940aca82f
0x7f6961b1182f
%