Mach-O File Format

From iPhone Development Wiki
Revision as of 05:13, 16 February 2023 by Cynder (talk | contribs) (Describe the Mach-O Header)

The Mach-O File format is the standard executable format across darwin (*OS) systems.

Like most executable formats, it contains a header, set of "commands" dictating memory layout and other attributes, followed by several segments and sections containing code and data.

Header

Magic

Error creating thumbnail: File missing

The magic field, a la the first 4 bytes of the binary, can be any one of 4 values. These denote some basic info about the binary.

MH_MAGIC = FE ED FA CE // Big endian, 32 bit Mach-O

MH_CIGAM = CE FA ED FE // Little endian, 32 bit Mach-O

MH_MAGIC_64 = FE ED FA CF // Big Endian, 64 bit Mach-O

MH_CIGAM_64 = CF FA ED FE // Little endian, 64 bit Mach-O

When read in the proper endianness, they will always be represented as their FEEDFAC* variant.

CPU Type

The CPU Type contains basic info about the architecture this binary was compiled for.

The 0x01000000 bit encodes whether a given type corresponds to the 64-bit variant of an architecture. So, for example, 0x7 corresponds to x86, while 0x01000007 corresponds to x86_64.

The following are common (some less so) constants for this field:

enum MachOArchitecture {
	MachOABIMask	= 0xff000000,
	MachOABI64	= 0x01000000, // 64 bit ABI
	MachOABI6432	= 0x02000000, // "ABI for 64-bit hardware with 32-bit types; LP32"

	// Constants for the cputype field.
	MachOx86	= 7,
	MachOx64	= MachOx86 | MachOABI64,
	MachOArm	= 0xc,
	MachOAarch64	= MachOABI64 | MachOArm,
	MachOAarch6432	= MachOABI6432 | MachOArm,
	MachOSPARC	= 0xe,
	MachOPPC	= 0x12,
	MachOPPC64	= MachOABI64 | MachOPPC,
};

CPU SubType

The meaning of the CPU subtype field's value is dependent on the CPU Type field. A full list of CPU Subtypes for their corresponding CPU Types can be found here:

https://github.com/apple-oss-distributions/lldb/blob/10de1840defe0dff10b42b9c56971dbc17c1f18c/llvm/include/llvm/Support/MachO.h#L925

File Type

A description of the current MH_FILETYPE constants and their meanings:

Name Value Description
MH_OBJECT 0x1 Describes an Object (.o) file, an unlinked intermediate during compilation
MH_EXECUTE 0x2 Describes a standard Executable Mach-O
MH_FVMLIB 0x3 Fixed VM Shared Library File
MH_CORE 0x4 Core dump file
MH_PRELOAD 0x5 Preloaded executable file
MH_DYLIB 0x6 Describes a Mach-O Dynamic Library
MH_DYLINKER 0x7 Dynamic Link Editor
MH_BUNDLE 0x8 Dynamically bound bundle file
MH_DYLIB_STUB 0x9 Shared library stub for static linking only, no section contents
MH_DSYM 0xA Describes a Companion file with only debug sections
MH_KEXT_BUNDLE 0xB x86_64 Kext bundle
MH_FILESET 0xC A set of MachOs running in the same address space and sharing a linkedit

Command Info

ncmds and sizeofcmds encode the number of commands following this header, along with their size in bytes.

Flags

This section is incomplete, you can help by expanding it


Other Resources

Heavily referenced here: https://github.com/Homebrew/ruby-macho/blob/master/lib/macho/headers.rb