Module: MachO

Defined in:
lib/macho.rb,
lib/macho/utils.rb,
lib/macho/headers.rb,
lib/macho/fat_file.rb,
lib/macho/sections.rb,
lib/macho/structure.rb,
lib/macho/exceptions.rb,
lib/macho/macho_file.rb,
lib/macho/load_commands.rb

Defined Under Namespace

Classes: CPUSubtypeError, CPUTypeError, DyldInfoCommand, DylibCommand, DylibUnknownError, DylinkerCommand, DysymtabCommand, EncryptionInfoCommand, EncryptionInfoCommand64, EntryPointCommand, FatArch, FatBinaryError, FatFile, FatHeader, FiletypeError, HeaderPadError, LinkeditDataCommand, LinkerOptionCommand, LoadCommand, LoadCommandError, MachHeader, MachHeader64, MachOBinaryError, MachOError, MachOFile, MachOStructure, MagicError, PrebindCksumCommand, PreboundDylibCommand, RoutinesCommand, RoutinesCommand64, RpathCommand, Section, Section64, SegmentCommand, SegmentCommand64, SourceVersionCommand, SubClientCommand, SubFrameworkCommand, SubLibraryCommand, SubUmbrellaCommand, SymtabCommand, ThreadCommand, TwolevelHintsCommand, UUIDCommand, VersionMinCommand

Constant Summary collapse

FAT_MAGIC =

magic numbers used in Mach-O files

0xcafebabe
FAT_CIGAM =

big-endian fat magic

0xbebafeca
MH_MAGIC =

little-endian fat magic

0xfeedface
MH_CIGAM =

32-bit big-endian magic

0xcefaedfe
MH_MAGIC_64 =

32-bit little-endian magic

0xfeedfacf
MH_CIGAM_64 =

64-bit big-endian magic

0xcffaedfe
MH_MAGICS =

64-bit little-endian magic

{
	FAT_MAGIC => "FAT_MAGIC",
	FAT_CIGAM => "FAT_CIGAM",
	MH_MAGIC => "MH_MAGIC",
	MH_CIGAM => "MH_CIGAM",
	MH_MAGIC_64 => "MH_MAGIC_64",
	MH_CIGAM_64 => "MH_CIGAM_64"
}
CPU_ARCH_MASK =

capability bits used in the definition of cputype

0xff000000
CPU_ARCH_ABI64 =
0x01000000
CPU_TYPE_ANY =

(select) values for cputype in MachHeader/MachHeader64

-1
CPU_TYPE_X86 =
0x07
CPU_TYPE_I386 =
CPU_TYPE_X86
CPU_TYPE_X86_64 =
(CPU_TYPE_X86 | CPU_ARCH_ABI64)
CPU_TYPE_POWERPC =
0x24
CPU_TYPE_POWERPC64 =
(CPU_TYPE_POWERPC | CPU_ARCH_ABI64)
CPU_TYPES =
{
	CPU_TYPE_ANY => "CPU_TYPE_ANY",
	CPU_TYPE_X86 => "CPU_TYPE_X86",
	CPU_TYPE_I386 => "CPU_TYPE_I386",
	CPU_TYPE_X86_64 => "CPU_TYPE_X86_64",
	CPU_TYPE_POWERPC => "CPU_TYPE_POWERPC",
	CPU_TYPE_POWERPC64 => "CPU_TYPE_POWERPC64"
}
CPU_SUBTYPE_MASK =

capability bits used in the definition of cpusubtype llvm.org/docs/doxygen/html/Support_2MachO_8h_source.html

0xff000000
CPU_SUBTYPE_LIB64 =
0x80000000
CPU_SUBTYPE_X86_ALL =

(select) cpusubtypes

3
CPU_SUBTYPE_X86_ARCH1 =
4
CPU_SUBTYPES =
{
	CPU_SUBTYPE_X86_ALL => "CPU_SUBTYPE_X86_ALL",
	CPU_SUBTYPE_X86_ARCH1 => "CPU_SUBTYPE_X86_ARCH1"
}
MH_OBJECT =

