metasm 1.0.1 → 1.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +1 -0
- data/.hgtags +3 -0
- data/Gemfile +1 -0
- data/INSTALL +61 -0
- data/LICENCE +458 -0
- data/README +29 -21
- data/Rakefile +10 -0
- data/TODO +10 -12
- data/doc/code_organisation.txt +2 -0
- data/doc/core/DynLdr.txt +247 -0
- data/doc/core/ExeFormat.txt +43 -0
- data/doc/core/Expression.txt +220 -0
- data/doc/core/GNUExports.txt +27 -0
- data/doc/core/Ia32.txt +236 -0
- data/doc/core/SerialStruct.txt +108 -0
- data/doc/core/VirtualString.txt +145 -0
- data/doc/core/WindowsExports.txt +61 -0
- data/doc/core/index.txt +1 -0
- data/doc/style.css +6 -3
- data/doc/usage/debugger.txt +327 -0
- data/doc/usage/index.txt +1 -0
- data/doc/use_cases.txt +2 -2
- data/metasm.gemspec +22 -0
- data/{lib/metasm.rb → metasm.rb} +11 -3
- data/{lib/metasm → metasm}/compile_c.rb +13 -7
- data/metasm/cpu/arc.rb +8 -0
- data/metasm/cpu/arc/decode.rb +425 -0
- data/metasm/cpu/arc/main.rb +191 -0
- data/metasm/cpu/arc/opcodes.rb +588 -0
- data/{lib/metasm → metasm/cpu}/arm.rb +7 -5
- data/{lib/metasm → metasm/cpu}/arm/debug.rb +2 -2
- data/{lib/metasm → metasm/cpu}/arm/decode.rb +13 -12
- data/{lib/metasm → metasm/cpu}/arm/encode.rb +23 -8
- data/{lib/metasm → metasm/cpu}/arm/main.rb +0 -3
- data/metasm/cpu/arm/opcodes.rb +324 -0
- data/{lib/metasm → metasm/cpu}/arm/parse.rb +25 -13
- data/{lib/metasm → metasm/cpu}/arm/render.rb +2 -2
- data/metasm/cpu/arm64.rb +15 -0
- data/metasm/cpu/arm64/debug.rb +38 -0
- data/metasm/cpu/arm64/decode.rb +289 -0
- data/metasm/cpu/arm64/encode.rb +41 -0
- data/metasm/cpu/arm64/main.rb +105 -0
- data/metasm/cpu/arm64/opcodes.rb +232 -0
- data/metasm/cpu/arm64/parse.rb +20 -0
- data/metasm/cpu/arm64/render.rb +95 -0
- data/{lib/metasm/ppc.rb → metasm/cpu/bpf.rb} +2 -4
- data/metasm/cpu/bpf/decode.rb +142 -0
- data/metasm/cpu/bpf/main.rb +60 -0
- data/metasm/cpu/bpf/opcodes.rb +81 -0
- data/metasm/cpu/bpf/render.rb +41 -0
- data/metasm/cpu/cy16.rb +9 -0
- data/metasm/cpu/cy16/decode.rb +253 -0
- data/metasm/cpu/cy16/main.rb +63 -0
- data/metasm/cpu/cy16/opcodes.rb +78 -0
- data/metasm/cpu/cy16/render.rb +41 -0
- data/metasm/cpu/dalvik.rb +11 -0
- data/{lib/metasm → metasm/cpu}/dalvik/decode.rb +35 -13
- data/{lib/metasm → metasm/cpu}/dalvik/main.rb +51 -2
- data/{lib/metasm → metasm/cpu}/dalvik/opcodes.rb +19 -11
- data/metasm/cpu/ia32.rb +17 -0
- data/{lib/metasm → metasm/cpu}/ia32/compile_c.rb +5 -7
- data/{lib/metasm → metasm/cpu}/ia32/debug.rb +5 -5
- data/{lib/metasm → metasm/cpu}/ia32/decode.rb +246 -59
- data/{lib/metasm → metasm/cpu}/ia32/decompile.rb +7 -7
- data/{lib/metasm → metasm/cpu}/ia32/encode.rb +19 -13
- data/{lib/metasm → metasm/cpu}/ia32/main.rb +51 -8
- data/metasm/cpu/ia32/opcodes.rb +1424 -0
- data/{lib/metasm → metasm/cpu}/ia32/parse.rb +47 -16
- data/{lib/metasm → metasm/cpu}/ia32/render.rb +31 -4
- data/metasm/cpu/mips.rb +14 -0
- data/{lib/metasm → metasm/cpu}/mips/compile_c.rb +1 -1
- data/metasm/cpu/mips/debug.rb +42 -0
- data/{lib/metasm → metasm/cpu}/mips/decode.rb +46 -16
- data/{lib/metasm → metasm/cpu}/mips/encode.rb +4 -3
- data/{lib/metasm → metasm/cpu}/mips/main.rb +11 -4
- data/{lib/metasm → metasm/cpu}/mips/opcodes.rb +86 -17
- data/{lib/metasm → metasm/cpu}/mips/parse.rb +1 -1
- data/{lib/metasm → metasm/cpu}/mips/render.rb +1 -1
- data/{lib/metasm/dalvik.rb → metasm/cpu/msp430.rb} +1 -1
- data/metasm/cpu/msp430/decode.rb +247 -0
- data/metasm/cpu/msp430/main.rb +62 -0
- data/metasm/cpu/msp430/opcodes.rb +101 -0
- data/{lib/metasm → metasm/cpu}/pic16c/decode.rb +6 -7
- data/{lib/metasm → metasm/cpu}/pic16c/main.rb +0 -0
- data/{lib/metasm → metasm/cpu}/pic16c/opcodes.rb +1 -1
- data/{lib/metasm/mips.rb → metasm/cpu/ppc.rb} +4 -4
- data/{lib/metasm → metasm/cpu}/ppc/decode.rb +18 -12
- data/{lib/metasm → metasm/cpu}/ppc/decompile.rb +3 -3
- data/{lib/metasm → metasm/cpu}/ppc/encode.rb +2 -2
- data/{lib/metasm → metasm/cpu}/ppc/main.rb +17 -12
- data/{lib/metasm → metasm/cpu}/ppc/opcodes.rb +11 -5
- data/metasm/cpu/ppc/parse.rb +55 -0
- data/metasm/cpu/python.rb +8 -0
- data/metasm/cpu/python/decode.rb +136 -0
- data/metasm/cpu/python/main.rb +36 -0
- data/metasm/cpu/python/opcodes.rb +180 -0
- data/{lib/metasm → metasm/cpu}/sh4.rb +1 -1
- data/{lib/metasm → metasm/cpu}/sh4/decode.rb +48 -17
- data/{lib/metasm → metasm/cpu}/sh4/main.rb +13 -4
- data/{lib/metasm → metasm/cpu}/sh4/opcodes.rb +7 -8
- data/metasm/cpu/x86_64.rb +15 -0
- data/{lib/metasm → metasm/cpu}/x86_64/compile_c.rb +28 -17
- data/{lib/metasm → metasm/cpu}/x86_64/debug.rb +4 -4
- data/{lib/metasm → metasm/cpu}/x86_64/decode.rb +57 -15
- data/{lib/metasm → metasm/cpu}/x86_64/encode.rb +55 -26
- data/{lib/metasm → metasm/cpu}/x86_64/main.rb +14 -6
- data/metasm/cpu/x86_64/opcodes.rb +136 -0
- data/{lib/metasm → metasm/cpu}/x86_64/parse.rb +10 -2
- data/metasm/cpu/x86_64/render.rb +35 -0
- data/metasm/cpu/z80.rb +9 -0
- data/metasm/cpu/z80/decode.rb +313 -0
- data/metasm/cpu/z80/main.rb +67 -0
- data/metasm/cpu/z80/opcodes.rb +224 -0
- data/metasm/cpu/z80/render.rb +59 -0
- data/{lib/metasm/os/main.rb → metasm/debug.rb} +160 -401
- data/{lib/metasm → metasm}/decode.rb +35 -4
- data/{lib/metasm → metasm}/decompile.rb +15 -16
- data/{lib/metasm → metasm}/disassemble.rb +201 -45
- data/{lib/metasm → metasm}/disassemble_api.rb +651 -87
- data/{lib/metasm → metasm}/dynldr.rb +220 -133
- data/{lib/metasm → metasm}/encode.rb +10 -1
- data/{lib/metasm → metasm}/exe_format/a_out.rb +9 -6
- data/{lib/metasm → metasm}/exe_format/autoexe.rb +1 -0
- data/{lib/metasm → metasm}/exe_format/bflt.rb +57 -27
- data/{lib/metasm → metasm}/exe_format/coff.rb +11 -3
- data/{lib/metasm → metasm}/exe_format/coff_decode.rb +53 -20
- data/{lib/metasm → metasm}/exe_format/coff_encode.rb +11 -13
- data/{lib/metasm → metasm}/exe_format/dex.rb +13 -5
- data/{lib/metasm → metasm}/exe_format/dol.rb +1 -0
- data/{lib/metasm → metasm}/exe_format/elf.rb +93 -57
- data/{lib/metasm → metasm}/exe_format/elf_decode.rb +143 -34
- data/{lib/metasm → metasm}/exe_format/elf_encode.rb +122 -31
- data/metasm/exe_format/gb.rb +65 -0
- data/metasm/exe_format/javaclass.rb +424 -0
- data/{lib/metasm → metasm}/exe_format/macho.rb +204 -16
- data/{lib/metasm → metasm}/exe_format/main.rb +26 -3
- data/{lib/metasm → metasm}/exe_format/mz.rb +1 -0
- data/{lib/metasm → metasm}/exe_format/nds.rb +7 -4
- data/{lib/metasm → metasm}/exe_format/pe.rb +71 -8
- data/metasm/exe_format/pyc.rb +167 -0
- data/{lib/metasm → metasm}/exe_format/serialstruct.rb +67 -14
- data/{lib/metasm → metasm}/exe_format/shellcode.rb +7 -3
- data/metasm/exe_format/shellcode_rwx.rb +114 -0
- data/metasm/exe_format/swf.rb +205 -0
- data/{lib/metasm → metasm}/exe_format/xcoff.rb +7 -7
- data/metasm/exe_format/zip.rb +335 -0
- data/metasm/gui.rb +13 -0
- data/{lib/metasm → metasm}/gui/cstruct.rb +35 -41
- data/{lib/metasm → metasm}/gui/dasm_coverage.rb +11 -11
- data/{lib/metasm → metasm}/gui/dasm_decomp.rb +7 -20
- data/{lib/metasm → metasm}/gui/dasm_funcgraph.rb +0 -0
- data/metasm/gui/dasm_graph.rb +1695 -0
- data/{lib/metasm → metasm}/gui/dasm_hex.rb +12 -8
- data/{lib/metasm → metasm}/gui/dasm_listing.rb +43 -28
- data/{lib/metasm → metasm}/gui/dasm_main.rb +310 -53
- data/{lib/metasm → metasm}/gui/dasm_opcodes.rb +5 -19
- data/{lib/metasm → metasm}/gui/debug.rb +93 -27
- data/{lib/metasm → metasm}/gui/gtk.rb +162 -40
- data/{lib/metasm → metasm}/gui/qt.rb +12 -2
- data/{lib/metasm → metasm}/gui/win32.rb +179 -42
- data/{lib/metasm → metasm}/gui/x11.rb +59 -59
- data/{lib/metasm → metasm}/main.rb +389 -264
- data/{lib/metasm/os/remote.rb → metasm/os/gdbremote.rb} +146 -54
- data/{lib/metasm → metasm}/os/gnu_exports.rb +1 -1
- data/{lib/metasm → metasm}/os/linux.rb +628 -151
- data/metasm/os/main.rb +330 -0
- data/{lib/metasm → metasm}/os/windows.rb +132 -42
- data/{lib/metasm → metasm}/os/windows_exports.rb +141 -0
- data/{lib/metasm → metasm}/parse.rb +26 -24
- data/{lib/metasm → metasm}/parse_c.rb +221 -116
- data/{lib/metasm → metasm}/preprocessor.rb +55 -40
- data/{lib/metasm → metasm}/render.rb +14 -38
- data/misc/hexdump.rb +2 -1
- data/misc/lint.rb +58 -0
- data/misc/txt2html.rb +9 -7
- data/samples/bindiff.rb +3 -4
- data/samples/dasm-plugins/bindiff.rb +15 -0
- data/samples/dasm-plugins/bookmark.rb +133 -0
- data/samples/dasm-plugins/c_constants.rb +57 -0
- data/samples/dasm-plugins/colortheme_solarized.rb +125 -0
- data/samples/dasm-plugins/cppobj_funcall.rb +60 -0
- data/samples/dasm-plugins/dasm_all.rb +70 -0
- data/samples/dasm-plugins/demangle_cpp.rb +31 -0
- data/samples/dasm-plugins/deobfuscate.rb +251 -0
- data/samples/dasm-plugins/dump_text.rb +35 -0
- data/samples/dasm-plugins/export_graph_svg.rb +86 -0
- data/samples/dasm-plugins/findgadget.rb +75 -0
- data/samples/dasm-plugins/hl_opcode.rb +32 -0
- data/samples/dasm-plugins/hotfix_gtk_dbg.rb +19 -0
- data/samples/dasm-plugins/imm2off.rb +34 -0
- data/samples/dasm-plugins/match_libsigs.rb +93 -0
- data/samples/dasm-plugins/patch_file.rb +95 -0
- data/samples/dasm-plugins/scanfuncstart.rb +36 -0
- data/samples/dasm-plugins/scanxrefs.rb +26 -0
- data/samples/dasm-plugins/selfmodify.rb +197 -0
- data/samples/dasm-plugins/stringsxrefs.rb +28 -0
- data/samples/dasmnavig.rb +1 -1
- data/samples/dbg-apihook.rb +24 -9
- data/samples/dbg-plugins/heapscan.rb +283 -0
- data/samples/dbg-plugins/heapscan/compiled_heapscan_lin.c +155 -0
- data/samples/dbg-plugins/heapscan/compiled_heapscan_win.c +128 -0
- data/samples/dbg-plugins/heapscan/graphheap.rb +616 -0
- data/samples/dbg-plugins/heapscan/heapscan.rb +709 -0
- data/samples/dbg-plugins/heapscan/winheap.h +174 -0
- data/samples/dbg-plugins/heapscan/winheap7.h +307 -0
- data/samples/dbg-plugins/trace_func.rb +214 -0
- data/samples/disassemble-gui.rb +35 -5
- data/samples/disassemble.rb +31 -6
- data/samples/dump_upx.rb +24 -12
- data/samples/dynamic_ruby.rb +12 -3
- data/samples/exeencode.rb +6 -5
- data/samples/factorize-headers-peimports.rb +1 -1
- data/samples/lindebug.rb +175 -381
- data/samples/metasm-shell.rb +1 -2
- data/samples/peldr.rb +2 -2
- data/tests/all.rb +1 -1
- data/tests/arc.rb +26 -0
- data/tests/dynldr.rb +22 -4
- data/tests/expression.rb +55 -0
- data/tests/graph_layout.rb +285 -0
- data/tests/ia32.rb +79 -26
- data/tests/mips.rb +9 -2
- data/tests/x86_64.rb +66 -18
- metadata +330 -218
- data/lib/metasm/arm/opcodes.rb +0 -177
- data/lib/metasm/gui.rb +0 -23
- data/lib/metasm/gui/dasm_graph.rb +0 -1354
- data/lib/metasm/ia32.rb +0 -14
- data/lib/metasm/ia32/opcodes.rb +0 -873
- data/lib/metasm/ppc/parse.rb +0 -52
- data/lib/metasm/x86_64.rb +0 -12
- data/lib/metasm/x86_64/opcodes.rb +0 -118
- data/samples/gdbclient.rb +0 -583
- data/samples/rubstop.rb +0 -399
@@ -139,7 +139,7 @@ class COFF
|
|
139
139
|
end
|
140
140
|
|
141
141
|
class ImportDirectory
|
142
|
-
#
|
142
|
+
# encode all import directories + iat
|
143
143
|
def self.encode(coff, ary)
|
144
144
|
edata = { 'iat' => [] }
|
145
145
|
%w[idata ilt nametable].each { |name| edata[name] = EncodedData.new }
|
@@ -160,12 +160,11 @@ class COFF
|
|
160
160
|
[it, iat]
|
161
161
|
end
|
162
162
|
|
163
|
-
#
|
163
|
+
# encode one import directory + iat + names in the edata hash received as arg
|
164
164
|
def encode(coff, edata)
|
165
165
|
edata['iat'] << EncodedData.new
|
166
166
|
# edata['ilt'] = edata['iat']
|
167
167
|
label = lambda { |n| coff.label_at(edata[n], 0, n) }
|
168
|
-
rva = lambda { |n| Expression[label[n], :-, coff.label_at(coff.encoded, 0)] }
|
169
168
|
rva_end = lambda { |n| Expression[[label[n], :-, coff.label_at(coff.encoded, 0)], :+, edata[n].virtsize] }
|
170
169
|
|
171
170
|
@libname_p = rva_end['nametable']
|
@@ -396,7 +395,8 @@ class COFF
|
|
396
395
|
s.characteristics = %w[MEM_READ MEM_WRITE MEM_DISCARDABLE]
|
397
396
|
encode_append_section s
|
398
397
|
|
399
|
-
if @imports.first and @imports.first.iat_p.kind_of?
|
398
|
+
if @imports.first and @imports.first.iat_p.kind_of?(Integer)
|
399
|
+
# ordiat = iat.sort_by { @import[x].iat_p }
|
400
400
|
ordiat = @imports.zip(iat).sort_by { |id, it| id.iat_p.kind_of?(Integer) ? id.iat_p : 1<<65 }.map { |id, it| it }
|
401
401
|
else
|
402
402
|
ordiat = iat
|
@@ -413,7 +413,7 @@ class COFF
|
|
413
413
|
plt.characteristics = %w[MEM_READ MEM_EXECUTE]
|
414
414
|
|
415
415
|
@imports.zip(iat) { |id, it|
|
416
|
-
if id.iat_p.kind_of?
|
416
|
+
if id.iat_p.kind_of?(Integer) and @sections.find { |s_| s_.virtaddr <= id.iat_p and s_.virtaddr + (s_.virtsize || s_.encoded.virtsize) > id.iat_p }
|
417
417
|
id.iat = it # will be fixed up after encode_section
|
418
418
|
else
|
419
419
|
# XXX should not be mixed (for @directory['iat'][1])
|
@@ -529,9 +529,7 @@ class COFF
|
|
529
529
|
end
|
530
530
|
|
531
531
|
# initialize reloc table base address if needed
|
532
|
-
|
533
|
-
rt.base_addr = off & ~0xfff
|
534
|
-
end
|
532
|
+
rt.base_addr ||= off & ~0xfff
|
535
533
|
|
536
534
|
(rt.relocs ||= []) << r
|
537
535
|
elsif $DEBUG and not rel.target.bind(binding).reduce.kind_of?(Integer)
|
@@ -559,7 +557,7 @@ class COFF
|
|
559
557
|
end
|
560
558
|
|
561
559
|
# initialize the header from target/cpu/etc, target in ['exe' 'dll' 'kmod' 'obj']
|
562
|
-
def pre_encode_header(target
|
560
|
+
def pre_encode_header(target='exe', want_relocs=true)
|
563
561
|
target = {:bin => 'exe', :lib => 'dll', :obj => 'obj', 'sys' => 'kmod', 'drv' => 'kmod'}.fetch(target, target)
|
564
562
|
|
565
563
|
@header.machine ||= case @cpu.shortname
|
@@ -650,11 +648,11 @@ class COFF
|
|
650
648
|
|
651
649
|
# append the section bodies to @encoded, and link the resulting binary
|
652
650
|
def encode_sections_fixup
|
653
|
-
@encoded.align @optheader.file_align
|
654
651
|
if @optheader.headers_size.kind_of?(::String)
|
655
652
|
@encoded.fixup! @optheader.headers_size => @encoded.virtsize
|
656
653
|
@optheader.headers_size = @encoded.virtsize
|
657
654
|
end
|
655
|
+
@encoded.align @optheader.file_align
|
658
656
|
|
659
657
|
baseaddr = @optheader.image_base.kind_of?(::Integer) ? @optheader.image_base : 0x400000
|
660
658
|
binding = @encoded.binding(baseaddr)
|
@@ -689,7 +687,7 @@ class COFF
|
|
689
687
|
# patch the iat where iat_p was defined
|
690
688
|
# sort to ensure a 0-terminated will not overwrite an entry
|
691
689
|
# (try to dump notepad.exe, which has a forwarder;)
|
692
|
-
@imports.find_all { |id| id.iat_p.kind_of?
|
690
|
+
@imports.find_all { |id| id.iat_p.kind_of?(Integer) }.sort_by { |id| id.iat_p }.each { |id|
|
693
691
|
s = sect_at_rva(id.iat_p)
|
694
692
|
@encoded[s.rawaddr + s.encoded.ptr, id.iat.virtsize] = id.iat
|
695
693
|
binding.update id.iat.binding(baseaddr + id.iat_p)
|
@@ -710,7 +708,7 @@ class COFF
|
|
710
708
|
# creates the base relocation tables (need for references to IAT not known before)
|
711
709
|
# defaults to generating relocatable files, eg ALSR-aware
|
712
710
|
# pass want_relocs=false to avoid the file overhead induced by this
|
713
|
-
def encode(target
|
711
|
+
def encode(target='exe', want_relocs=true)
|
714
712
|
@encoded = EncodedData.new
|
715
713
|
label_at(@encoded, 0, 'coff_start')
|
716
714
|
pre_encode_header(target, want_relocs)
|
@@ -832,7 +830,7 @@ class COFF
|
|
832
830
|
@lexer.unreadtok tok if not tok = @lexer.readtok or tok.type != :punct or tok.raw != '='
|
833
831
|
raise instr, 'invalid base' if not s.virtaddr = Expression.parse(@lexer).reduce or not s.virtaddr.kind_of?(::Integer)
|
834
832
|
if not @optheader.image_base
|
835
|
-
|
833
|
+
@optheader.image_base = (s.virtaddr-0x80) & 0xfff00000
|
836
834
|
puts "Warning: no image_base specified, using #{Expression[@optheader.image_base]}" if $VERBOSE
|
837
835
|
end
|
838
836
|
s.virtaddr -= @optheader.image_base
|
@@ -43,6 +43,7 @@ class DEX < ExeFormat
|
|
43
43
|
|
44
44
|
|
45
45
|
class SerialStruct < Metasm::SerialStruct
|
46
|
+
# TODO move uleb/sleb to new_field for sizeof
|
46
47
|
new_int_field :u2, :u4, :uleb, :sleb
|
47
48
|
end
|
48
49
|
|
@@ -135,7 +136,7 @@ class DEX < ExeFormat
|
|
135
136
|
|
136
137
|
class MethodId < SerialStruct
|
137
138
|
u2 :classidx
|
138
|
-
u2 :
|
139
|
+
u2 :protoidx
|
139
140
|
u4 :nameidx
|
140
141
|
end
|
141
142
|
|
@@ -182,7 +183,7 @@ class DEX < ExeFormat
|
|
182
183
|
uleb :fieldid_diff # this field id - array.previous field id
|
183
184
|
uleb :access
|
184
185
|
|
185
|
-
attr_accessor :field
|
186
|
+
attr_accessor :fieldid, :field
|
186
187
|
end
|
187
188
|
|
188
189
|
class EncodedMethod < SerialStruct
|
@@ -190,7 +191,7 @@ class DEX < ExeFormat
|
|
190
191
|
uleb :access
|
191
192
|
uleb :codeoff # offset to CodeItem
|
192
193
|
|
193
|
-
attr_accessor :method, :code, :name
|
194
|
+
attr_accessor :methodid, :method, :code, :name
|
194
195
|
end
|
195
196
|
|
196
197
|
class TypeItem < SerialStruct
|
@@ -256,7 +257,7 @@ class DEX < ExeFormat
|
|
256
257
|
uleb :typeidx
|
257
258
|
uleb :handleroff
|
258
259
|
end
|
259
|
-
|
260
|
+
|
260
261
|
class Link < SerialStruct
|
261
262
|
# undefined
|
262
263
|
end
|
@@ -328,6 +329,8 @@ class DEX < ExeFormat
|
|
328
329
|
def encode_u4(val) Expression[val].encode(:u32, @endianness) end
|
329
330
|
def decode_u2(edata = @encoded) edata.decode_imm(:u16, @endianness) end
|
330
331
|
def decode_u4(edata = @encoded) edata.decode_imm(:u32, @endianness) end
|
332
|
+
def sizeof_u2 ; 2 ; end
|
333
|
+
def sizeof_u4 ; 4 ; end
|
331
334
|
def decode_uleb(ed = @encoded, signed=false)
|
332
335
|
v = s = 0
|
333
336
|
while s < 5*7
|
@@ -390,6 +393,7 @@ class DEX < ExeFormat
|
|
390
393
|
(c.data.direct_methods + [0] + c.data.virtual_methods).each { |m|
|
391
394
|
next id=0 if m == 0
|
392
395
|
id += m.methodid_diff
|
396
|
+
m.methodid = id
|
393
397
|
m.method = @methods[id]
|
394
398
|
m.name = @strings[m.method.nameidx]
|
395
399
|
@encoded.ptr = m.codeoff
|
@@ -441,7 +445,11 @@ class DEX < ExeFormat
|
|
441
445
|
end
|
442
446
|
|
443
447
|
def get_default_entrypoints
|
444
|
-
|
448
|
+
@classes.find_all { |c| c.data }.map { |c|
|
449
|
+
(c.data.direct_methods + c.data.virtual_methods).map { |m|
|
450
|
+
m.codeoff+m.code.insns_off
|
451
|
+
}
|
452
|
+
}.flatten
|
445
453
|
end
|
446
454
|
end
|
447
455
|
|
@@ -21,29 +21,52 @@ class ELF < ExeFormat
|
|
21
21
|
TYPE_HIPROC = 0xffff
|
22
22
|
|
23
23
|
MACHINE = {
|
24
|
-
0 => 'NONE',
|
25
|
-
4 => '68K',
|
26
|
-
8 => 'MIPS',
|
27
|
-
15 => 'PARISC',
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
48 => 'H8S', 49 => 'H8_500', 50 => 'IA_64', 51 => 'MIPS_X',
|
24
|
+
0 => 'NONE', 1 => 'M32', 2 => 'SPARC', 3 => '386',
|
25
|
+
4 => '68K', 5 => '88K', 6 => '486', 7 => '860',
|
26
|
+
8 => 'MIPS', 9 => 'S370', 10 => 'MIPS_RS3_LE',
|
27
|
+
15 => 'PARISC', 17 => 'VPP500', 18 => 'SPARC32PLUS', 19 => '960',
|
28
|
+
20 => 'PPC', 21 => 'PPC64', 22 => 'S390', 23 => 'SPU',
|
29
|
+
36 => 'V800', 37 => 'FR20', 38 => 'RH32', 39 => 'MCORE',
|
30
|
+
40 => 'ARM', 41 => 'ALPHA', 42 => 'SH', 43 => 'SPARCV9',
|
31
|
+
44 => 'TRICORE', 45 => 'ARC', 46 => 'H8_300', 47 => 'H8_300H',
|
32
|
+
48 => 'H8S', 49 => 'H8_500', 50 => 'IA_64', 51 => 'MIPS_X',
|
34
33
|
52 => 'COLDFIRE', 53 => '68HC12', 54 => 'MMA', 55 => 'PCP',
|
35
|
-
56 => 'NCPU',
|
36
|
-
60 => 'ST100', 61 => 'TINYJ',
|
37
|
-
66 => 'FX66',
|
38
|
-
68 => 'ST7',
|
39
|
-
72 => '68HC05',73 => 'SVX',
|
40
|
-
76 => 'CRIS',
|
41
|
-
80 => 'MMIX',
|
42
|
-
84 => 'FR30',
|
43
|
-
88 => 'M32R',
|
44
|
-
92 => 'OPENRISC', 93 => 'ARC_A5', 94 => 'XTENSA',
|
45
|
-
99 => '
|
46
|
-
|
34
|
+
56 => 'NCPU', 57 => 'NDR1', 58 => 'STARCORE', 59 => 'ME16',
|
35
|
+
60 => 'ST100', 61 => 'TINYJ', 62 => 'X86_64', 63 => 'PDSP',
|
36
|
+
64 => 'PDP10', 65 => 'PDP11', 66 => 'FX66', 67 => 'ST9PLUS',
|
37
|
+
68 => 'ST7', 69 => '68HC16', 70 => '68HC11', 71 => '68HC08',
|
38
|
+
72 => '68HC05',73 => 'SVX', 74 => 'ST19', 75 => 'VAX',
|
39
|
+
76 => 'CRIS', 77 => 'JAVELIN',78 => 'FIREPATH', 79 => 'ZSP',
|
40
|
+
80 => 'MMIX', 81 => 'HUANY', 82 => 'PRISM', 83 => 'AVR',
|
41
|
+
84 => 'FR30', 85 => 'D10V', 86 => 'D30V', 87 => 'V850',
|
42
|
+
88 => 'M32R', 89 => 'MN10300',90 => 'MN10200',91 => 'PJ',
|
43
|
+
92 => 'OPENRISC', 93 => 'ARC_A5', 94 => 'XTENSA', 95 => 'VIDEOCORE',
|
44
|
+
96 => 'TMM_GPP', 97 => 'NS32K', 98 => 'TPC', 99 => 'SNP1K',
|
45
|
+
100 => 'ST200', 101 => 'IP2K', 102 => 'MAX', 103 => 'CR',
|
46
|
+
104 => 'F2MC16', 105 => 'MSP430', 106 => 'BLACKFIN', 107 => 'SE_C33',
|
47
|
+
108 => 'SEP', 109 => 'ARCA', 110 => 'UNICORE', 111 => 'EXCESS',
|
48
|
+
112 => 'DXP', 113 => 'ALTERA_NIOS2', 114 => 'CRX', 115 => 'XGATE',
|
49
|
+
116 => 'C166', 117 => 'M16C', 118 => 'DSPIC30F', 119 => 'CE',
|
50
|
+
120 => 'M32C',
|
51
|
+
131 => 'TSK3000', 132 => 'RS08', 133 => 'SHARC',
|
52
|
+
134 => 'ECOG2', 135 => 'SCORE7', 136 => 'DSP24', 137 => 'VIDEOCORE3',
|
53
|
+
138 => 'LATTICEMICO32', 139 => 'SE_C17', 140 => 'TI_C6000', 141 => 'TI_C2000',
|
54
|
+
142 => 'TI_C5500',
|
55
|
+
160 => 'MMDSP_PLUS', 161 => 'CYPRESS_M8C', 162 => 'R32C', 163 => 'TRIMEDIA',
|
56
|
+
164 => 'QDSP6', 165 => '8051', 166 => 'STXP7X', 167 => 'NDS32',
|
57
|
+
168 => 'ECOG1', 169 => 'MAXQ30', 170 => 'XIMO16', 171 => 'MANIK',
|
58
|
+
172 => 'CRAYNV2', 173 => 'RX', 174 => 'METAG', 175 => 'MCST_ELBRUS',
|
59
|
+
176 => 'ECOG16', 177 => 'CR16', 178 => 'ETPU', 179 => 'SLE9X',
|
60
|
+
180 => 'L10M', 181 => 'K10M', 182 => 'INTEL_RESV', 183 => 'AARCH64',
|
61
|
+
184 => 'ARM_RESV', 185 => 'AVR32', 186 => 'STM8', 187 => 'TILE64',
|
62
|
+
188 => 'TILEPRO', 189 => 'MICROBLAZE', 190 => 'CUDA', 191 => 'TILEGX',
|
63
|
+
192 => 'CLOUDSHIELD', 193 => 'COREA_1ST', 194 => 'COREA_2ND', 195 => 'ARC_COMPACT2',
|
64
|
+
196 => 'OPEN8', 197 => 'RL78', 198 => 'VIDEOCORE5', 199 => '78KOR',
|
65
|
+
200 => '56800EX', 201 => 'BA1', 202 => 'BA2', 203 => 'XCORE',
|
66
|
+
204 => 'MCHP_PIC', 205 => 'INTEL205', 206 => 'INTEL206', 207 => 'INTEL207',
|
67
|
+
208 => 'INTEL208', 209 => 'INTEL209', 210 => 'KM32', 211 => 'KMX32',
|
68
|
+
212 => 'KMX16', 213 => 'KMX8', 214 => 'KVARC', 215 => 'CDP',
|
69
|
+
216 => 'COGE', 217 => 'COOL', 218 => 'NORC',
|
47
70
|
}
|
48
71
|
|
49
72
|
FLAGS = {
|
@@ -52,8 +75,9 @@ class ELF < ExeFormat
|
|
52
75
|
0x8000_0000 => 'LEDATA'},
|
53
76
|
'SPARCV9' => {0 => 'TSO', 1 => 'PSO', 2 => 'RMO'}, # XXX not a flag
|
54
77
|
'MIPS' => {1 => 'NOREORDER', 2 => 'PIC', 4 => 'CPIC',
|
55
|
-
8 => 'XGOT',
|
56
|
-
|
78
|
+
8 => 'XGOT', 0x10 => '64BIT_WHIRL', 0x20 => 'ABI2',
|
79
|
+
0x40 => 'ABI_ON32', 0x80 => 'OPTIONSFIRST',
|
80
|
+
0x100 => '32BITMODE'}
|
57
81
|
}
|
58
82
|
|
59
83
|
DYNAMIC_TAG = { 0 => 'NULL', 1 => 'NEEDED', 2 => 'PLTRELSZ', 3 =>
|
@@ -300,6 +324,37 @@ class ELF < ExeFormat
|
|
300
324
|
112 => 'EMB_RELST_LO', 113 => 'EMB_RELST_HI',
|
301
325
|
114 => 'EMB_RELST_HA', 115 => 'EMB_BIT_FLD',
|
302
326
|
116 => 'EMB_RELSDA' },
|
327
|
+
'SH' => { 0 => 'NONE', 1 => 'DIR32', 2 => 'REL32', 3 => 'DIR8WPN',
|
328
|
+
4 => 'IND12W', 5 => 'DIR8WPL', 6 => 'DIR8WPZ', 7 => 'DIR8BP',
|
329
|
+
8 => 'DIR8W', 9 => 'DIR8L', 10 => 'LOOP_START', 11 => 'LOOP_END',
|
330
|
+
22 => 'GNU_VTINHERIT', 23 => 'GNU_VTENTRY', 24 => 'SWITCH8',
|
331
|
+
25 => 'SWITCH16', 26 => 'SWITCH32', 27 => 'USES', 28 => 'COUNT',
|
332
|
+
29 => 'ALIGN', 30 => 'CODE', 31 => 'DATA', 32 => 'LABEL',
|
333
|
+
33 => 'DIR16', 34 => 'DIR8', 35 => 'DIR8UL', 36 => 'DIR8UW',
|
334
|
+
37 => 'DIR8U', 38 => 'DIR8SW', 39 => 'DIR8S', 40 => 'DIR4UL',
|
335
|
+
41 => 'DIR4UW', 42 => 'DIR4U', 43 => 'PSHA', 44 => 'PSHL',
|
336
|
+
45 => 'DIR5U', 46 => 'DIR6U', 47 => 'DIR6S', 48 => 'DIR10S',
|
337
|
+
49 => 'DIR10SW', 50 => 'DIR10SL', 51 => 'DIR10SQ', 53 => 'DIR16S',
|
338
|
+
144 => 'TLS_GD_32', 145 => 'TLS_LD_32', 146 => 'TLS_LDO_32',
|
339
|
+
147 => 'TLS_IE_32', 148 => 'TLS_LE_32', 149 => 'TLS_DTPMOD32',
|
340
|
+
150 => 'TLS_DTPOFF32', 151 => 'TLS_TPOFF32', 160 => 'GOT32',
|
341
|
+
161 => 'PLT32', 162 => 'COPY', 163 => 'GLOB_DAT',
|
342
|
+
164 => 'JMP_SLOT', 165 => 'RELATIVE', 166 => 'GOTOFF',
|
343
|
+
167 => 'GOTPC', 168 => 'GOTPLT32', 169 => 'GOT_LOW16',
|
344
|
+
170 => 'GOT_MEDLOW16', 171 => 'GOT_MEDHI16', 172 => 'GOT_HI16',
|
345
|
+
173 => 'GOTPLT_LOW16', 174 => 'GOTPLT_MEDLOW16', 175 => 'GOTPLT_MEDHI16',
|
346
|
+
176 => 'GOTPLT_HI16', 177 => 'PLT_LOW16', 178 => 'PLT_MEDLOW16',
|
347
|
+
179 => 'PLT_MEDHI16', 180 => 'PLT_HI16', 181 => 'GOTOFF_LOW16',
|
348
|
+
182 => 'GOTOFF_MEDLOW16', 183 => 'GOTOFF_MEDHI16', 184 => 'GOTOFF_HI16',
|
349
|
+
185 => 'GOTPC_LOW16', 186 => 'GOTPC_MEDLOW16', 187 => 'GOTPC_MEDHI16',
|
350
|
+
188 => 'GOTPC_HI16', 189 => 'GOT10BY4', 190 => 'GOTPLT10BY4',
|
351
|
+
191 => 'GOT10BY8', 192 => 'GOTPLT10BY8', 193 => 'COPY64',
|
352
|
+
194 => 'GLOB_DAT64', 195 => 'JMP_SLOT64', 196 => 'RELATIVE64',
|
353
|
+
242 => 'SHMEDIA_CODE', 243 => 'PT_16', 244 => 'IMMS16',
|
354
|
+
245 => 'IMMU16', 246 => 'IMM_LOW16', 247 => 'IMM_LOW16_PCREL',
|
355
|
+
248 => 'IMM_MEDLOW16', 249 => 'IMM_MEDLOW16_PCREL', 250 => 'IMM_MEDHI16',
|
356
|
+
251 => 'IMM_MEDHI16_PCREL', 252 => 'IMM_HI16', 253 => 'IMM_HI16_PCREL',
|
357
|
+
254 => '64', 255 => '64_PCREL' },
|
303
358
|
'SPARC' => { 0 => 'NONE', 1 => '8', 2 => '16', 3 => '32',
|
304
359
|
4 => 'DISP8', 5 => 'DISP16', 6 => 'DISP32',
|
305
360
|
7 => 'WDISP30', 8 => 'WDISP22', 9 => 'HI22',
|
@@ -362,11 +417,6 @@ class ELF < ExeFormat
|
|
362
417
|
word :flags
|
363
418
|
fld_bits(:flags) { |elf, hdr| FLAGS[hdr.machine] || {} }
|
364
419
|
halfs :ehsize, :phentsize, :phnum, :shentsize, :shnum, :shstrndx
|
365
|
-
|
366
|
-
def self.size elf
|
367
|
-
x = elf.bitsize >> 3
|
368
|
-
40 + 3*x
|
369
|
-
end
|
370
420
|
end
|
371
421
|
|
372
422
|
class Segment < SerialStruct
|
@@ -380,11 +430,6 @@ class ELF < ExeFormat
|
|
380
430
|
else Segment64
|
381
431
|
end
|
382
432
|
end
|
383
|
-
|
384
|
-
def self.size elf
|
385
|
-
x = elf.bitsize >> 3
|
386
|
-
8 + 6*x
|
387
|
-
end
|
388
433
|
end
|
389
434
|
|
390
435
|
class Segment32 < Segment
|
@@ -421,11 +466,6 @@ class ELF < ExeFormat
|
|
421
466
|
xword :entsize
|
422
467
|
|
423
468
|
attr_accessor :name, :encoded
|
424
|
-
|
425
|
-
def self.size elf
|
426
|
-
x = elf.bitsize >> 3
|
427
|
-
16 + 6*x
|
428
|
-
end
|
429
469
|
end
|
430
470
|
|
431
471
|
class Symbol < SerialStruct
|
@@ -439,11 +479,6 @@ class ELF < ExeFormat
|
|
439
479
|
|
440
480
|
attr_accessor :name_p, :value, :size, :bind, :type, :other, :shndx
|
441
481
|
attr_accessor :name, :thunk
|
442
|
-
|
443
|
-
def self.size elf
|
444
|
-
x = elf.bitsize >> 3
|
445
|
-
8 + 2*x
|
446
|
-
end
|
447
482
|
end
|
448
483
|
|
449
484
|
class Symbol32 < Symbol
|
@@ -478,12 +513,6 @@ class ELF < ExeFormat
|
|
478
513
|
end
|
479
514
|
|
480
515
|
def addend ; end
|
481
|
-
|
482
|
-
def self.size elf
|
483
|
-
x = elf.bitsize >> 3
|
484
|
-
2*x
|
485
|
-
end
|
486
|
-
|
487
516
|
end
|
488
517
|
class Relocation32 < Relocation
|
489
518
|
addr :offset
|
@@ -506,11 +535,6 @@ class ELF < ExeFormat
|
|
506
535
|
else RelocationAddend64
|
507
536
|
end
|
508
537
|
end
|
509
|
-
def self.size elf
|
510
|
-
x = elf.bitsize >> 3
|
511
|
-
3*x
|
512
|
-
end
|
513
|
-
|
514
538
|
end
|
515
539
|
class RelocationAddend32 < RelocationAddend
|
516
540
|
addr :offset
|
@@ -637,6 +661,15 @@ class ELF < ExeFormat
|
|
637
661
|
end
|
638
662
|
|
639
663
|
def shortname; 'elf'; end
|
664
|
+
|
665
|
+
def sizeof_byte ; 1 ; end
|
666
|
+
def sizeof_half ; 2 ; end
|
667
|
+
def sizeof_word ; 4 ; end
|
668
|
+
def sizeof_sword ; 4 ; end
|
669
|
+
def sizeof_xword ; @bitsize == 32 ? 4 : 8 ; end
|
670
|
+
alias sizeof_sxword sizeof_xword
|
671
|
+
alias sizeof_addr sizeof_xword
|
672
|
+
alias sizeof_off sizeof_xword
|
640
673
|
end
|
641
674
|
|
642
675
|
class LoadedELF < ELF
|
@@ -689,6 +722,9 @@ class FatELF < ExeFormat
|
|
689
722
|
def decode_byte(edata = @encoded) edata.decode_imm(:u8, @endianness) end
|
690
723
|
def decode_word(edata = @encoded) edata.decode_imm(:u16, @endianness) end
|
691
724
|
def decode_qword(edata = @encoded) edata.decode_imm(:u64, @endianness) end
|
725
|
+
def sizeof_byte ; 1 ; end
|
726
|
+
def sizeof_word ; 2 ; end
|
727
|
+
def sizeof_qword ; 8 ; end
|
692
728
|
|
693
729
|
attr_accessor :header, :list
|
694
730
|
def initialize
|
@@ -716,7 +752,7 @@ class FatELF < ExeFormat
|
|
716
752
|
f.encoded = e.encode_string
|
717
753
|
h = e.header
|
718
754
|
f.machine, f.abi, f.abi_version, f.e_class, f.data =
|
719
|
-
|
755
|
+
h.machine, h.abi, h.abi_version, h.e_class, h.data
|
720
756
|
end
|
721
757
|
f.offset = new_label('fat_off')
|
722
758
|
f.size = f.encoded.size
|
@@ -812,7 +848,7 @@ typedef struct { /* Verneed Auxiliary Structure. */
|
|
812
848
|
Elf32_Word vna_next; /* no. of bytes from start of this */
|
813
849
|
} Elf32_Vernaux; /* vernaux to next vernaux entry */
|
814
850
|
|
815
|
-
typedef Elf32_Half
|
851
|
+
typedef Elf32_Half Elf32_Versym; /* Version symbol index array */
|
816
852
|
|
817
853
|
typedef struct {
|
818
854
|
Elf32_Half si_boundto; /* direct bindings - symbol bound to */
|
@@ -18,19 +18,19 @@ class ELF
|
|
18
18
|
case hdr.e_class
|
19
19
|
when '32'; elf.bitsize = 32
|
20
20
|
when '64', '64_icc'; elf.bitsize = 64
|
21
|
-
else
|
21
|
+
else puts "W: ELF: unsupported class #{hdr.e_class}, assuming 32bit"; elf.bitsize = 32
|
22
22
|
end
|
23
23
|
|
24
24
|
case hdr.data
|
25
25
|
when 'LSB'; elf.endianness = :little
|
26
26
|
when 'MSB'; elf.endianness = :big
|
27
|
-
else
|
27
|
+
else puts "W: ELF: unsupported endianness #{hdr.data}, assuming littleendian"; elf.endianness = :little
|
28
28
|
end
|
29
29
|
|
30
30
|
if hdr.i_version != 'CURRENT'
|
31
|
-
|
31
|
+
puts ":: ELF: unsupported ELF version #{hdr.i_version}"
|
32
32
|
end
|
33
|
-
|
33
|
+
}
|
34
34
|
end
|
35
35
|
|
36
36
|
class Symbol
|
@@ -66,7 +66,7 @@ class ELF
|
|
66
66
|
# handles relocated LoadedELF
|
67
67
|
def addr_to_fileoff(addr)
|
68
68
|
la = module_address
|
69
|
-
|
69
|
+
la = (la == 0 ? (@load_address ||= 0) : 0)
|
70
70
|
addr_to_off(addr - la)
|
71
71
|
end
|
72
72
|
|
@@ -75,7 +75,7 @@ class ELF
|
|
75
75
|
def fileoff_to_addr(foff)
|
76
76
|
if s = @segments.find { |s_| s_.type == 'LOAD' and s_.offset <= foff and s_.offset + s_.filesz > foff }
|
77
77
|
la = module_address
|
78
|
-
|
78
|
+
la = (la == 0 ? (@load_address ||= 0) : 0)
|
79
79
|
s.vaddr + la + foff - s.offset
|
80
80
|
end
|
81
81
|
end
|
@@ -106,7 +106,7 @@ class ELF
|
|
106
106
|
def decode_header(off = 0, decode_phdr=true, decode_shdr=true)
|
107
107
|
@encoded.ptr = off
|
108
108
|
@header.decode self
|
109
|
-
raise InvalidExeFormat, "Invalid elf header size: #{@header.ehsize}" if Header.
|
109
|
+
raise InvalidExeFormat, "Invalid elf header size: #{@header.ehsize}" if Header.sizeof(self) != @header.ehsize
|
110
110
|
if decode_phdr and @header.phoff != 0
|
111
111
|
decode_program_header(@header.phoff+off)
|
112
112
|
end
|
@@ -118,7 +118,7 @@ class ELF
|
|
118
118
|
# decodes the section header
|
119
119
|
# section names are read from shstrndx if possible
|
120
120
|
def decode_section_header(off = @header.shoff)
|
121
|
-
raise InvalidExeFormat, "Invalid elf section header size: #{@header.shentsize}" if Section.
|
121
|
+
raise InvalidExeFormat, "Invalid elf section header size: #{@header.shentsize}" if Section.sizeof(self) != @header.shentsize
|
122
122
|
@encoded.add_export new_label('section_header'), off
|
123
123
|
@encoded.ptr = off
|
124
124
|
@sections = []
|
@@ -137,7 +137,7 @@ class ELF
|
|
137
137
|
# decodes the program header table
|
138
138
|
# marks the elf entrypoint as an export of +self.encoded+
|
139
139
|
def decode_program_header(off = @header.phoff)
|
140
|
-
raise InvalidExeFormat, "Invalid elf program header size: #{@header.phentsize}" if Segment.
|
140
|
+
raise InvalidExeFormat, "Invalid elf program header size: #{@header.phentsize}" if Segment.sizeof(self) != @header.phentsize
|
141
141
|
@encoded.add_export new_label('program_header'), off
|
142
142
|
@encoded.ptr = off
|
143
143
|
@segments = []
|
@@ -224,7 +224,40 @@ class ELF
|
|
224
224
|
# (gnu_hash(sym[N].name) & ~1) | (N == dynsymcount-1 || (gnu_hash(sym[N].name) % nbucket) != (gnu_hash(sym[N+1].name) % nbucket))
|
225
225
|
# that's the hash, with its lower bit replaced by the bool [1 if i am the last sym having my hash as hash]
|
226
226
|
|
227
|
-
|
227
|
+
# we're going to decode the symbol table, and we just want to get the nr of symbols to read
|
228
|
+
if just_get_count
|
229
|
+
# index of highest hashed (exported) symbols
|
230
|
+
ns = hsymcount+symndx
|
231
|
+
|
232
|
+
# no way to get the number of non-exported symbols from what we have here
|
233
|
+
# so we'll decode all relocs and use the largest index we see..
|
234
|
+
rels = []
|
235
|
+
if @encoded.ptr = @tag['REL'] and @tag['RELENT'] == Relocation.sizeof(self)
|
236
|
+
p_end = @encoded.ptr + @tag['RELSZ']
|
237
|
+
while @encoded.ptr < p_end
|
238
|
+
rels << Relocation.decode(self)
|
239
|
+
end
|
240
|
+
end
|
241
|
+
if @encoded.ptr = @tag['RELA'] and @tag['RELAENT'] == RelocationAddend.sizeof(self)
|
242
|
+
p_end = @encoded.ptr + @tag['RELASZ']
|
243
|
+
while @encoded.ptr < p_end
|
244
|
+
rels << RelocationAddend.decode(self)
|
245
|
+
end
|
246
|
+
end
|
247
|
+
if @encoded.ptr = @tag['JMPREL'] and relcls = case @tag['PLTREL']
|
248
|
+
when 'REL'; Relocation
|
249
|
+
when 'RELA'; RelocationAddend
|
250
|
+
end
|
251
|
+
p_end = @encoded.ptr + @tag['PLTRELSZ']
|
252
|
+
while @encoded.ptr < p_end
|
253
|
+
rels << relcls.decode(self)
|
254
|
+
end
|
255
|
+
end
|
256
|
+
maxr = rels.map { |rel| rel.symbol }.grep(::Integer).max || -1
|
257
|
+
|
258
|
+
return [ns, maxr+1].max
|
259
|
+
end
|
260
|
+
|
228
261
|
|
229
262
|
# TODO
|
230
263
|
end
|
@@ -359,7 +392,7 @@ class ELF
|
|
359
392
|
def decode_segments_symbols
|
360
393
|
return unless @tag['STRTAB'] and @tag['STRSZ'] and @tag['SYMTAB'] and (@tag['HASH'] or @tag['GNU_HASH'])
|
361
394
|
|
362
|
-
raise "E: ELF: unsupported symbol entry size: #{@tag['SYMENT']}" if @tag['SYMENT'] != Symbol.
|
395
|
+
raise "E: ELF: unsupported symbol entry size: #{@tag['SYMENT']}" if @tag['SYMENT'] != Symbol.sizeof(self)
|
363
396
|
|
364
397
|
# find number of symbols
|
365
398
|
if @tag['HASH']
|
@@ -394,14 +427,16 @@ class ELF
|
|
394
427
|
@encoded.ptr = sec.offset
|
395
428
|
syms = []
|
396
429
|
raise 'Invalid symbol table' if sec.size > @encoded.length
|
397
|
-
(sec.size / Symbol.
|
430
|
+
(sec.size / Symbol.sizeof(self)).times { syms << Symbol.decode(self, strtab) }
|
398
431
|
alreadysegs = true if @header.type == 'DYN' or @header.type == 'EXEC'
|
432
|
+
alreadysyms = @symbols.inject({}) { |h, s| h.update s.name => true } if alreadysegs
|
399
433
|
syms.each { |s|
|
400
434
|
if alreadysegs
|
401
435
|
# if we already decoded the symbols from the DYNAMIC segment,
|
402
436
|
# ignore dups and imports from this section
|
403
437
|
next if s.shndx == 'UNDEF'
|
404
|
-
next if
|
438
|
+
next if alreadysyms[s.name]
|
439
|
+
alreadysyms[s.name] = true
|
405
440
|
end
|
406
441
|
@symbols << s
|
407
442
|
decode_symbol_export(s)
|
@@ -445,7 +480,7 @@ class ELF
|
|
445
480
|
def decode_segments_relocs
|
446
481
|
@relocations.clear
|
447
482
|
if @encoded.ptr = @tag['REL']
|
448
|
-
raise "E: ELF: unsupported rel entry size #{@tag['RELENT']}" if @tag['RELENT'] != Relocation.
|
483
|
+
raise "E: ELF: unsupported rel entry size #{@tag['RELENT']}" if @tag['RELENT'] != Relocation.sizeof(self)
|
449
484
|
p_end = @encoded.ptr + @tag['RELSZ']
|
450
485
|
while @encoded.ptr < p_end
|
451
486
|
@relocations << Relocation.decode(self)
|
@@ -453,7 +488,7 @@ class ELF
|
|
453
488
|
end
|
454
489
|
|
455
490
|
if @encoded.ptr = @tag['RELA']
|
456
|
-
raise "E: ELF: unsupported rela entry size #{@tag['RELAENT'].inspect}" if @tag['RELAENT'] != RelocationAddend.
|
491
|
+
raise "E: ELF: unsupported rela entry size #{@tag['RELAENT'].inspect}" if @tag['RELAENT'] != RelocationAddend.sizeof(self)
|
457
492
|
p_end = @encoded.ptr + @tag['RELASZ']
|
458
493
|
while @encoded.ptr < p_end
|
459
494
|
@relocations << RelocationAddend.decode(self)
|
@@ -509,10 +544,28 @@ class ELF
|
|
509
544
|
end
|
510
545
|
end
|
511
546
|
|
547
|
+
# returns the target of a relocation using reloc.symbol
|
548
|
+
# may create new labels if the relocation targets a section
|
549
|
+
def reloc_target(reloc)
|
550
|
+
target = 0
|
551
|
+
if reloc.symbol.kind_of?(Symbol)
|
552
|
+
if reloc.symbol.type == 'SECTION'
|
553
|
+
s = @sections[reloc.symbol.shndx]
|
554
|
+
if not target = @encoded.inv_export[s.offset]
|
555
|
+
target = new_label(s.name)
|
556
|
+
@encoded.add_export(target, s.offset)
|
557
|
+
end
|
558
|
+
elsif reloc.symbol.name
|
559
|
+
target = reloc.symbol.name
|
560
|
+
end
|
561
|
+
end
|
562
|
+
target
|
563
|
+
end
|
564
|
+
|
512
565
|
# returns the Metasm::Relocation that should be applied for reloc
|
513
566
|
# self.encoded.ptr must point to the location that will be relocated (for implicit addends)
|
514
567
|
def arch_decode_segments_reloc_386(reloc)
|
515
|
-
if reloc.symbol and n = reloc.symbol.name and reloc.symbol.shndx == 'UNDEF' and @sections and
|
568
|
+
if reloc.symbol.kind_of?(Symbol) and n = reloc.symbol.name and reloc.symbol.shndx == 'UNDEF' and @sections and
|
516
569
|
s = @sections.find { |s_| s_.name and s_.offset <= @encoded.ptr and s_.offset + s_.size > @encoded.ptr }
|
517
570
|
@encoded.add_export(new_label("#{s.name}_#{n}"), @encoded.ptr, true)
|
518
571
|
end
|
@@ -541,15 +594,14 @@ class ELF
|
|
541
594
|
when 'GLOB_DAT', 'JMP_SLOT', '32', 'PC32', 'TLS_TPOFF', 'TLS_TPOFF32'
|
542
595
|
# XXX use versionned version
|
543
596
|
# lazy jmp_slot ?
|
544
|
-
target =
|
545
|
-
target = reloc.symbol.name if reloc.symbol.kind_of?(Symbol) and reloc.symbol.name
|
597
|
+
target = reloc_target(reloc)
|
546
598
|
target = Expression[target, :-, reloc.offset] if reloc.type == 'PC32'
|
547
599
|
target = Expression[target, :+, addend] if addend and addend != 0
|
548
600
|
target = Expression[target, :+, 'tlsoffset'] if reloc.type == 'TLS_TPOFF'
|
549
601
|
target = Expression[:-, [target, :+, 'tlsoffset']] if reloc.type == 'TLS_TPOFF32'
|
550
602
|
when 'COPY'
|
551
603
|
# mark the address pointed as a copy of the relocation target
|
552
|
-
if not reloc.symbol or not name = reloc.symbol.name
|
604
|
+
if not reloc.symbol.kind_of?(Symbol) or not name = reloc.symbol.name
|
553
605
|
puts "W: Elf: symbol to COPY has no name: #{reloc.inspect}" if $VERBOSE
|
554
606
|
name = ''
|
555
607
|
end
|
@@ -567,24 +619,40 @@ class ELF
|
|
567
619
|
# returns the Metasm::Relocation that should be applied for reloc
|
568
620
|
# self.encoded.ptr must point to the location that will be relocated (for implicit addends)
|
569
621
|
def arch_decode_segments_reloc_mips(reloc)
|
570
|
-
if reloc.symbol and n = reloc.symbol.name and reloc.symbol.shndx == 'UNDEF' and @sections and
|
622
|
+
if reloc.symbol.kind_of?(Symbol) and n = reloc.symbol.name and reloc.symbol.shndx == 'UNDEF' and @sections and
|
571
623
|
s = @sections.find { |s_| s_.name and s_.offset <= @encoded.ptr and s_.offset + s_.size > @encoded.ptr }
|
572
624
|
@encoded.add_export(new_label("#{s.name}_#{n}"), @encoded.ptr, true)
|
573
625
|
end
|
574
626
|
|
627
|
+
original_word = decode_word
|
628
|
+
|
575
629
|
# decode addend if needed
|
576
630
|
case reloc.type
|
577
631
|
when 'NONE' # no addend
|
578
|
-
else addend = reloc.addend ||
|
632
|
+
else addend = reloc.addend || Expression.make_signed(original_word, 32)
|
579
633
|
end
|
580
634
|
|
581
635
|
case reloc.type
|
582
636
|
when 'NONE'
|
583
637
|
when '32', 'REL32'
|
584
|
-
target =
|
585
|
-
target = reloc.symbol.name if reloc.symbol.kind_of?(Symbol) and reloc.symbol.name
|
638
|
+
target = reloc_target(reloc)
|
586
639
|
target = Expression[target, :-, reloc.offset] if reloc.type == 'REL32'
|
587
640
|
target = Expression[target, :+, addend] if addend and addend != 0
|
641
|
+
when '26'
|
642
|
+
target = reloc_target(reloc)
|
643
|
+
addend &= 0x3ff_ffff
|
644
|
+
target = Expression[target, :+, [addend, :<<, 2]] if addend and addend != 0
|
645
|
+
target = Expression[[original_word, :&, 0xfc0_0000], :|, [[target, :&, 0x3ff_ffff], :>>, 2]]
|
646
|
+
when 'HI16'
|
647
|
+
target = reloc_target(reloc)
|
648
|
+
addend &= 0xffff
|
649
|
+
target = Expression[target, :+, [addend, :<<, 16]] if addend and addend != 0
|
650
|
+
target = Expression[[original_word, :&, 0xffff_0000], :|, [[target, :>>, 16], :&, 0xffff]]
|
651
|
+
when 'LO16'
|
652
|
+
target = reloc_target(reloc)
|
653
|
+
addend &= 0xffff
|
654
|
+
target = Expression[target, :+, addend] if addend and addend != 0
|
655
|
+
target = Expression[[original_word, :&, 0xffff_0000], :|, [target, :&, 0xffff]]
|
588
656
|
else
|
589
657
|
puts "W: Elf: unhandled MIPS reloc #{reloc.inspect}" if $VERBOSE
|
590
658
|
target = nil
|
@@ -596,7 +664,7 @@ class ELF
|
|
596
664
|
# returns the Metasm::Relocation that should be applied for reloc
|
597
665
|
# self.encoded.ptr must point to the location that will be relocated (for implicit addends)
|
598
666
|
def arch_decode_segments_reloc_x86_64(reloc)
|
599
|
-
if reloc.symbol and n = reloc.symbol.name and reloc.symbol.shndx == 'UNDEF' and @sections and
|
667
|
+
if reloc.symbol.kind_of?(Symbol) and n = reloc.symbol.name and reloc.symbol.shndx == 'UNDEF' and @sections and
|
600
668
|
s = @sections.find { |s_| s_.name and s_.offset <= @encoded.ptr and s_.offset + s_.size > @encoded.ptr }
|
601
669
|
@encoded.add_export(new_label("#{s.name}_#{n}"), @encoded.ptr, true)
|
602
670
|
end
|
@@ -627,14 +695,13 @@ class ELF
|
|
627
695
|
when 'GLOB_DAT', 'JMP_SLOT', '64', 'PC64', '32', 'PC32'
|
628
696
|
# XXX use versionned version
|
629
697
|
# lazy jmp_slot ?
|
630
|
-
target =
|
631
|
-
target = reloc.symbol.name if reloc.symbol.kind_of?(Symbol) and reloc.symbol.name
|
698
|
+
target = reloc_target(reloc)
|
632
699
|
target = Expression[target, :-, reloc.offset] if reloc.type == 'PC64' or reloc.type == 'PC32'
|
633
700
|
target = Expression[target, :+, addend] if addend and addend != 0
|
634
701
|
sz = :u32 if reloc.type == '32' or reloc.type == 'PC32'
|
635
702
|
when 'COPY'
|
636
703
|
# mark the address pointed as a copy of the relocation target
|
637
|
-
if not reloc.symbol or not name = reloc.symbol.name
|
704
|
+
if not reloc.symbol.kind_of?(Symbol) or not name = reloc.symbol.name
|
638
705
|
puts "W: Elf: symbol to COPY has no name: #{reloc.inspect}" if $VERBOSE
|
639
706
|
name = ''
|
640
707
|
end
|
@@ -649,6 +716,33 @@ class ELF
|
|
649
716
|
Metasm::Relocation.new(Expression[target], sz, @endianness) if target
|
650
717
|
end
|
651
718
|
|
719
|
+
def arch_decode_segments_reloc_sh(reloc)
|
720
|
+
if reloc.symbol.kind_of?(Symbol) and n = reloc.symbol.name and reloc.symbol.shndx == 'UNDEF' and @sections and
|
721
|
+
s = @sections.find { |s_| s_.name and s_.offset <= @encoded.ptr and s_.offset + s_.size > @encoded.ptr }
|
722
|
+
@encoded.add_export(new_label("#{s.name}_#{n}"), @encoded.ptr, true)
|
723
|
+
end
|
724
|
+
|
725
|
+
original_word = decode_word
|
726
|
+
|
727
|
+
# decode addend if needed
|
728
|
+
case reloc.type
|
729
|
+
when 'NONE' # no addend
|
730
|
+
else addend = reloc.addend || Expression.make_signed(original_word, 32)
|
731
|
+
end
|
732
|
+
|
733
|
+
case reloc.type
|
734
|
+
when 'NONE'
|
735
|
+
when 'GLOB_DAT', 'JMP_SLOT'
|
736
|
+
target = reloc_target(reloc)
|
737
|
+
target = Expression[target, :+, addend] if addend and addend != 0
|
738
|
+
else
|
739
|
+
puts "W: Elf: unhandled SH reloc #{reloc.inspect}" if $VERBOSE
|
740
|
+
target = nil
|
741
|
+
end
|
742
|
+
|
743
|
+
Metasm::Relocation.new(Expression[target], :u32, @endianness) if target
|
744
|
+
end
|
745
|
+
|
652
746
|
class DwarfDebug
|
653
747
|
# decode a DWARF2 'compilation unit'
|
654
748
|
def decode(elf, info, abbrev, str)
|
@@ -749,12 +843,13 @@ class ELF
|
|
749
843
|
end
|
750
844
|
|
751
845
|
# decodes the ELF dynamic tags, interpret them, and decodes symbols and relocs
|
752
|
-
def decode_segments_dynamic
|
846
|
+
def decode_segments_dynamic(decode_relocs=true)
|
753
847
|
return if not dynamic = @segments.find { |s| s.type == 'DYNAMIC' }
|
754
848
|
@encoded.ptr = add_label('dynamic_tags', dynamic.vaddr)
|
755
849
|
decode_tags
|
756
850
|
decode_segments_tags_interpret
|
757
851
|
decode_segments_symbols
|
852
|
+
return if not decode_relocs
|
758
853
|
decode_segments_relocs
|
759
854
|
decode_segments_relocs_interpret
|
760
855
|
end
|
@@ -783,6 +878,7 @@ class ELF
|
|
783
878
|
|
784
879
|
# decodes sections, interprets symbols/relocs, fills sections.encoded
|
785
880
|
def decode_sections
|
881
|
+
@symbols.clear # the NULL symbol is explicit in the symbol table
|
786
882
|
decode_sections_symbols
|
787
883
|
decode_sections_relocs
|
788
884
|
@sections.each { |s|
|
@@ -804,7 +900,7 @@ class ELF
|
|
804
900
|
end
|
805
901
|
|
806
902
|
def decode_exports
|
807
|
-
decode_segments_dynamic
|
903
|
+
decode_segments_dynamic(false)
|
808
904
|
end
|
809
905
|
|
810
906
|
# decodes the elf header, and depending on the elf type, decode segments or sections
|
@@ -819,12 +915,14 @@ class ELF
|
|
819
915
|
|
820
916
|
def each_section
|
821
917
|
@segments.each { |s| yield s.encoded, s.vaddr if s.type == 'LOAD' }
|
822
|
-
|
918
|
+
return if @header.type != 'REL'
|
823
919
|
@sections.each { |s|
|
824
920
|
next if not s.encoded
|
825
|
-
l =
|
826
|
-
|
827
|
-
|
921
|
+
if not l = s.encoded.inv_export[0] or l != s.name.tr('^a-zA-Z0-9_', '_')
|
922
|
+
l = new_label(s.name)
|
923
|
+
s.encoded.add_export l, 0
|
924
|
+
end
|
925
|
+
yield s.encoded, l
|
828
926
|
}
|
829
927
|
end
|
830
928
|
|
@@ -833,9 +931,13 @@ class ELF
|
|
833
931
|
case @header.machine
|
834
932
|
when 'X86_64'; X86_64.new
|
835
933
|
when '386'; Ia32.new
|
836
|
-
when 'MIPS'; MIPS.new @endianness
|
934
|
+
when 'MIPS'; (@header.flags.include?('32BITMODE') ? MIPS64 : MIPS).new @endianness
|
837
935
|
when 'PPC'; PPC.new
|
838
936
|
when 'ARM'; ARM.new
|
937
|
+
when 'AARCH64'; AArch64.new
|
938
|
+
when 'SH'; Sh4.new
|
939
|
+
when 'ARC_COMPACT'; ARC.new
|
940
|
+
when 'MSP430'; MSP430.new
|
839
941
|
else raise "unsupported cpu #{@header.machine}"
|
840
942
|
end
|
841
943
|
end
|
@@ -912,6 +1014,13 @@ EOC
|
|
912
1014
|
(d.address_binding[s.value] ||= {})[:$t9] ||= Expression[s.value]
|
913
1015
|
}
|
914
1016
|
d.function[:default] = @cpu.disassembler_default_func
|
1017
|
+
when 'sh4'
|
1018
|
+
noret = DecodedFunction.new
|
1019
|
+
noret.noreturn = true
|
1020
|
+
%w[__stack_chk_fail abort exit].each { |fn|
|
1021
|
+
d.function[Expression[fn]] = noret
|
1022
|
+
}
|
1023
|
+
d.function[:default] = @cpu.disassembler_default_func
|
915
1024
|
end
|
916
1025
|
d
|
917
1026
|
end
|