在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
内存管理器。)
答案 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
标志应该足够吗?