indis-macho 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
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