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 +1 -2
- data/indis-macho.gemspec +1 -1
- data/lib/indis-macho.rb +41 -6
- data/lib/indis-macho/command.rb +78 -1
- data/lib/indis-macho/dyld_info_parser.rb +127 -0
- data/lib/indis-macho/symbol.rb +34 -30
- data/lib/indis-macho/version.rb +1 -1
- data/spec/indis-macho/macho_spec.rb +29 -5
- metadata +7 -6
data/README.md
CHANGED
data/indis-macho.gemspec
CHANGED
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.
|
221
|
+
symtabcommand = @commands.find{ |c| c.is_a?(Indis::MachO::SymTabCommand) }
|
198
222
|
return if symtabcommand.length == 0
|
199
223
|
|
200
|
-
@
|
224
|
+
@symbols = symtabcommand.symbols
|
225
|
+
|
226
|
+
@target.symbols = []
|
201
227
|
|
202
|
-
|
203
|
-
|
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
|
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
|
data/lib/indis-macho/command.rb
CHANGED
@@ -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, :
|
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
|
data/lib/indis-macho/symbol.rb
CHANGED
@@ -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
|
-
#
|
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
|
data/lib/indis-macho/version.rb
CHANGED
@@ -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.
|
97
|
-
sym.
|
98
|
-
sym.
|
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.
|
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-
|
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:
|
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:
|
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
|