According to Wikipedia, the NX bit is set for all x64 binaries:

OS X for Intel supports the NX bit on all CPUs supported by Apple (from 10.4.4 – the first Intel release – onwards). Mac OS X 10.4 only supported NX stack protection. In Mac OS X 10.5, all 64-bit executables have NX stack and heap; W^X protection. This includes x86-64 (Core 2 or later) and 64-bit PowerPC on the G5 Macs.

However, what if the executable is is not 64 bit: Mach-O executable i386?

Similarly, for ASLR, Wikipedia says that it's enabled by default for 10.7 and up:

In Mac OS X Lion 10.7 (released July 2011), Apple expanded their implementation to cover all applications, stating "address space layout randomization (ASLR) has been improved for all applications. It is now available for 32-bit apps (as are heap memory protections), making 64-bit and 32-bit applications more resistant to attack."

Does this mean there is no way to opt-out of it via a compiler option? If there is, how could I verify that the application has not? Are there any analogies to Windows, where some libraries may be ASLR-ed, but others not?

  • NX bit is for AMD architecture and XD is for Intel. You want to know if a page is executable, basically. vmmap <pid or partial process name> will list out memory chunks permissions.

  • You can check for ASLR (PIE, to be correct) in OS X by using otool -hv <file_path> and checking out the "PIE" flag. For example my i386 Wireshark has no PIE flag (most probably b/c it was compiled without one). I don't know how it is in 10.9, but in 10.7 you could link your program with --no_pie flag to disable PIE.

There's an interesting script at https://github.com/electron-archive/brightray/blob/master/tools/mac/change_mach_o_flags.py which can answer your question. You can actually use it to opt-out already compiled binaries with --no-pie flag to the script. Let me cite a part of it and invite you read the full source:



Traditionally in Mac OS X, 32-bit processes did not have data pages set to prohibit execution. Although user programs could call mprotect and mach_vm_protect to deny execution of code in data pages, the kernel would silently ignore such requests without updating the page tables, and the hardware would happily execute code on such pages. 64-bit processes were always given proper hardware protection of data pages. This behavior was controllable on a system-wide level via the vm.allow_data_exec sysctl, which is set by default to 1. The bit with value 1 (set by default) allows code execution on data pages for 32-bit processes, and the bit with value 2 (clear by default) does the same for 64-bit processes.

In Mac OS X 10.7, executables can "opt in" to having hardware protection against code execution on data pages applied. This is done by setting a new bit in the |flags| field of an executable's |mach_header|. When MH_NO_HEAP_EXECUTION is set, proper protections will be applied, regardless of the setting of vm.allow_data_exec.


On top of that I have to add a link to SO page with two very good answers related to the issue: https://stackoverflow.com/questions/12824045/what-exactly-is-randomized-with-aslr-in-macos-x-and-ios

  • I think NX is the generic name of the feature in general. The marketing terms are (as you said), XD for Intel, but AMD calls it EVP (Enhanced Virus Protection), for some silly reason. ARM calls it XN (eXecute Never). But all of those are NX implementations. AMD did indeed add it to the AMD64 ISA under the name NX, but I don't think that was the term they marketed it as, or at least it's not a trademark (to the best of my knowledge). – forest Dec 19 '17 at 8:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.