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

时间:2014-05-27 20:04:50

标签: macos osx-mavericks aslr

在OS X 10.9(Mavericks)上,如果通过调用address space layout randomization并传递未记录的属性0x100来启动该过程,则可以为单个进程禁用posix_spawn()。像这样:

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's GDB sources的逆向工程。)

像这样的无证件功能的问题在于它们往往会在没有通知的情况下消失。根据{{​​3}},动态链接器this Stack Overflow answer用于查询环境变量DYLD_NO_PIE,但这在10.9中不起作用;类似地,静态链接器显然用于采用--no-pie选项,但现在不再是这种情况了。

有没有记录的方法来禁用ASLR?

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

1 个答案:

答案 0 :(得分:37)

实际上,仍然存在-no_pie链接器标志,但您可能认为它实际上被称为--no-pie

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

#include <stdio.h>

const char *test = "test";

int main() {
  printf("%p\n", (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标志,我的Mavericks系统似乎仍然遵守它。

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标志应该足够吗?