On OS X 10.9 (Mavericks), it's possible to disable address space layout randomization for a single process if you launch the process by calling posix_spawn()
and passing the undocumented attribute 0x100
. Like this:
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);
(This is reverse-engineered from Apple's GDB sources.)
The trouble with undocumented features like this is that they tend to disappear without notice. According to this Stack Overflow answer the dynamic linker dyld
used to consult the environment variable DYLD_NO_PIE
, but this does not work in 10.9; similarly the static linker apparently used to take a --no-pie
option, but this is no longer the case.
So is there a documented way to disable ASLR?
(The reason why I need to disable ASLR is to ensure repeatability, when testing and debugging, of code whose behaviour depends on the addresses of objects, for example address-based hash tables and BIBOP-based memory managers.)
If ASLR is enabled, the Oracle software may fail to access the shared memory address. Therefore, you need to disable ASLR on Linux (see Oracle document 1345364.1). Run the sysctl -p command to make the modification take effect.
randomize_va_space = 0 This will permanently disable ASLR.
Actually, there still is a -no_pie
linker flag, but you might have thought it is actually called --no-pie
.
Lets have a small test program:
#include <stdio.h> const char *test = "test"; int main() { printf("%p\n", (void*)test); return 0; }
And compile as usual first:
cc -o test-pie test-pie.c
And check the flags
$ 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
Alright there is a PIE
flag in there, let's verify
$ for x in $(seq 1 5); do echo -n "$x "; ./test-pie; done 1 0x10a447f96 2 0x10e3cbf96 3 0x1005daf96 4 0x10df50f96 5 0x104e63f96
That looks random enough.
Now, lets tell the linker we don't want PIE
using -Wl,-no_pie
:
cc -o test-nopie test-pie.c -Wl,-no_pie
Sure enough the PIE
flag is gone:
$ 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
And test:
$ for x in $(seq 1 5); do echo -n "$x "; ./test-nopie; done 1 0x100000f96 2 0x100000f96 3 0x100000f96 4 0x100000f96 5 0x100000f96
So we make the linker not add the PIE
flag, and my Mavericks system seems to still abide by it.
FWIW, the PIE
flag is defined and documented in /usr/include/mach-o/loader.h
as MH_PIE
.
There are tools all over the Internet to clear the PIE flag from existing binaries, e.g. http://src.chromium.org/svn/trunk/src/build/mac/change_mach_o_flags.py
While I cannot offer you a documented way to start a PIE
-flagged binary without ASLR, since you want to test code, presumably your own, just linking your test programs with -no_pie
or removing the PIE
flag afterwards from your test binaries should suffice?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With