实际上,仍然存在一个-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系统似乎仍然遵守这一规定。
值得一提的是,在/usr/include/mach-o/loader.h
中定义和记录了PIE
标志,其表示为MH_PIE
。
互联网上有很多工具可以清除现有二进制文件的PIE标志,例如 http://src.chromium.org/svn/trunk/src/build/mac/change_mach_o_flags.py
虽然我无法提供一种文档化的方法来启动没有ASLR的PIE
标志二进制文件,但是既然您想测试代码,可能是您自己的代码,那么只需使用-no_pie
链接您的测试程序或从您的测试二进制文件中删除PIE
标志就应该足够了?