indis-macho 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/README.md CHANGED
@@ -2,5 +2,4 @@
2
2
 
3
3
  # Indis::MachO
4
4
 
5
- This gem provides support for processing mach-o binaries in th indis framework.
6
-
5
+ This gem provides support for processing mach-o binaries in the indis framework.
data/indis-macho.gemspec CHANGED
@@ -17,5 +17,5 @@ Gem::Specification.new do |gem|
17
17
  gem.version = Indis::MachO::VERSION
18
18
 
19
19
  gem.add_development_dependency 'rspec'
20
- gem.add_runtime_dependency 'indis-core'
20
+ gem.add_runtime_dependency 'indis-core', '~> 0.1.2'
21
21
  end
data/lib/indis-macho.rb CHANGED
@@ -105,6 +105,7 @@ module Indis
105
105
  build_segments
106
106
  build_dylibs if self.flags.include? :MH_TWOLEVEL
107
107
  build_symbols
108
+ build_indirect_symbols
108
109
  end
109
110
 
110
111
  def flags
@@ -115,6 +116,26 @@ module Indis
115
116
  f
116
117
  end
117
118
 
119
+ def resolve_symbol_at_address(vmaddr)
120
+ segcommands = @commands.map{ |c| c if c.is_a?(Indis::MachO::SegmentCommand) }.compact
121
+ seg = segcommands.find { |seg| vmaddr >= seg.vmaddr && vmaddr < seg.vmaddr+seg.vmsize }
122
+ return nil unless seg
123
+
124
+ ok_types = [:S_NON_LAZY_SYMBOL_POINTERS, :S_LAZY_SYMBOL_POINTERS, :S_LAZY_DYLIB_SYMBOL_POINTERS,
125
+ :S_THREAD_LOCAL_VARIABLE_POINTERS, :S_SYMBOL_STUBS]
126
+ sect = seg.sections.find { |sec| vmaddr >= sec.addr && vmaddr < sec.addr+sec.size && ok_types.include?(sec.type) }
127
+ return nil unless sect
128
+
129
+ stride = sect.type == :S_SYMBOL_STUBS ? sect.reserved2 : 4 # cctools/otool/ofile_print.c:8105
130
+ index = sect.reserved1 + (vmaddr - sect.addr) / stride
131
+
132
+ return nil if index >= @indirect_symbols.length
133
+
134
+ symb = @symbols[@indirect_symbols[index]].name
135
+ @target.publish_event(:macho_indirect_symbol_resolved, vmaddr, symb)
136
+ symb
137
+ end
138
+
118
139
  private
119
140
  def validate_format
120
141
  raise "Not a Mach-O" if @io.length < 4
@@ -145,6 +166,7 @@ module Indis
145
166
  begin
146
167
  c = Indis::MachO::Command.class_of_command(cmd).new(cmd, size, @io)
147
168
  @commands << c
169
+ @target.publish_event(:macho_command_processed, c)
148
170
  rescue Indis::MachO::UnknownCommandError
149
171
  print "Unknown command #{cmd} size #{size}, skipping\n"
150
172
  @io.read(size-8)
@@ -173,11 +195,13 @@ module Indis
173
195
  @target.io.pos = cmd.fileoff
174
196
  seg = Indis::Segment.new(@target, name, cmd.vmaddr, cmd.vmsize, cmd.fileoff, @target.io.read(cmd.filesize))
175
197
  @target.segments << seg
198
+ @target.publish_event(:target_segment_processed, seg)
176
199
 
177
200
  cmd.sections.each do |sec|
178
201
  sec.index = @indexed_sections.length
179
- s = Indis::Section.new(seg, sec.sectname, sec.addr, sec.size, sec.offset)
202
+ s = Indis::Section.new(seg, sec.sectname, sec.addr, sec.size, sec.offset, sec.type, sec.attributes)
180
203
  seg.sections << s
204
+ @target.publish_event(:target_section_processed, s)
181
205
  @indexed_sections << s
182
206
  end
183
207
  end
@@ -194,13 +218,16 @@ module Indis
194
218
  end
195
219
 
196
220
  def build_symbols
197
- symtabcommand = @commands.map{ |c| c if c.is_a?(Indis::MachO::SymTabCommand) }.compact
221
+ symtabcommand = @commands.find{ |c| c.is_a?(Indis::MachO::SymTabCommand) }
198
222
  return if symtabcommand.length == 0
199
223
 