values for filetype in MachHeader/MachHeader64

0x1
MH_EXECUTE =

relocatable object file

0x2
MH_FVMLIB =

demand paged executable file

0x3
MH_CORE =

fixed VM shared library file

0x4
MH_PRELOAD =

core file

0x5
MH_DYLIB =

preloaded executable file

0x6
MH_DYLINKER =

dynamically bound shared library

0x7
MH_BUNDLE =

dynamic link editor

0x8
MH_DYLIB_STUB =

dynamically bound bundle file

0x9
MH_DSYM =

section contents

0xa
MH_KEXT_BUNDLE =

companion file with only debug sections

0xb
MH_FILETYPES =

x86_64 lexts

{
	MH_OBJECT => "MH_OBJECT",
	MH_EXECUTE => "MH_EXECUTE",
	MH_FVMLIB => "MH_FVMLIB",
	MH_CORE => "MH_CORE",
	MH_PRELOAD => "MH_PRELOAD",
	MH_DYLIB => "MH_DYLIB",
	MH_DYLINKER => "MH_DYLINKER",
	MH_BUNDLE => "MH_BUNDLE",
	MH_DYLIB_STUB => "MH_DYLIB_STUB",
	MH_DSYM => "MH_DSYM",
	MH_KEXT_BUNDLE => "MH_KEXT_BUNDLE"
}
MH_NOUNDEFS =

values for flags field in MachHeader/MachHeader64

0x1
0x2
0x4
MH_BINDATLOAD =
0x8
MH_PREBOUND =
0x10
MH_SPLIT_SEGS =
0x20
MH_LAZY_INIT =
0x40
MH_TWOLEVEL =
0x80
MH_FORCE_FLAT =
0x100
MH_NOMULTIDEFS =
0x200
MH_NOPREFIXBINDING =
0x400
MH_PREBINDABLE =
0x800
MH_ALLMODSBOUND =
0x1000
MH_SUBSECTIONS_VIA_SYMBOLS =
0x2000
MH_CANONICAL =
0x4000
MH_WEAK_DEFINES =
0x8000
MH_BINDS_TO_WEAK =
0x10000
MH_ALLOW_STACK_EXECUTION =
0x20000
MH_ROOT_SAFE =
0x40000
MH_SETUID_SAFE =
0x80000
MH_NO_REEXPORTED_DYLIBS =
0x100000
MH_PIE =
0x200000
MH_DEAD_STRIPPABLE_DYLIB =
0x400000
MH_HAS_TLV_DESCRIPTORS =
0x800000
MH_NO_HEAP_EXECUTION =
0x1000000
MH_APP_EXTENSION_SAFE =
0x02000000
MH_FLAGS =
{
	MH_NOUNDEFS => "MH_NOUNDEFS",
	MH_INCRLINK => "MH_INCRLINK",
	MH_DYLDLINK => "MH_DYLDLINK",
	MH_BINDATLOAD => "MH_BINDATLOAD",
	MH_PREBOUND => "MH_PREBOUND",
	MH_SPLIT_SEGS => "MH_SPLIT_SEGS",
	MH_LAZY_INIT => "MH_LAZY_INIT",
	MH_TWOLEVEL => "MH_TWOLEVEL",
	MH_FORCE_FLAT => "MH_FORCE_FLAT",
	MH_NOMULTIDEFS => "MH_NOMULTIDEFS",
	MH_NOPREFIXBINDING => "MH_NOPREFIXBINDING",
	MH_PREBINDABLE => "MH_PREBINDABLE",
	MH_ALLMODSBOUND => "MH_ALLMODSBOUND",
	MH_SUBSECTIONS_VIA_SYMBOLS => "MH_SUBSECTIONS_VIA_SYMBOLS",
	MH_CANONICAL => "MH_CANONICAL",
	MH_WEAK_DEFINES => "MH_WEAK_DEFINES",
	MH_BINDS_TO_WEAK => "MH_BINDS_TO_WEAK",
	MH_ALLOW_STACK_EXECUTION => "MH_ALLOW_STACK_EXECUTION",
	MH_ROOT_SAFE => "MH_ROOT_SAFE",
	MH_SETUID_SAFE => "MH_SETUID_SAFE",
	MH_NO_REEXPORTED_DYLIBS => "MH_NO_REEXPORTED_DYLIBS",
	MH_PIE => "MH_PIE",
	MH_DEAD_STRIPPABLE_DYLIB => "MH_DEAD_STRIPPABLE_DYLIB",
	MH_HAS_TLV_DESCRIPTORS => "MH_HAS_TLV_DESCRIPTORS",
	MH_NO_HEAP_EXECUTION => "MH_NO_HEAP_EXECUTION",
	MH_APP_EXTENSION_SAFE => "MH_APP_EXTENSION_SAFE"
}
SECTION_TYPE =

