记录在OS X上禁用ASLR的方式?

在OS X 10.9(Mavericks)上,如果通过调用posix_spawn()并传递未记录的属性0x100启动进程,可以禁用单个进程的地址空间布局随机化。 喜欢这个:

extern char **environ;
pid_t pid;
posix_spawnattr_t attr;

posix_spawnattr_init(&attr);
posix_spawnattr_setflags(&attr, 0x100);
posix_spawn(&pid, argv[0], NULL, &attr, argv, environ);

(这是从Apple的GDB资源反向设计的。)

这种无证功能的麻烦在于,它们往往会在没有通知的情况下消失。 根据这个堆栈溢出回答动态链接器dyld用于咨询环境变量DYLD_NO_PIE ,但这不适用于10.9; 同样,静态链接器显然用于采取--no-pie选项,但现在不再是这种情况。

那么是否有文件记录的方法来禁用ASLR?

(之所以我需要禁用ASLR,是为了在测试和调试时确保其行为取决于对象地址的代码(例如基于地址的散列表和基于BIBOP的内存管理器)的可重复性。)


实际上,还有一个-no_pie连接器标志,但你可能认为它实际上被称为--no-pie

让我们有一个小测试程序:

#include <stdio.h>

const char *test = "test";

int main() {
  printf("%pn", (void*)test);
  return 0;
}

并照常编译:

cc -o test-pie test-pie.c

并检查标志

$ otool -hv test-pie
test-pie:
Mach header
      magic cputype cpusubtype  caps    filetype ncmds sizeofcmds      flags
MH_MAGIC_64  X86_64        ALL LIB64     EXECUTE    16       1376   NOUNDEFS DYLDLINK TWOLEVEL PIE

好吧,那里有一个PIE旗帜,让我们来验证一下

$ for x in $(seq 1 5); do echo -n "$x "; ./test-pie; done
1 0x10a447f96
2 0x10e3cbf96
3 0x1005daf96
4 0x10df50f96
5 0x104e63f96

这看起来足够随意。

现在,让我们告诉链接器我们不想使用PIE -Wl,-no_pie

cc -o test-nopie test-pie.c -Wl,-no_pie

果然, PIE旗帜消失了:

$ otool -hv test-nopie
test-pie:
Mach header
      magic cputype cpusubtype  caps    filetype ncmds sizeofcmds      flags
MH_MAGIC_64  X86_64        ALL LIB64     EXECUTE    16       1376   NOUNDEFS DYLDLINK TWOLEVEL

并测试:

$ for x in $(seq 1 5); do echo -n "$x "; ./test-nopie; done
1 0x100000f96
2 0x100000f96
3 0x100000f96
4 0x100000f96
5 0x100000f96

所以我们让链接器不添加PIE标志,而我的小牛系统似乎仍然遵守它。

FWIW, PIE标志被定义并记录在/usr/include/mach-o/loader.h作为MH_PIE

互联网上有许多工具可以清除现有二进制文件中的PIE标志,例如http://src.chromium.org/svn/trunk/src/build/mac/change_mach_o_flags.py

虽然我无法为您提供一种文档化的方式来创建一个没有ASLR的PIE标记二进制文件,但是由于您想测试代码,可能是您自己的,只需将测试程序与-no_pie关联起来或者从测试二进制文件中删除PIE标志就足够了?

链接地址: http://www.djcxy.com/p/62197.html

上一篇: Documented way to disable ASLR on OS X?

下一篇: Does MapUserPhysicalPages (AWE remapping) affect ASLR?