200
- @target.symbols = {}
224
+ @symbols = symtabcommand.symbols
225
+
226
+ @target.symbols = []
201
227
 
202
- cmd = symtabcommand.first
203
- cmd.symbols.each do |sym|
228
+ symtabcommand.symbols.each do |sym|
229
+ next if sym.stab?
230
+
204
231
  sec = if sym.sect > 0
205
232
  @indexed_sections[sym.sect]
206
233
  else
@@ -215,9 +242,17 @@ module Indis
215
242
  end
216
243
 
217
244
  s = Indis::Symbol.new(sym.name, sec, dy, sym.value, sym)
218
- @target.symbols[sym.name] = s
245
+ @target.symbols << s
246
+ @target.publish_event(:target_symbol_processed, s)
219
247
  end
220
248
  end
249
+
250
+ def build_indirect_symbols
251
+ dysymtabcommand = @commands.find{ |c| c.is_a?(Indis::MachO::DySymTabCommand) }
252
+ return if !dysymtabcommand || dysymtabcommand.length == 0
253
+
254
+ @indirect_symbols = dysymtabcommand.indirect_symbols
255
+ end
221
256
  end
222
257
 
223
258
  end
@@ -17,6 +17,7 @@
17
17
  ##############################################################################
18
18
 
19
19
  require 'indis-macho/symbol'
20
+ require 'indis-macho/dyld_info_parser'
20
21
 
21
22
  module Indis
22
23
  module MachO
@@ -140,11 +141,53 @@ module Indis
140
141
  class SectionSubCommand < Command # LC_SEGMENT.sub
141
142
  f_string :sectname, 16
142
143
  f_string :segname, 16
143
- f_uint32 :addr, :size, :offset, :align, :reloff, :nreloc, :flags, :reserved1, :reseved2
144
+ f_uint32 :addr, :size, :offset, :align, :reloff, :nreloc, :flags, :reserved1, :reserved2
144
145
  attr_accessor :index
146
+ attr_reader :type, :attributes
147
+
148
+ SECTION_TYPE_MASK = 0x000000ff
149
+ SECTION_ATTRIBUTES_MASK = 0xffffff00
150
+
151
+ SECTION_TYPE = {
152
+ 0x00 => :S_REGULAR, # regular section
153
+ 0x01 => :S_ZEROFILL, # zero-fill on demand section
154
+ 0x02 => :S_CSTRING_LITERALS, # section with only literal C strings
155
+ 0x03 => :S_4BYTE_LITERALS, # section with only 4 byte literals
156
+ 0x04 => :S_8BYTE_LITERALS, # section with only 8 byte literals
157
+ 0x05 => :S_LITERAL_POINTERS, # section with only pointers to literals
158
+ 0x06 => :S_NON_LAZY_SYMBOL_POINTERS, # section with only non-lazy symbol pointers
159
+ 0x07 => :S_LAZY_SYMBOL_POINTERS, # section with only lazy symbol pointers
160
+ 0x08 => :S_SYMBOL_STUBS, # section with only symbol stubs (s.a. byte size of stub in the reserved2)
161
+ 0x09 => :S_MOD_INIT_FUNC_POINTERS, # section with only function pointers for initialization
162
+ 0x0a => :S_MOD_TERM_FUNC_POINTERS, # section with only function pointers for termination
163
+ 0x0b => :S_COALESCED, # section contains symbols that are to be coalesced
164
+ 0x0c => :S_GB_ZEROFILL, # zero fill on demand section (>4Gb)
165
+ 0x0d => :S_INTERPOSING, # section with only pairs of function pointers for interposing
166
+ 0x0e => :S_16BYTE_LITERALS, # section with only 16 byte literals
167
+ 0x0f => :S_DTRACE_DOF, # section contains DTrace Object Format
168
+ 0x10 => :S_LAZY_DYLIB_SYMBOL_POINTERS, # section with only lazy symbol pointers to lazy loaded dylibs
169
+ 0x11 => :S_THREAD_LOCAL_REGULAR, # template of initial values for TLVs
170
+ 0x12 => :S_THREAD_LOCAL_ZEROFILL, # template of initial values for TLVs (zero-filled on demand?)
171
+ 0x13 => :S_THREAD_LOCAL_VARIABLES, # TLV descriptors
172
+ 0x14 => :S_THREAD_LOCAL_VARIABLE_POINTERS, # pointers to TLV descriptors
173
+ 0x15 => :S_THREAD_LOCAL_INIT_FUNCTION_POINTERS, # functions to call to initialize TLV values
174
+ }
175
+
176
+ SECTION_ATTRIBUTES = {
177
+ 0x80000000 => :S_ATTR_PURE_INSTRUCTIONS, # section contains only true machine instructions
178
+ 0x40000000 => :S_ATTR_NO_TOC, # section contains coalesced symbols that are not to be in a ranlib table of contents
179
+ 0x20000000 => :S_ATTR_STRIP_STATIC_SYMS, # ok to strip static symbols in this section in files with the MH_DYLDLINK flag
180
+ 0x10000000 => :S_ATTR_NO_DEAD_STRIP, # no dead stripping
181
+ 0x08000000 => :S_ATTR_LIVE_SUPPORT, # blocks are live if they reference live blocks
182
+ 0x04000000 => :S_ATTR_SELF_MODIFYING_CODE, # Used with i386 code stubs written on by dyld
183
+ # s.a. S_ATTR_DEBUG & friends in loader.h
184
+ }
145
185
 