the flags field of a section has two parts: a type and attributes

0x000000ff
SECTION_ATTRIBUTES =

type mask

0xffffff00
SECTION_ATTRIBUTES_USR =

attributes mask

0xff000000
SECTION_ATTRIBUTES_SYS =

user settable attributes mask

0x00ffff00
S_REGULAR =

section types for the flags field

0x0
S_ZEROFILL =
0x1
S_CSTRING_LITERALS =
0x2
S_4BYTE_LITERALS =
0x3
S_8BYTE_LITERALS =
0x4
S_LITERAL_POINTERS =
0x5
S_NON_LAZY_SYMBOL_POINTERS =
0x6
S_LAZY_SYMBOL_POINTERS =
0x7
S_SYMBOL_STUBS =
0x8
S_MOD_INIT_FUNC_POINTERS =
0x9
S_MOD_TERM_FUNC_POINTERS =
0xa
S_COALESCED =
0xb
S_GB_ZEROFILE =
0xc
S_INTERPOSING =
0xd
S_16BYTE_LITERALS =
0xe
S_DTRACE_DOF =
0xf
S_LAZY_DYLIB_SYMBOL_POINTERS =
0x10
S_THREAD_LOCAL_REGULAR =
0x11
S_THREAD_LOCAL_ZEROFILL =
0x12
S_THREAD_LOCAL_VARIABLES =
0x13
S_THREAD_LOCAL_VARIABLE_POINTERS =
0x14
S_THREAD_LOCAL_INIT_FUNCTION_POINTERS =
0x15
S_ATTR_PURE_INSTRUCTIONS =

section attributes for the flags field

0x80000000
S_ATTR_NO_TOC =
0x40000000
S_ATTR_STRIP_STATIC_SYMS =
0x20000000
S_ATTR_NO_DEAD_STRIP =
0x10000000
S_ATTR_LIVE_SUPPORT =
0x08000000
S_ATTR_SELF_MODIFYING_CODE =
0x04000000
S_ATTR_DEBUG =
0x02000000
S_ATTR_SOME_INSTRUCTIONS =
0x00000400
S_ATTR_EXT_RELOC =
0x00000200
S_ATTR_LOC_RELOC =
0x00000100
SECT_TEXT =

currently known section names we don’t use these anywhere right now, but they’re good to have

"__text"
SECT_FVMLIB_INIT0 =
"__fvmlib_init0"
SECT_FVMLIB_INIT1 =
"__fvmlib_init1"
SECT_DATA =
"__data"
SECT_BSS =
"__bss"
SECT_COMMON =
"__common"
SECT_OBJC_SYMBOLS =
"__symbol_table"
SECT_OBJC_MODULES =
"__module_info"
SECT_OBJC_STRINGS =
"__selector_strs"
SECT_OBJC_REFS =
"__selector_refs"
SECT_ICON_HEADER =
"__header"
SECT_ICON_TIFF =
"__tiff"
LC_REQ_DYLD =

