Module: MachO

Defined in:
lib/macho.rb,
lib/macho/open.rb,
lib/macho/tools.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

Overview

The primary namespace for ruby-macho.

Defined Under Namespace

Modules: Tools 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

VERSION =

release version

"0.1.9".freeze
FAT_MAGIC =

big-endian fat magic

0xcafebabe
FAT_CIGAM =

little-endian fat magic

0xbebafeca
MH_MAGIC =

32-bit big-endian magic

0xfeedface
MH_CIGAM =

32-bit little-endian magic

0xcefaedfe
MH_MAGIC_64 =

64-bit big-endian magic

0xfeedfacf
MH_CIGAM_64 =

64-bit little-endian magic

0xcffaedfe
MH_MAGICS =

association of magic numbers to string representations

{
	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_ABI64 =

mask for CPUs with 64-bit architectures (when running a 64-bit ABI?)

0x01000000
CPU_TYPE_ANY =

any CPU (unused?)

-1
CPU_TYPE_X86 =

x86 compatible CPUs

0x07
CPU_TYPE_I386 =

i386 and later compatible CPUs

CPU_TYPE_X86
CPU_TYPE_X86_64 =

x86_64 (AMD64) compatible CPUs

(CPU_TYPE_X86 | CPU_ARCH_ABI64)
CPU_TYPE_POWERPC =

PowerPC compatible CPUs (7400 series?)

0x24
CPU_TYPE_POWERPC64 =

PowerPC64 compatible CPUs (970 series?)

(CPU_TYPE_POWERPC | CPU_ARCH_ABI64)
CPU_TYPES =

association of cpu types to string representations

{
	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 =

mask for CPU subtype capabilities

0xff000000
CPU_SUBTYPE_LIB64 =

64-bit libraries (undocumented!)

0x80000000
CPU_SUBTYPE_X86_ALL =

all x86-type CPUs

3
CPU_SUBTYPE_X86_ARCH1 =

all x86-type CPUs (what makes this different from CPU_SUBTYPE_X86_ALL?)

4
CPU_SUBTYPES =

association of cpu subtypes to string representations

{
	CPU_SUBTYPE_X86_ALL => "CPU_SUBTYPE_X86_ALL",
	CPU_SUBTYPE_X86_ARCH1 => "CPU_SUBTYPE_X86_ARCH1"
}
MH_OBJECT =

relocatable object file

0x1
MH_EXECUTE =

demand paged executable file

0x2
MH_FVMLIB =

fixed VM shared library file

0x3
MH_CORE =

core dump file

0x4
MH_PRELOAD =

preloaded executable file

0x5
MH_DYLIB =

dynamically bound shared library

0x6
MH_DYLINKER =

dynamic link editor

0x7
MH_BUNDLE =

dynamically bound bundle file

0x8
MH_DYLIB_STUB =

shared library stub for static linking only, no section contents

0x9
MH_DSYM =

companion file with only debug sections

0xa
MH_KEXT_BUNDLE =

x86_64 kexts

0xb
MH_FILETYPES =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

association of filetypes to string representations

{
	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_FLAGS =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

association of mach header flag symbols to values

{
	:MH_NOUNDEFS => 0x1,
	:MH_INCRLINK => 0x2,
	:MH_DYLDLINK => 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
}
SECTION_TYPE =

type mask

0x000000ff
SECTION_ATTRIBUTES =

attributes mask

0xffffff00
SECTION_ATTRIBUTES_USR =

user settable attributes mask

0xff000000
SECTION_ATTRIBUTES_SYS =

system settable attributes mask

0x00ffff00
SECTION_FLAGS =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

association of section flag symbols to values

{
	:S_REGULAR => 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 => 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
}
SECTION_NAMES =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

association of section name symbols to names

{
	:SECT_TEXT => "__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
LOAD_COMMANDS =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

association of load commands to symbol representations

{
	0x1 => :LC_SEGMENT,
	0x2 => :LC_SYMTAB,
	0x3 => :LC_SYMSEG,
	0x4 => :LC_THREAD,
	0x5 => :LC_UNIXTHREAD,
	0x6 => :LC_LOADFVMLIB,
	0x7 => :LC_IDFVMLIB,
	0x8 => :LC_IDENT,
	0x9 => :LC_FVMFILE,
	0xa => :LC_PREPAGE,
	0xb => :LC_DYSYMTAB,
	0xc => :LC_LOAD_DYLIB,
	0xd => :LC_ID_DYLIB,
	0xe => :LC_LOAD_DYLINKER,
	0xf => :LC_ID_DYLINKER,
	0x10 => :LC_PREBOUND_DYLIB,
	0x11 => :LC_ROUTINES,
	0x12 => :LC_SUB_FRAMEWORK,
	0x13 => :LC_SUB_UMBRELLA,
	0x14 => :LC_SUB_CLIENT,
	0x15 => :LC_SUB_LIBRARY,
	0x16 => :LC_TWOLEVEL_HINTS,
	0x17 => :LC_PREBIND_CKSUM,
	(0x18 | LC_REQ_DYLD) => :LC_LOAD_WEAK_DYLIB,
	0x19 => :LC_SEGMENT_64,
	0x1a => :LC_ROUTINES_64,
	0x1b => :LC_UUID,
	(0x1c | LC_REQ_DYLD) => :LC_RPATH,
	0x1d => :LC_CODE_SIGNATURE,
	0x1e => :LC_SEGMENT_SPLIT_INFO,
	(0x1f | LC_REQ_DYLD) => :LC_REEXPORT_DYLIB,
	0x20 => :LC_LAZY_LOAD_DYLIB,
	0x21 => :LC_ENCRYPTION_INFO,
	0x22 => :LC_DYLD_INFO,
	(0x22 | LC_REQ_DYLD) => :LC_DYLD_INFO_ONLY,
	(0x23 | LC_REQ_DYLD) => :LC_LOAD_UPWARD_DYLIB,
	0x24 => :LC_VERSION_MIN_MACOSX,
	0x25 => :LC_VERSION_MIN_IPHONEOS,
	0x26 => :LC_FUNCTION_STARTS,
	0x27 => :LC_DYLD_ENVIRONMENT,
	(0x28 | LC_REQ_DYLD) => :LC_MAIN,
	0x29 => :LC_DATA_IN_CODE,
	0x2a => :LC_SOURCE_VERSION,
	0x2b => :LC_DYLIB_CODE_SIGN_DRS,
	0x2c => :LC_ENCRYPTION_INFO_64,
	0x2d => :LC_LINKER_OPTION,
	0x2e => :LC_LINKER_OPTIMIZATION_HINT
}
LC_STRUCTURES =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

association of load command symbols to string representations of classes

{
	: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"
}
SEGMENT_NAMES =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

association of segment name symbols to names

{
	:SEG_PAGEZERO => "__PAGEZERO",
	:SEG_TEXT => "__TEXT",
	:SEG_DATA => "__DATA",
	:SEG_OBJC => "__OBJC",
	:SEG_ICON => "__ICON",
	:SEG_LINKEDIT => "__LINKEDIT",
	:SEG_UNIXSTACK => "__UNIXSTACK",
	:SEG_IMPORT => "__IMPORT"
}
SEGMENT_FLAGS =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

association of segment flag symbols to values

{
	:SG_HIGHVM => 0x1,
	:SG_FVMLIB => 0x2,
	:SG_NORELOC => 0x4,
	:SG_PROTECTED_VERSION_1 => 0x8
}

Class Method Summary collapse

Class Method Details

.fat_magic?(num) ⇒ Boolean

Returns true if num is a valid Fat magic number, false otherwise.

Parameters:

  • num (Fixnum)

    the number being checked

Returns:

  • (Boolean)

    true if num is a valid Fat magic number, false otherwise



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

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

.magic32?(num) ⇒ Boolean

Returns true if num is a valid 32-bit magic number, false otherwise.

Parameters:

  • num (Fixnum)

    the number being checked

Returns:

  • (Boolean)

    true if num is a valid 32-bit magic number, false otherwise



27
28
29
# File 'lib/macho/utils.rb', line 27

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

.magic64?(num) ⇒ Boolean

Returns true if num is a valid 64-bit magic number, false otherwise.

Parameters:

  • num (Fixnum)

    the number being checked

Returns:

  • (Boolean)

    true if num is a valid 64-bit magic number, false otherwise



33
34
35
# File 'lib/macho/utils.rb', line 33

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

.magic?(num) ⇒ Boolean

Returns true if num is a valid Mach-O magic number, false otherwise.

Parameters:

  • num (Fixnum)

    the number being checked

Returns:

  • (Boolean)

    true if num is a valid Mach-O magic number, false otherwise



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

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

.open(filename) ⇒ MachO::MachOFile, MachO::FatFile

Opens the given filename as a MachOFile or FatFile, depending on its magic.

Parameters:

  • filename (String)

    the file being opened

Returns:



6
7
8
9
10
11
12
13
14
15
# File 'lib/macho/open.rb', line 6

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) ⇒ Fixnum

Returns the next number >= value such that round is its divisor.

Parameters:

  • value (Fixnum)

    the number being rounded

  • round (Fixnum)

    the number being rounded with

Returns:

  • (Fixnum)

    the next number >= value such that round is its divisor

See Also:



6
7
8
9
10
11
# File 'lib/macho/utils.rb', line 6

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