146
186
  def initialize(payload)
147
187
  process(payload)
188
+ @type = SECTION_TYPE[@flags & SECTION_TYPE_MASK]
189
+ atr = @falgs & SECTION_ATTRIBUTES_MASK
190
+ @attributes = SECTION_ATTRIBUTES.map { |k,v| (atr & k == k) ? v : nil }.compact
148
191
  end
149
192
  end
150
193
 
@@ -191,6 +234,16 @@ module Indis
191
234
  f_uint32 :ilocalsym, :nlocalsym, :iextdefsym, :nextdefsym, :iundefsym, :nundefsym, :tocoff,
192
235
  :ntoc, :modtaboff, :nmodtab, :extrefsymoff, :nextrefsyms, :indirectsymoff, :nindirectsyms,
193
236
  :extreloff, :nextrel, :locreloff, :nlocrel
237
+ attr_reader :indirect_symbols
238
+
239
+ def process(payload)
240
+ super(payload)
241
+
242
+ ofs = payload.pos
243
+ payload.pos = @indirectsymoff
244
+ @indirect_symbols = payload.read(@nindirectsyms * 4).unpack('V*')
245
+ payload.pos = ofs
246
+ end
194
247
  end
195
248
 
196
249
  class LoadDyLinkerCommand < Command # LC_LOAD_DYLINKER
@@ -265,6 +318,30 @@ module Indis
265
318
  class DyldInfoOnlyCommand < Command # LC_DYLD_INFO_ONLY
266
319
  f_uint32 :rebase_off, :rebase_size, :bind_off, :bind_size, :weak_bind_off, :weak_bind_size,
267
320
  :lazy_bind_off, :lazy_bind_size, :export_off, :export_size
321
+ attr_reader :bind_symbols, :weak_bind_symbols, :lazy_bind_symbols
322
+
323
+ def process(payload)
324
+ super(payload)
325
+
326
+ # TODO: rebase
327
+
328
+ off = payload.pos
329
+ payload.pos = @bind_off
330
+ bind = payload.read(@bind_size)
331
+ @bind_symbols = DyldInfoParser.new(bind).parse if @bind_size > 0
332
+
333
+ payload.pos = @weak_bind_off
334
+ weak_bind = payload.read(@weak_bind_size)
335
+ @weak_bind_symbols = DyldInfoParser.new(weak_bind).parse if @weak_bind_size > 0
336
+
337
+ payload.pos = @lazy_bind_off
338
+ lazy_bind = payload.read(@lazy_bind_size)
339
+ @lazy_bind_symbols = DyldInfoParser.new(lazy_bind).parse if @lazy_bind_size > 0
340
+
341
+ # TODO: export
342
+
343
+ payload.pos = off
344
+ end
268
345
  end
269
346
 
270
347
  end
