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

Gar*_*ees 25 macos aslr osx-mavericks

在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);
Run Code Online (Sandbox Code Playgroud)

(这是Apple的GDB来源的逆向工程.)

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

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

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

nma*_*ier 38

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

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

#include <stdio.h>

const char *test = "test";

int main() {
  printf("%p\n", (void*)test);
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

并照常编译:

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

并检查标志

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

好吧那里有PIE一面旗帜,我们来核实一下

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

这看起来很随机.

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

cc -o test-nopie test-pie.c -Wl,-no_pie
Run Code Online (Sandbox Code Playgroud)

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

并测试:

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

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

FWIW,PIE标志被定义并记录/usr/include/mach-o/loader.hMH_PIE.

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

虽然我不能为你提供一个文件化的方法来启动PIE没有ASLR 的标准二进制文件,因为你想测试代码,大概就是你自己的代码,只是将你的测试程序与测试二进制文件之间的链接-no_pie或删除PIE标志应该就足够了?