metasm 1.0.1 → 1.0.2
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.
- 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
|