@@ -0,0 +1,127 @@
1
+ ##############################################################################
2
+ # Indis framework #
3
+ # Copyright (C) 2012 Vladimir "Farcaller" Pouzanov <farcaller@gmail.com> #
4
+ # #
5
+ # This program is free software: you can redistribute it and/or modify #
6
+ # it under the terms of the GNU General Public License as published by #
7
+ # the Free Software Foundation, either version 3 of the License, or #
8
+ # (at your option) any later version. #
9
+ # #
10
+ # This program is distributed in the hope that it will be useful, #
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of #
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
13
+ # GNU General Public License for more details. #
14
+ # #
15
+ # You should have received a copy of the GNU General Public License #
16
+ # along with this program. If not, see <http://www.gnu.org/licenses/>. #
17
+ ##############################################################################
18
+
19
+ module Indis
20
+ module MachO
21
+
22
+ class DyldInfoParser
23
+ BIND_OPCODE_MASK = 0xF0
24
+ BIND_IMMEDIATE_MASK = 0x0F
25
+
26
+ BIND_OPCODES = {
27
+ 0x00 => :BIND_OPCODE_DONE,
28
+ 0x10 => :BIND_OPCODE_SET_DYLIB_ORDINAL_IMM,
29
+ 0x20 => :BIND_OPCODE_SET_DYLIB_ORDINAL_ULEB,
30
+ 0x30 => :BIND_OPCODE_SET_DYLIB_SPECIAL_IMM,
31
+ 0x40 => :BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM,
32
+ 0x50 => :BIND_OPCODE_SET_TYPE_IMM,
33
+ 0x60 => :BIND_OPCODE_SET_ADDEND_SLEB,
34
+ 0x70 => :BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB,
35
+ 0x80 => :BIND_OPCODE_ADD_ADDR_ULEB,
36
+ 0x90 => :BIND_OPCODE_DO_BIND,
37
+ 0xA0 => :BIND_OPCODE_DO_BIND_ADD_ADDR_ULEB,
38
+ 0xB0 => :BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED,
39
+ 0xC0 => :BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB,
40
+ }
41
+
42
+ TYPE_IMM = {
43
+ 1 => :POINTER,
44
+ 2 => :TEXT_ABSOLUTE32,
45
+ 3 => :TEXT_PCREL32,
46
+ }
47
+
48
+ def initialize(bytes)
49
+ @bytes = StringIO.new(bytes)
50
+ end
51
+
52
+ def parse
53
+ syms = []
54
+ sym = {offset: 0}
55
+ begin
56
+
57
+ b = pop
58
+ opcode = BIND_OPCODES[b & BIND_OPCODE_MASK]
59
+ imm = b & BIND_IMMEDIATE_MASK
60
+ #puts "** OPCODE #{opcode} IMM #{imm}"
61
+ case opcode
62
+ when :BIND_OPCODE_SET_DYLIB_ORDINAL_IMM
63
+ sym[:library] = imm
64
+ when :BIND_OPCODE_SET_SYMBOL_TRAILING_FLAGS_IMM
65
+ sym[:flags] = []
66
+ sym[:flags] << :WEAK_IMPORT if imm & 1 == 1
67
+ sym[:flags] << :NON_WEAK_DEFINITION if imm & 8 == 8
68
+
69
+ nm = ''
70
+ c = pop
71
+ while c != 0 do
72
+ nm += c.chr
73
+ c = pop
74
+ end
75
+ sym[:name] = nm
76
+ when :BIND_OPCODE_SET_TYPE_IMM
77
+ #puts "Unknown type #{imm}" unless TYPE_IMM[imm]
78
+ sym[:type] = TYPE_IMM[imm] || imm
79
+ when :BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB
80
+ sym[:segment] = imm
81
+ sym[:offset] = pop_uleb
82
+ when :BIND_OPCODE_DONE
83
+ #break
84
+ when :BIND_OPCODE_DO_BIND
85
+ syms << sym.dup
86
+ sym[:offset] += 4
87
+ when :BIND_OPCODE_ADD_ADDR_ULEB
88
+ u = pop_uleb
89
+ sym[:offset] += u
90
+ when :BIND_OPCODE_DO_BIND_ADD_ADDR_IMM_SCALED
91
+ syms << sym.dup
92
+ sym[:offset] += 4 + imm*4
93
+ when :BIND_OPCODE_DO_BIND_ULEB_TIMES_SKIPPING_ULEB
94
+ count = pop_uleb
95
+ skip = pop_uleb
96
+ count.times do
97
+ syms << sym.dup
98
+ sym[:offset] += skip + 4
99
+ end
100
+ else
101
+ raise "unknown opcode #{opcode} #{(b & BIND_OPCODE_MASK).to_s 16}"
102
+ end
103
+ sym[:offset] &= 0xffffffff
104
+ end while @bytes.pos < @bytes.length
105
+ syms
106
+ end
107
+
108
+ private
109
+ def pop
110
+ @bytes.read(1).ord
111
+ end
112
+
113
+ def pop_uleb
114
+ result = 0
115
+ bit = 0
116
+ begin
117
+ p = pop
118
+ slice = p & 0x7f
119
+ result |= (slice << bit)
120
+ bit += 7
121
+ end while p & 0x80 != 0
122
+ result
123
+ end
124
+ end
125
+
126
+ end
127
+ end
@@ -32,35 +32,35 @@ module Indis
32
32
  0xa => :INDR,