load commands added after OS X 10.1 need to be bitwise ORed with LC_REQ_DYLD to be recognized by the dynamic linder (dyld)

0x80000000
LC_SEGMENT =

values for cmd in LoadCommand

0x1
LC_SYMTAB =
0x2
LC_SYMSEG =
0x3
LC_THREAD =
0x4
LC_UNIXTHREAD =
0x5
LC_LOADFVMLIB =
0x6
LC_IDFVMLIB =
0x7
LC_IDENT =
0x8
LC_FVMFILE =
0x9
LC_PREPAGE =
0xa
LC_DYSYMTAB =
0xb
LC_LOAD_DYLIB =
0xc
LC_ID_DYLIB =
0xd
LC_LOAD_DYLINKER =
0xe
LC_ID_DYLINKER =
0xf
LC_PREBOUND_DYLIB =
0x10
LC_ROUTINES =
0x11
LC_SUB_FRAMEWORK =
0x12
LC_SUB_UMBRELLA =
0x13
LC_SUB_CLIENT =
0x14
LC_SUB_LIBRARY =
0x15
LC_TWOLEVEL_HINTS =
0x16
LC_PREBIND_CKSUM =
0x17
LC_LOAD_WEAK_DYLIB =
(0x18 | LC_REQ_DYLD)
LC_SEGMENT_64 =
0x19
LC_ROUTINES_64 =
0x1a
LC_UUID =
0x1b
LC_RPATH =
(0x1c | LC_REQ_DYLD)
LC_CODE_SIGNATURE =
0x1d
LC_SEGMENT_SPLIT_INFO =
0x1e
LC_REEXPORT_DYLIB =
(0x1f | LC_REQ_DYLD)
LC_LAZY_LOAD_DYLIB =
0x20
LC_ENCRYPTION_INFO =
0x21
LC_DYLD_INFO =
0x22
LC_DYLD_INFO_ONLY =
(0x22 | LC_REQ_DYLD)
LC_LOAD_UPWARD_DYLIB =
(0x23 | LC_REQ_DYLD)
LC_VERSION_MIN_MACOSX =
0x24
LC_VERSION_MIN_IPHONEOS =
0x25
LC_FUNCTION_STARTS =
0x26
LC_DYLD_ENVIRONMENT =
0x27
LC_MAIN =
(0x28 | LC_REQ_DYLD)
LC_DATA_IN_CODE =
0x29
LC_SOURCE_VERSION =
0x2a
LC_DYLIB_CODE_SIGN_DRS =
0x2b
LC_ENCRYPTION_INFO_64 =
0x2c
LC_LINKER_OPTION =
0x2d
LC_LINKER_OPTIMIZATION_HINT =
0x2e
LOAD_COMMANDS =
{
	LC_SEGMENT => "LC_SEGMENT",
	LC_SYMTAB => "LC_SYMTAB",
	LC_SYMSEG => "LC_SYMSEG",
	LC_THREAD => "LC_THREAD",
	LC_UNIXTHREAD => "LC_UNIXTHREAD",
	LC_LOADFVMLIB => "LC_LOADFVMLIB",
	LC_IDFVMLIB => "LC_IDFVMLIB",
	LC_IDENT => "LC_IDENT",
	LC_FVMFILE => "LC_FVMFILE",
	LC_PREPAGE => "LC_PREPAGE",
	LC_DYSYMTAB => "LC_DYSYMTAB",
	LC_LOAD_DYLIB => "LC_LOAD_DYLIB",
	LC_ID_DYLIB => "LC_ID_DYLIB",
	LC_LOAD_DYLINKER => "LC_LOAD_DYLINKER",
	LC_ID_DYLINKER => "LC_ID_DYLINKER",
	LC_PREBOUND_DYLIB => "LC_PREBOUND_DYLIB",
	LC_ROUTINES => "LC_ROUTINES",
	LC_SUB_FRAMEWORK => "LC_SUB_FRAMEWORK",
	LC_SUB_UMBRELLA => "LC_SUB_UMBRELLA",
	LC_SUB_CLIENT => "LC_SUB_CLIENT",
	LC_SUB_LIBRARY => "LC_SUB_LIBRARY",
	LC_TWOLEVEL_HINTS => "LC_TWOLEVEL_HINTS",
	LC_PREBIND_CKSUM => "LC_PREBIND_CKSUM",
	LC_LOAD_WEAK_DYLIB => "LC_LOAD_WEAK_DYLIB",
	LC_SEGMENT_64 => "LC_SEGMENT_64",
	LC_ROUTINES_64 => "LC_ROUTINES_64",
	LC_UUID => "LC_UUID",
	LC_RPATH => "LC_RPATH",
	LC_CODE_SIGNATURE => "LC_CODE_SIGNATURE",
	LC_SEGMENT_SPLIT_INFO => "LC_SEGMENT_SPLIT_INFO",
	LC_REEXPORT_DYLIB => "LC_REEXPORT_DYLIB",
	LC_LAZY_LOAD_DYLIB => "LC_LAZY_LOAD_DYLIB",
	LC_ENCRYPTION_INFO => "LC_ENCRYPTION_INFO",
	LC_DYLD_INFO => "LC_DYLD_INFO",
	LC_DYLD_INFO_ONLY => "LC_DYLD_INFO_ONLY",
	LC_LOAD_UPWARD_DYLIB => "LC_LOAD_UPWARD_DYLIB",
	LC_VERSION_MIN_MACOSX => "LC_VERSION_MIN_MACOSX",
	LC_VERSION_MIN_IPHONEOS => "LC_VERSION_MIN_IPHONEOS",
	LC_FUNCTION_STARTS => "LC_FUNCTION_STARTS",
	LC_DYLD_ENVIRONMENT => "LC_DYLD_ENVIRONMENT",
	LC_MAIN => "LC_MAIN",
	LC_DATA_IN_CODE => "LC_DATA_IN_CODE",
	LC_SOURCE_VERSION => "LC_SOURCE_VERSION",
	LC_DYLIB_CODE_SIGN_DRS => "LC_DYLIB_CODE_SIGN_DRS",
	LC_ENCRYPTION_INFO_64 => "LC_ENCRYPTION_INFO_64",
	LC_LINKER_OPTION => "LC_LINKER_OPTION",
	LC_LINKER_OPTIMIZATION_HINT => "LC_LINKER_OPTIMIZATION_HINT"
}
LC_STRUCTURES =
{
	LC_SEGMENT => "SegmentCommand",
	LC_SYMTAB => "SymtabCommand",
	LC_SYMSEG => "LoadCommand", # obsolete
	LC_THREAD => "ThreadCommand",
	LC_UNIXTHREAD => "ThreadCommand",
	LC_LOADFVMLIB => "LoadCommand", # obsolete
	LC_IDFVMLIB => "LoadCommand", # obsolete
	LC_IDENT => "LoadCommand", # obsolete
	LC_FVMFILE => "LoadCommand", # reserved for internal use only
	LC_PREPAGE => "LoadCommand", # reserved for internal use only
	LC_DYSYMTAB => "DysymtabCommand",
	LC_LOAD_DYLIB => "DylibCommand",
	LC_ID_DYLIB => "DylibCommand",
	LC_LOAD_DYLINKER => "DylinkerCommand",
	LC_ID_DYLINKER => "DylinkerCommand",
	LC_PREBOUND_DYLIB => "PreboundDylibCommand",
	LC_ROUTINES => "RoutinesCommand",
	LC_SUB_FRAMEWORK => "SubFrameworkCommand",
	LC_SUB_UMBRELLA => "SubUmbrellaCommand",
	LC_SUB_CLIENT => "SubClientCommand",
	LC_SUB_LIBRARY => "SubLibraryCommand",
	LC_TWOLEVEL_HINTS => "TwolevelHintsCommand",
	LC_PREBIND_CKSUM => "PrebindCksumCommand",
	LC_LOAD_WEAK_DYLIB => "DylibCommand",
	LC_SEGMENT_64 => "SegmentCommand64",
	LC_ROUTINES_64 => "RoutinesCommand64",
	LC_UUID => "UUIDCommand",
	LC_RPATH => "RpathCommand",
	LC_CODE_SIGNATURE => "LinkeditDataCommand",
	LC_SEGMENT_SPLIT_INFO => "LinkeditDataCommand",
	LC_REEXPORT_DYLIB => "DylibCommand",
	LC_LAZY_LOAD_DYLIB => "LoadCommand", # undoc, maybe DylibCommand?
	LC_ENCRYPTION_INFO => "EncryptionInfoCommand",
	LC_DYLD_INFO => "DyldInfoCommand",
	LC_DYLD_INFO_ONLY => "DyldInfoCommand",
	LC_LOAD_UPWARD_DYLIB => "LoadCommand", # undoc, maybe DylibCommand?
	LC_VERSION_MIN_MACOSX => "VersionMinCommand",
	LC_VERSION_MIN_IPHONEOS => "VersionMinCommand",
	LC_FUNCTION_STARTS => "LinkeditDataCommand",
	LC_DYLD_ENVIRONMENT => "DylinkerCommand",
	LC_MAIN => "EntryPointCommand",
	LC_DATA_IN_CODE => "LinkeditDataCommand",
	LC_SOURCE_VERSION => "SourceVersionCommand",
	LC_DYLIB_CODE_SIGN_DRS => "LinkeditDataCommand",
	LC_ENCRYPTION_INFO_64 => "EncryptionInfoCommand64",
	LC_LINKER_OPTION => "LinkerOptionCommand",
	LC_LINKER_OPTIMIZATION_HINT => "LinkeditDataCommand"
}
SEG_PAGEZERO =

