Class: Indis::BinaryFormat::MachO

Inherits:
Format
  • Object
show all
Defined in:
lib/indis-macho.rb

Constant Summary collapse

MH_MAGIC =
0xfeedface
CPUTYPE =
{
  12 => :CPU_TYPE_ARM
}
CPUSUBTYPE =
{
  5 => :CPU_SUBTYPE_ARM_V4T,
  6 => :CPU_SUBTYPE_ARM_V6,
  7 => :CPU_SUBTYPE_ARM_V5TEJ,
  8 => :CPU_SUBTYPE_ARM_XSCALE,
  9 => :CPU_SUBTYPE_ARM_V7
}
FILETYPE =
{
  0x1 => :MH_OBJECT,
  0x2 => :MH_EXECUTE,
  0x3 => :MH_FVMLIB,
  0x4 => :MH_CORE,
  0x5 => :MH_PRELOAD,
  0x6 => :MH_DYLIB,
  0x7 => :MH_DYLINKER,
  0x8 => :MH_BUNDLE,
  0x9 => :MH_DYLIB_STUB,
  0xa => :MH_DSYM,
  0xb => :MH_KEXT_BUNDLE
}
FLAGS =
{
  0x1 => :MH_NOUNDEFS,
  0x2 => :MH_INCRLINK,
  0x4 => :MH_DYLDLINK,
  0x8 => :MH_BINDATLOAD,
  0x10 => :MH_PREBOUND,
  0x20 => :MH_SPLIT_SEGS,
  0x40 => :MH_LAZY_INIT,
  0x80 => :MH_TWOLEVEL,
  0x100 => :MH_FORCE_FLAT,
  0x200 => :MH_NOMULTIDEFS,
  0x400 => :MH_NOFIXPREBINDING,
  0x800 => :MH_PREBINDABLE,
  0x1000 => :MH_ALLMODSBOUND,
  0x2000 => :MH_SUBSECTIONS_VIA_SYMBOLS,
  0x4000 => :MH_CANONICAL,
  0x8000 => :MH_WEAK_DEFINES,
  0x10000 => :MH_BINDS_TO_WEAK,
  0x20000 => :MH_ALLOW_STACK_EXECUTION,
  0x40000 => :MH_ROOT_SAFE,
  0x80000 => :MH_SETUID_SAFE,
  0x100000 => :MH_NO_REEXPORTED_DYLIBS,
  0x200000 => :MH_PIE,
  0x400000 => :MH_DEAD_STRIPPABLE_DYLIB,
  0x800000 => :MH_HAS_TLV_DESCRIPTORS,
  0x1000000 => :MH_NO_HEAP_EXECUTION,
}

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(target, io) ⇒ MachO

Returns a new instance of MachO.



97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/indis-macho.rb', line 97

def initialize(target, io)
  super(target, io)
  
  @commands = []

  parse_header
  parse_commands

  build_segments
  build_dylibs if self.flags.include? :MH_TWOLEVEL
  build_symbols
  build_indirect_symbols
end

Instance Attribute Details

#commandsObject (readonly)

Returns the value of attribute commands.



87
88
89
# File 'lib/indis-macho.rb', line 87

def commands
  @commands
end

#cpusubtypeObject (readonly)

Returns the value of attribute cpusubtype.



87
88
89
# File 'lib/indis-macho.rb', line 87

def cpusubtype
  @cpusubtype
end

#cputypeObject (readonly)

Returns the value of attribute cputype.



87
88
89
# File 'lib/indis-macho.rb', line 87

def cputype
  @cputype
end

#filetypeObject (readonly)

Returns the value of attribute filetype.



87
88
89
# File 'lib/indis-macho.rb', line 87

def filetype
  @filetype
end

Class Method Details

.magicObject



89
90
91
# File 'lib/indis-macho.rb', line 89

def self.magic
  MH_MAGIC
end

.nameObject



93
94
95
# File 'lib/indis-macho.rb', line 93

def self.name
  'Mach-O'
end

Instance Method Details

#flagsObject



111
112
113
114
115
116
117
# File 'lib/indis-macho.rb', line 111

def flags
  f = []
  FLAGS.each_pair do |k, v|
    f << v if @flags_val & k == k
  end
  f
end

#resolve_symbol_at_address(vmaddr) ⇒ Object



119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/indis-macho.rb', line 119

def resolve_symbol_at_address(vmaddr)
  segcommands = @commands.map{ |c| c if c.is_a?(Indis::MachO::SegmentCommand) }.compact
  seg = segcommands.find { |seg| vmaddr >= seg.vmaddr && vmaddr < seg.vmaddr+seg.vmsize }
  return nil unless seg
  
  ok_types = [:S_NON_LAZY_SYMBOL_POINTERS, :S_LAZY_SYMBOL_POINTERS, :S_LAZY_DYLIB_SYMBOL_POINTERS,
              :S_THREAD_LOCAL_VARIABLE_POINTERS, :S_SYMBOL_STUBS]
  sect = seg.sections.find { |sec| vmaddr >= sec.addr && vmaddr < sec.addr+sec.size && ok_types.include?(sec.type) }
  return nil unless sect
  
  stride = sect.type == :S_SYMBOL_STUBS ? sect.reserved2 : 4 # cctools/otool/ofile_print.c:8105
  index = sect.reserved1 + (vmaddr - sect.addr) / stride
  
  return nil if index >= @indirect_symbols.length
  
  symb = @symbols[@indirect_symbols[index]].name
  @target.publish_event(:macho_indirect_symbol_resolved, vmaddr, symb)
  symb
end