33
33
  }
34
34
  STAB = {
35
- 0x20 => :N_GSYM,
36
- 0x22 => :N_FNAME,
37
- 0x24 => :N_FUN,
38
- 0x26 => :N_STSYM,
39
- 0x28 => :N_LCSYM,
40
- 0x2e => :N_BNSYM,
41
- 0x3c => :N_OPT,
42
- 0x40 => :N_RSYM,
43
- 0x44 => :N_SLINE,
44
- 0x4e => :N_ENSYM,
45
- 0x60 => :N_SSYM,
46
- 0x64 => :N_SO,
47
- 0x66 => :N_OSO,
48
- 0x80 => :N_LSYM,
49
- 0x82 => :N_BINCL,
50
- 0x84 => :N_SOL,
51
- 0x86 => :N_PARAMS,
52
- 0x88 => :N_VERSION,
53
- 0x8A => :N_OLEVEL,
54
- 0xa0 => :N_PSYM,
55
- 0xa2 => :N_EINCL,
56
- 0xa4 => :N_ENTRY,
57
- 0xc0 => :N_LBRAC,
58
- 0xc2 => :N_EXCL,
59
- 0xe0 => :N_RBRAC,
60
- 0xe2 => :N_BCOMM,
61
- 0xe4 => :N_ECOMM,
62
- 0xe8 => :N_ECOML,
63
- 0xfe => :N_LENG,
35
+ 0x20 => :N_GSYM, # global symbol
36
+ 0x22 => :N_FNAME, # procedure name (f77 kludge)
37
+ 0x24 => :N_FUN, # procedure name
38
+ 0x26 => :N_STSYM, # static symbol
39
+ 0x28 => :N_LCSYM, # .lcomm symbol
40
+ 0x2e => :N_BNSYM, # begin nsect symbol
41
+ 0x3c => :N_OPT, # emitted with gcc2_compiled and in gcc source
42
+ 0x40 => :N_RSYM, # register symbol
43
+ 0x44 => :N_SLINE, # src line
44
+ 0x4e => :N_ENSYM, # end nsect symbol
45
+ 0x60 => :N_SSYM, # structure elt
46
+ 0x64 => :N_SO, # source file name
47
+ 0x66 => :N_OSO, # object file name
48
+ 0x80 => :N_LSYM, # local symbol
49
+ 0x82 => :N_BINCL, # include file beginning
50
+ 0x84 => :N_SOL, # #included file name
51
+ 0x86 => :N_PARAMS, # compiler parameters
52
+ 0x88 => :N_VERSION, # compiler version
53
+ 0x8A => :N_OLEVEL, # compiler -O level
54
+ 0xa0 => :N_PSYM, # parameter
55
+ 0xa2 => :N_EINCL, # include file end
56
+ 0xa4 => :N_ENTRY, # alternate entry
57
+ 0xc0 => :N_LBRAC, # left bracket
58
+ 0xc2 => :N_EXCL, # deleted include file
59
+ 0xe0 => :N_RBRAC, # right bracket
60
+ 0xe2 => :N_BCOMM, # begin common
61
+ 0xe4 => :N_ECOMM, # end common
62
+ 0xe8 => :N_ECOML, # end common (local name)
63
+ 0xfe => :N_LENG, # second stab entry with length information
64
64
  }
65
65
  REFERENCE_TYPE_MASK = 0xf