currently known segment names we don’t use these anywhere right now, but they’re good to have

"__PAGEZERO"
SEG_TEXT =
"__TEXT"
SEG_DATA =
"__DATA"
SEG_OBJC =
"__OBJC"
SEG_ICON =
"__ICON"
SEG_LINKEDIT =
"__LINKEDIT"
SEG_UNIXSTACK =
"__UNIXSTACK"
SEG_IMPORT =
"__IMPORT"

Class Method Summary collapse

Class Method Details

.fat_magic?(num) ⇒ Boolean

Returns:

  • (Boolean)


14
15
16
# File 'lib/macho/utils.rb', line 14

def self.fat_magic?(num)
	num == FAT_MAGIC || num == FAT_CIGAM
end

.magic32?(num) ⇒ Boolean

Returns:

  • (Boolean)


18
19
20
# File 'lib/macho/utils.rb', line 18

def self.magic32?(num)
	num == MH_MAGIC || num == MH_CIGAM
end

.magic64?(num) ⇒ Boolean

Returns:

  • (Boolean)


22
23
24
# File 'lib/macho/utils.rb', line 22

def self.magic64?(num)
	num == MH_MAGIC_64 || num == MH_CIGAM_64
end

.magic?(num) ⇒ Boolean

Returns:

  • (Boolean)


10
11
12
# File 'lib/macho/utils.rb', line 10

def self.magic?(num)
	MH_MAGICS.has_key?(num)
end

.open(filename) ⇒ Object



13
14
15
16
17
18
19
20
21
22
# File 'lib/macho.rb', line 13

def self.open(filename)
	# open file and test magic instead of using exceptions for control?
	begin
		file = MachOFile.new(filename)
	rescue FatBinaryError
		file = FatFile.new(filename)
	end

	file
end

.round(value, round) ⇒ Object



3
4
5
6
7
8
# File 'lib/macho/utils.rb', line 3

def self.round(value, round)
	round -= 1
	value += round
	value &= ~round
	value
end