Flutter Engine
The Flutter Engine
|
Classes | |
class | MachOError |
Functions | |
CheckedSeek (file, offset) | |
CheckedRead (file, count) | |
ReadUInt32 (file, endian) | |
ReadMachHeader (file, endian) | |
ReadFatArch (file) | |
WriteUInt32 (file, uint32, endian) | |
HandleMachOFile (file, options, offset=0) | |
HandleFatFile (file, options, fat_offset=0) | |
main (me, args) | |
Variables | |
int | FAT_MAGIC = 0xcafebabe |
int | FAT_CIGAM = 0xbebafeca |
int | MH_MAGIC = 0xfeedface |
int | MH_CIGAM = 0xcefaedfe |
int | MH_MAGIC_64 = 0xfeedfacf |
int | MH_CIGAM_64 = 0xcffaedfe |
int | MH_EXECUTE = 0x2 |
int | MH_PIE = 0x00200000 |
int | MH_NO_HEAP_EXECUTION = 0x01000000 |
Usage: change_mach_o_flags.py [--executable-heap] [--no-pie] <executablepath> Arranges for the executable at |executable_path| to have its data (heap) pages protected to prevent execution on Mac OS X 10.7 ("Lion"), and to have the PIE (position independent executable) bit set to enable ASLR (address space layout randomization). With --executable-heap or --no-pie, the respective bits are cleared instead of set, making the heap executable or disabling PIE/ASLR. This script is able to operate on thin (single-architecture) Mach-O files and fat (universal, multi-architecture) files. When operating on fat files, it will set or clear the bits for each architecture contained therein. NON-EXECUTABLE HEAP 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. See xnu-1699.22.73/osfmk/vm/vm_map.c override_nx and xnu-1699.22.73/bsd/kern/mach_loader.c load_machfile. The Apple toolchain has been revised to set the MH_NO_HEAP_EXECUTION when producing executables, provided that -allow_heap_execute is not specified at link time. Only linkers shipping with Xcode 4.0 and later (ld64-123.2 and later) have this ability. See ld64-123.2.1/src/ld/Options.cpp Options::reconfigureDefaults() and ld64-123.2.1/src/ld/HeaderAndLoadCommands.hpp HeaderAndLoadCommandsAtom<A>::flags(). This script sets the MH_NO_HEAP_EXECUTION bit on Mach-O executables. It is intended for use with executables produced by a linker that predates Apple's modifications to set this bit itself. It is also useful for setting this bit for non-i386 executables, including x86_64 executables. Apple's linker only sets it for 32-bit i386 executables, presumably under the assumption that the value of vm.allow_data_exec is set in stone. However, if someone were to change vm.allow_data_exec to 2 or 3, 64-bit x86_64 executables would run without hardware protection against code execution on data pages. This script can set the bit for x86_64 executables, guaranteeing that they run with appropriate protection even when vm.allow_data_exec has been tampered with. POSITION-INDEPENDENT EXECUTABLES/ADDRESS SPACE LAYOUT RANDOMIZATION This script sets or clears the MH_PIE bit in an executable's Mach-O header, enabling or disabling position independence on Mac OS X 10.5 and later. Processes running position-independent executables have varying levels of ASLR protection depending on the OS release. The main executable's load address, shared library load addresses, and the heap and stack base addresses may be randomized. Position-independent executables are produced by supplying the -pie flag to the linker (or defeated by supplying -no_pie). Executables linked with a deployment target of 10.7 or higher have PIE on by default. This script is never strictly needed during the build to enable PIE, as all linkers used are recent enough to support -pie. However, it's used to disable the PIE bit as needed on already-linked executables.
change_mach_o_flags.CheckedRead | ( | file, | |
count | |||
) |
Reads |count| bytes from the file-like |file| object, raising a MachOError if any other number of bytes is read.
Definition at line 111 of file change_mach_o_flags.py.
change_mach_o_flags.CheckedSeek | ( | file, | |
offset | |||
) |
Seeks the file-like object at |file| to offset |offset| and raises a MachOError if anything funny happens.
Definition at line 100 of file change_mach_o_flags.py.
change_mach_o_flags.HandleFatFile | ( | file, | |
options, | |||
fat_offset = 0 |
|||
) |
Seeks the file-like |file| object to |offset| and loops over its |fat_header| entries, calling HandleMachOFile for each.
Definition at line 219 of file change_mach_o_flags.py.
change_mach_o_flags.HandleMachOFile | ( | file, | |
options, | |||
offset = 0 |
|||
) |
Seeks the file-like |file| object to |offset|, reads its |mach_header|, and rewrites the header's |flags| field if appropriate. The header's endianness is detected. Both 32-bit and 64-bit Mach-O headers are supported (mach_header and mach_header_64). Raises MachOError if used on a header that does not have a known magic number or is not of type MH_EXECUTE. The MH_PIE and MH_NO_HEAP_EXECUTION bits are set or cleared in the |flags| field according to |options| and written to |file| if any changes need to be made. If already set or clear as specified by |options|, nothing is written.
Definition at line 173 of file change_mach_o_flags.py.
change_mach_o_flags.main | ( | me, | |
args | |||
) |
Definition at line 240 of file change_mach_o_flags.py.
change_mach_o_flags.ReadFatArch | ( | file | ) |
Reads an entire |fat_arch| structure (<mach-o/fat.h>) from the file-like |file| object, treating it as having endianness specified by |endian| (per the |struct| module), and returns a 5-tuple of its members as numbers. Raises a MachOError if the proper length of data can't be read from |file|.
Definition at line 149 of file change_mach_o_flags.py.
change_mach_o_flags.ReadMachHeader | ( | file, | |
endian | |||
) |
Reads an entire |mach_header| structure (<mach-o/loader.h>) from the file-like |file| object, treating it as having endianness specified by |endian| (per the |struct| module), and returns a 7-tuple of its members as numbers. Raises a MachOError if the proper length of data can't be read from |file|.
Definition at line 135 of file change_mach_o_flags.py.
change_mach_o_flags.ReadUInt32 | ( | file, | |
endian | |||
) |
Reads an unsigned 32-bit integer from the file-like |file| object, treating it as having endianness specified by |endian| (per the |struct| module), and returns it as a number. Raises a MachOError if the proper length of data can't be read from |file|.
Definition at line 123 of file change_mach_o_flags.py.
change_mach_o_flags.WriteUInt32 | ( | file, | |
uint32, | |||
endian | |||
) |
Writes |uint32| as an unsigned 32-bit integer to the file-like |file| object, treating it as having endianness specified by |endian| (per the |struct| module).
Definition at line 162 of file change_mach_o_flags.py.
int change_mach_o_flags.FAT_CIGAM = 0xbebafeca |
Definition at line 82 of file change_mach_o_flags.py.
int change_mach_o_flags.FAT_MAGIC = 0xcafebabe |
Definition at line 81 of file change_mach_o_flags.py.
int change_mach_o_flags.MH_CIGAM = 0xcefaedfe |
Definition at line 86 of file change_mach_o_flags.py.
int change_mach_o_flags.MH_CIGAM_64 = 0xcffaedfe |
Definition at line 88 of file change_mach_o_flags.py.
int change_mach_o_flags.MH_EXECUTE = 0x2 |
Definition at line 89 of file change_mach_o_flags.py.
int change_mach_o_flags.MH_MAGIC = 0xfeedface |
Definition at line 85 of file change_mach_o_flags.py.
int change_mach_o_flags.MH_MAGIC_64 = 0xfeedfacf |
Definition at line 87 of file change_mach_o_flags.py.
int change_mach_o_flags.MH_NO_HEAP_EXECUTION = 0x01000000 |
Definition at line 91 of file change_mach_o_flags.py.
int change_mach_o_flags.MH_PIE = 0x00200000 |
Definition at line 90 of file change_mach_o_flags.py.