66
66
  DESC_REFERENCE = {
@@ -94,7 +94,11 @@ module Indis
94
94
  @name = strtab[name_idx..-1].split("\0", 2)[0]
95
95
  end
96
96
 
97
- #puts "#{printf('%08x', value)} #{@name} sect #{@sect} #{self.type ? self.type : 'UNK 0b'+@type_val.to_s(2)} #{self.stab? ? 'stab ' : ''} #{self.private_extern? ? 'pvt ' : ''} #{self.extern? ? 'extern' : ''}"
97
+ # if stab?
98
+ # puts ".stabs \"#{@name}\", #{STAB[@type_val]}, #{@sect}, #{self.desc}, #{@value}"
99
+ # else
100
+ # puts "SYM \"#{@name}\", #{TYPE[@type_val & TYPE_MASK]}, #{@sect}, #{self.desc}, #{@value}"
101
+ # end
98
102
  end
99
103
 
100
104
  def type
@@ -18,6 +18,6 @@
18
18
 
19
19
  module Indis
20
20
  module MachO
21
- VERSION = '0.2.0'
21
+ VERSION = '0.3.0'
22
22
  end
23
23
  end
@@ -14,10 +14,11 @@ def macho_target_double(*args)
14
14
  if o[:symbols]
15
15
  target.should_receive(:symbols){ o[:symbols] }.any_number_of_times
16
16
  else
17
- target.should_receive(:symbols).any_number_of_times.and_return({})
17
+ target.should_receive(:symbols).any_number_of_times.and_return([])
18
18
  end
19
19
  target.stub(:vamap=)
20
20
  target.stub(:io).and_return(o[:io])
21
+ target.stub(:publish_event)
21
22
  target
22
23
  end
23
24
 
@@ -87,14 +88,37 @@ describe Indis::BinaryFormat::MachO do
87
88
  end
88
89
 
89
90
  it "should parse symbols" do
90
- sym = {}
91
+ sym = []
91
92
  io = StringIO.new(File.open('spec/fixtures/single-object.o', 'rb').read().force_encoding('BINARY'))
92
93
  target = macho_target_double(io: io, symbols: sym)
93
94
 
94
95
  m = Indis::BinaryFormat::MachO.new(target, io)
95
96
 
96
- sym.keys.should include("_add")
97
- sym.keys.should include("_sub")
98
- sym.keys.should include("_printf")
97
+ sym.find {|s| s.name == '_add' }.should be_a(Indis::Symbol)
98
+ sym.find {|s| s.name == '_sub' }.should be_a(Indis::Symbol)
99
+ sym.find {|s| s.name == '_printf' }.should be_a(Indis::Symbol)
100
+ end
101
+
102
+ it "should parse dyld operands" do
103
+ io = StringIO.new(File.open('spec/fixtures/app-arm-release.o', 'rb').read().force_encoding('BINARY'))
104
+ target = macho_target_double(io: io)
105
+
106
+ m = Indis::BinaryFormat::MachO.new(target, io)
107
+ dysymtab = m.commands.map{ |c| c if c.is_a?(Indis::MachO::DyldInfoOnlyCommand) }.compact.first
108
+ dysymtab.bind_symbols.length.should == 20
109
+ dysymtab.weak_bind_symbols.should be_nil
110
+ dysymtab.lazy_bind_symbols.length.should == 10
111
+ end
112
+
113
+ it "should post events while parsing" do
114
+ io = StringIO.new(File.open('spec/fixtures/app-arm-release.o', 'rb').read().force_encoding('BINARY'))
115
+ target = macho_target_double(io: io)
116
+
117
+ target.should_receive(:publish_event).with(:macho_command_processed, anything).exactly(20).times
118
+ target.should_receive(:publish_event).with(:target_segment_processed, anything).exactly(4).times
119
+ target.should_receive(:publish_event).with(:target_section_processed, anything).exactly(22).times
120
+ target.should_receive(:publish_event).with(:target_symbol_processed, anything).exactly(51).times
121
+
122
+ m = Indis::BinaryFormat::MachO.new(target, io)
99
123
  end
100
124
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: indis-macho
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-04-15 00:00:00.000000000 Z
12
+ date: 2012-04-18 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
@@ -32,17 +32,17 @@ dependencies:
32
32
  requirement: !ruby/object:Gem::Requirement
33
33
  none: false
34
34
  requirements:
35
- - - ! '>='
35
+ - - ~>
36
36
  - !ruby/object:Gem::Version
37
- version: '0'
37
+ version: 0.1.2
38
38
  type: :runtime
39
39
  prerelease: false
40
40
  version_requirements: !ruby/object:Gem::Requirement
41
41
  none: false
42
42
  requirements:
43
- - - ! '>='
43
+ - - ~>
44
44
  - !ruby/object:Gem::Version
45
- version: '0'
45
+ version: 0.1.2
46
46
  description: Mach-o format processor for indis provides support for loading mach-o
47
47
  binaries for analysis
48
48
  email:
@@ -62,6 +62,7 @@ files:
62
62
  - indis-macho.gemspec
63
63
  - lib/indis-macho.rb
64
64
  - lib/indis-macho/command.rb
65
+ - lib/indis-macho/dyld_info_parser.rb
65
66
  - lib/indis-macho/symbol.rb
66
67
  - lib/indis-macho/version.rb
67
68
  - spec/fixtures/app-arm-release.o