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
@@ -20,10 +20,10 @@ class ELF
|
|
20
20
|
@phoff ||= elf.segments.empty? ? 0 : elf.new_label('phdr')
|
21
21
|
@shoff ||= elf.sections.length <= 1 ? 0 : elf.new_label('shdr')
|
22
22
|
@flags ||= []
|
23
|
-
@ehsize ||= Header.
|
24
|
-
@phentsize ||= Segment.
|
23
|
+
@ehsize ||= Header.sizeof(elf)
|
24
|
+
@phentsize ||= Segment.sizeof(elf)
|
25
25
|
@phnum ||= elf.segments.length
|
26
|
-
@shentsize ||= Section.
|
26
|
+
@shentsize ||= Section.sizeof(elf)
|
27
27
|
@shnum ||= elf.sections.length
|
28
28
|
|
29
29
|
super(elf)
|
@@ -47,8 +47,8 @@ class ELF
|
|
47
47
|
# defines the @name_p field from @name and elf.section[elf.header.shstrndx]
|
48
48
|
# creates .shstrtab if needed
|
49
49
|
def make_name_p elf
|
50
|
-
return 0 if not name or @name == ''
|
51
|
-
if elf.header.shstrndx.to_i == 0
|
50
|
+
return 0 if not name or @name == '' or elf.header.shnum == 0
|
51
|
+
if elf.header.shstrndx.to_i == 0 or not elf.sections[elf.header.shstrndx]
|
52
52
|
sn = Section.new
|
53
53
|
sn.name = '.shstrtab'
|
54
54
|
sn.type = 'STRTAB'
|
@@ -140,6 +140,9 @@ class ELF
|
|
140
140
|
srank = rank[s]
|
141
141
|
nexts = @sections.find { |sec| rank[sec] > srank } # find section with rank superior
|
142
142
|
nexts = nexts ? @sections.index(nexts) : -1 # if none, last
|
143
|
+
if @header.shstrndx.to_i != 0 and nexts != -1 and @header.shstrndx >= nexts
|
144
|
+
@header.shstrndx += 1
|
145
|
+
end
|
143
146
|
@sections.insert(nexts, s) # insert section
|
144
147
|
end
|
145
148
|
|
@@ -196,6 +199,8 @@ class ELF
|
|
196
199
|
|
197
200
|
# encodes the symbol dynamic hash table in the .hash section, updates the HASH tag
|
198
201
|
def encode_hash
|
202
|
+
return if @symbols.length <= 1
|
203
|
+
|
199
204
|
if not hash = @sections.find { |s| s.type == 'HASH' }
|
200
205
|
hash = Section.new
|
201
206
|
hash.name = '.hash'
|
@@ -236,11 +241,13 @@ class ELF
|
|
236
241
|
# encodes the symbol table
|
237
242
|
# should have a stable self.sections array (only append allowed after this step)
|
238
243
|
def encode_segments_symbols(strtab)
|
244
|
+
return if @symbols.length <= 1
|
245
|
+
|
239
246
|
if not dynsym = @sections.find { |s| s.type == 'DYNSYM' }
|
240
247
|
dynsym = Section.new
|
241
248
|
dynsym.name = '.dynsym'
|
242
249
|
dynsym.type = 'DYNSYM'
|
243
|
-
dynsym.entsize = Symbol.
|
250
|
+
dynsym.entsize = Symbol.sizeof(self)
|
244
251
|
dynsym.addralign = 4
|
245
252
|
dynsym.flags = ['ALLOC']
|
246
253
|
dynsym.info = @symbols[1..-1].find_all { |s| s.bind == 'LOCAL' }.length + 1
|
@@ -251,7 +258,7 @@ class ELF
|
|
251
258
|
@symbols.each { |s| dynsym.encoded << s.encode(self, strtab.encoded) } # needs all section indexes, as will be in the final section header
|
252
259
|
|
253
260
|
@tag['SYMTAB'] = label_at(dynsym.encoded, 0)
|
254
|
-
@tag['SYMENT'] = Symbol.
|
261
|
+
@tag['SYMENT'] = Symbol.sizeof(self)
|
255
262
|
|
256
263
|
encode_check_section_size dynsym
|
257
264
|
|
@@ -261,7 +268,7 @@ class ELF
|
|
261
268
|
# encodes the relocation tables
|
262
269
|
# needs a complete self.symbols array
|
263
270
|
def encode_segments_relocs
|
264
|
-
return if not @relocations
|
271
|
+
return if not @relocations or @relocations.empty?
|
265
272
|
|
266
273
|
arch_preencode_reloc_func = "arch_#{@header.machine.downcase}_preencode_reloc"
|
267
274
|
send arch_preencode_reloc_func if respond_to? arch_preencode_reloc_func
|
@@ -287,7 +294,7 @@ class ELF
|
|
287
294
|
@tag['JMPREL'] = label_at(relplt.encoded, 0)
|
288
295
|
@tag['PLTRELSZ'] = relplt.encoded.virtsize
|
289
296
|
@tag['PLTREL'] = relplt.type = stype
|
290
|
-
@tag[stype + 'ENT'] = relplt.entsize = relplt.addralign = (stype == 'REL' ? Relocation.
|
297
|
+
@tag[stype + 'ENT'] = relplt.entsize = relplt.addralign = (stype == 'REL' ? Relocation.sizeof(self) : RelocationAddend.sizeof(self))
|
291
298
|
encode_check_section_size relplt
|
292
299
|
end
|
293
300
|
|
@@ -305,13 +312,13 @@ class ELF
|
|
305
312
|
rel.name = '.rel.dyn'
|
306
313
|
rel.type = 'REL'
|
307
314
|
rel.flags = ['ALLOC']
|
308
|
-
rel.entsize = rel.addralign = Relocation.
|
315
|
+
rel.entsize = rel.addralign = Relocation.sizeof(self)
|
309
316
|
encode_add_section rel
|
310
317
|
end
|
311
318
|
rel.encoded = EncodedData.new
|
312
319
|
list.each { |r| rel.encoded << r.encode(self) }
|
313
320
|
@tag['REL'] = label_at(rel.encoded, 0)
|
314
|
-
@tag['RELENT'] = Relocation.
|
321
|
+
@tag['RELENT'] = Relocation.sizeof(self)
|
315
322
|
@tag['RELSZ'] = rel.encoded.virtsize
|
316
323
|
encode_check_section_size rel
|
317
324
|
end
|
@@ -323,13 +330,13 @@ class ELF
|
|
323
330
|
rela.name = '.rela.dyn'
|
324
331
|
rela.type = 'RELA'
|
325
332
|
rela.flags = ['ALLOC']
|
326
|
-
rela.entsize = rela.addralign = RelocationAddend.
|
333
|
+
rela.entsize = rela.addralign = RelocationAddend.sizeof(self)
|
327
334
|
encode_add_section rela
|
328
335
|
end
|
329
336
|
rela.encoded = EncodedData.new
|
330
337
|
list.each { |r| rela.encoded << r.encode(self) }
|
331
338
|
@tag['RELA'] = label_at(rela.encoded, 0)
|
332
|
-
@tag['RELAENT'] = RelocationAddend.
|
339
|
+
@tag['RELAENT'] = RelocationAddend.sizeof(self)
|
333
340
|
@tag['RELASZ'] = rela.encoded.virtsize
|
334
341
|
encode_check_section_size rela
|
335
342
|
end
|
@@ -337,6 +344,8 @@ class ELF
|
|
337
344
|
|
338
345
|
# creates the .plt/.got from the @relocations
|
339
346
|
def arch_386_preencode_reloc
|
347
|
+
return if @relocations.empty?
|
348
|
+
|
340
349
|
# if .got.plt does not exist, the dynamic loader segfaults
|
341
350
|
if not gotplt = @sections.find { |s| s.type == 'PROGBITS' and s.name == '.got.plt' }
|
342
351
|
gotplt = Section.new
|
@@ -358,7 +367,7 @@ class ELF
|
|
358
367
|
when 'PC32'
|
359
368
|
next if not r.symbol
|
360
369
|
|
361
|
-
|
370
|
+
if r.symbol.type != 'FUNC'
|
362
371
|
# external data xref: generate a GOT entry
|
363
372
|
# XXX reuse .got.plt ?
|
364
373
|
if not got ||= @sections.find { |s| s.type == 'PROGBITS' and s.name == '.got' }
|
@@ -385,7 +394,7 @@ class ELF
|
|
385
394
|
else
|
386
395
|
@relocations.delete r
|
387
396
|
end
|
388
|
-
|
397
|
+
|
389
398
|
# prevoffset is label_section_start + int_section_offset
|
390
399
|
target_s = @sections.find { |s| s.encoded and s.encoded.export[prevoffset.lexpr] == 0 }
|
391
400
|
rel = target_s.encoded.reloc[prevoffset.rexpr]
|
@@ -411,12 +420,12 @@ class ELF
|
|
411
420
|
#
|
412
421
|
# [.got.plt header]
|
413
422
|
# dd _DYNAMIC
|
414
|
-
# dd 0
|
423
|
+
# dd 0 # rewritten to GOTPLT? by ld-linux
|
415
424
|
# dd 0 # rewritten to dlresolve_inplace by ld-linux
|
416
425
|
#
|
417
426
|
# [.got.plt + func_got_offset]
|
418
427
|
# dd some_func_got_default # lazily rewritten to the real addr of some_func by jmp dlresolve_inplace
|
419
|
-
#
|
428
|
+
# # base_relocated ?
|
420
429
|
|
421
430
|
# in the PIC case, _dlresolve imposes us to use the ebx register (which may not be saved by the calling function..)
|
422
431
|
# also geteip trashes eax, which may interfere with regparm(3)
|
@@ -448,7 +457,7 @@ class ELF
|
|
448
457
|
plt.encoded << shellcode["jmp [#{base} + #{gotplt.encoded.length}]"]
|
449
458
|
plt.encoded.add_export r.symbol.name+'_plt_default', plt.encoded.length
|
450
459
|
reloffset = @relocations.find_all { |rr| rr.type == 'JMP_SLOT' }.length
|
451
|
-
reloffset *= Relocation.
|
460
|
+
reloffset *= Relocation.sizeof(self) if @bitsize == 32
|
452
461
|
plt.encoded << shellcode["push #{reloffset}\njmp metasm_plt_start"]
|
453
462
|
|
454
463
|
# transform the reloc PC32 => JMP_SLOT
|
@@ -531,7 +540,7 @@ class ELF
|
|
531
540
|
|
532
541
|
# fill these later, but create the base relocs now
|
533
542
|
arch_create_reloc_func = "arch_#{@header.machine.downcase}_create_reloc"
|
534
|
-
next if not respond_to?(arch_create_reloc_func)
|
543
|
+
next if not respond_to?(arch_create_reloc_func)
|
535
544
|
curaddr = label_at(@encoded, 0, 'elf_start')
|
536
545
|
fkbind = {}
|
537
546
|
@sections.each { |s|
|
@@ -557,6 +566,9 @@ class ELF
|
|
557
566
|
|
558
567
|
encode_check_section_size strtab
|
559
568
|
|
569
|
+
# rm unused tag (shrink .nointerp binaries by allowing to skip the section entirely)
|
570
|
+
@tag.delete('STRTAB') if strtab.encoded.length == 1
|
571
|
+
|
560
572
|
# XXX any order needed ?
|
561
573
|
@tag.keys.each { |k|
|
562
574
|
case k
|
@@ -581,7 +593,7 @@ class ELF
|
|
581
593
|
encode_tag[k, @tag[k]]
|
582
594
|
end
|
583
595
|
}
|
584
|
-
encode_tag['NULL', @tag['NULL'] || 0]
|
596
|
+
encode_tag['NULL', @tag['NULL'] || 0] unless @tag.empty?
|
585
597
|
|
586
598
|
encode_check_section_size dynamic
|
587
599
|
end
|
@@ -598,17 +610,13 @@ class ELF
|
|
598
610
|
@sections.each { |s|
|
599
611
|
next if not s.encoded
|
600
612
|
s.encoded.reloc.each_value { |r|
|
601
|
-
|
602
|
-
|
603
|
-
|
604
|
-
|
605
|
-
else
|
606
|
-
symname = t.reduce_rec
|
607
|
-
end
|
608
|
-
next if not dll = autoexports[symname]
|
613
|
+
et = r.target.externals
|
614
|
+
extern = et.find_all { |name| autoexports[name] }
|
615
|
+
next if extern.length != 1
|
616
|
+
symname = extern.first
|
609
617
|
if not @symbols.find { |sym| sym.name == symname }
|
610
618
|
@tag['NEEDED'] ||= []
|
611
|
-
@tag['NEEDED'] |= [
|
619
|
+
@tag['NEEDED'] |= [autoexports[symname]]
|
612
620
|
sym = Symbol.new
|
613
621
|
sym.shndx = 'UNDEF'
|
614
622
|
sym.type = 'FUNC'
|
@@ -737,6 +745,55 @@ class ELF
|
|
737
745
|
@relocations << r
|
738
746
|
end
|
739
747
|
|
748
|
+
def arch_mips_create_reloc(section, off, binding, rel=nil)
|
749
|
+
rel ||= section.encoded.reloc[off]
|
750
|
+
startaddr = label_at(@encoded, 0)
|
751
|
+
r = Relocation.new
|
752
|
+
r.offset = Expression[label_at(section.encoded, 0, 'sect_start'), :+, off]
|
753
|
+
if Expression[rel.target, :-, startaddr].bind(binding).reduce.kind_of?(::Integer)
|
754
|
+
# this location is relative to the base load address of the ELF
|
755
|
+
r.type = 'REL32'
|
756
|
+
else
|
757
|
+
et = rel.target.externals
|
758
|
+
extern = et.find_all { |name| not binding[name] }
|
759
|
+
if extern.length != 1
|
760
|
+
puts "ELF: mips_create_reloc: ignoring reloc #{rel.target} in #{section.name}: #{extern.inspect} unknown" if $VERBOSE
|
761
|
+
return
|
762
|
+
end
|
763
|
+
if not sym = @symbols.find { |s| s.name == extern.first }
|
764
|
+
puts "ELF: mips_create_reloc: ignoring reloc #{rel.target} in #{section.name}: undefined symbol #{extern.first}" if $VERBOSE
|
765
|
+
return
|
766
|
+
end
|
767
|
+
r.symbol = sym
|
768
|
+
if Expression[rel.target, :-, sym.name].bind(binding).reduce.kind_of?(::Integer)
|
769
|
+
rel.target = Expression[rel.target, :-, sym.name]
|
770
|
+
r.type = '32'
|
771
|
+
elsif Expression[rel.target, :&, 0xffff0000].reduce.kind_of?(::Integer)
|
772
|
+
lo = Expression[rel.target, :&, 0xffff].reduce
|
773
|
+
lo = lo.lexpr if lo.kind_of?(Expression) and lo.op == :& and lo.rexpr == 0xffff
|
774
|
+
if lo.kind_of?(Expression) and lo.op == :>> and lo.rexpr == 16
|
775
|
+
r.type = 'HI16'
|
776
|
+
rel.target = Expression[rel.target, :&, 0xffff0000]
|
777
|
+
# XXX offset ?
|
778
|
+
elsif lo.kind_of?(String) or (lo.kind_of(Expression) and lo.op == :+)
|
779
|
+
r.type = 'LO16'
|
780
|
+
rel.target = Expression[rel.target, :&, 0xffff0000]
|
781
|
+
# XXX offset ?
|
782
|
+
else
|
783
|
+
puts "ELF: mips_create_reloc: ignoring reloc #{lo}: cannot find matching 16 reloc type" if $VERBOSE
|
784
|
+
return
|
785
|
+
end
|
786
|
+
#elsif Expression[rel.target, :+, label_at(section.encoded, 0)].bind(section.encoded.binding).reduce.kind_of? ::Integer
|
787
|
+
# rel.target = Expression[[rel.target, :+, label_at(section.encoded, 0)], :+, off]
|
788
|
+
# r.type = 'PC32'
|
789
|
+
else
|
790
|
+
puts "ELF: mips_create_reloc: ignoring reloc #{sym.name} + #{rel.target}: cannot find matching standard reloc type" if $VERBOSE
|
791
|
+
return
|
792
|
+
end
|
793
|
+
end
|
794
|
+
@relocations << r
|
795
|
+
end
|
796
|
+
|
740
797
|
# resets the fields of the elf headers that should be recalculated, eg phdr offset
|
741
798
|
def invalidate_header
|
742
799
|
@header.shoff = @header.shnum = nil
|
@@ -817,9 +874,13 @@ class ELF
|
|
817
874
|
end
|
818
875
|
|
819
876
|
if @header.type == 'REL'
|
820
|
-
|
877
|
+
encode_rel
|
878
|
+
else
|
879
|
+
encode_elf
|
821
880
|
end
|
881
|
+
end
|
822
882
|
|
883
|
+
def encode_elf
|
823
884
|
@encoded = EncodedData.new
|
824
885
|
if @header.type != 'EXEC' or @segments.find { |i| i.type == 'INTERP' }
|
825
886
|
# create a .dynamic section unless we are an ET_EXEC with .nointerp
|
@@ -870,7 +931,7 @@ class ELF
|
|
870
931
|
end
|
871
932
|
|
872
933
|
# add dynamic segment
|
873
|
-
if ds = @sections.find { |sec| sec.type == 'DYNAMIC' }
|
934
|
+
if ds = @sections.find { |sec| sec.type == 'DYNAMIC' } and ds.encoded.length > 1
|
874
935
|
ds.set_default_values self
|
875
936
|
seg = Segment.new
|
876
937
|
seg.type = 'DYNAMIC'
|
@@ -979,6 +1040,36 @@ class ELF
|
|
979
1040
|
@encoded.data
|
980
1041
|
end
|
981
1042
|
|
1043
|
+
def encode_rel
|
1044
|
+
@encoded = EncodedData.new
|
1045
|
+
automagic_symbols
|
1046
|
+
create_relocations
|
1047
|
+
|
1048
|
+
@header.phoff = @header.phnum = @header.phentsize = 0
|
1049
|
+
@header.entry = 0
|
1050
|
+
@sections.each { |sec| sec.addr = 0 }
|
1051
|
+
st = @sections.inject(EncodedData.new) { |edata, sec| edata << sec.encode(self) }
|
1052
|
+
|
1053
|
+
binding = {}
|
1054
|
+
@encoded << @header.encode(self)
|
1055
|
+
@encoded.align 8
|
1056
|
+
|
1057
|
+
binding[@header.shoff] = @encoded.length
|
1058
|
+
@encoded << st
|
1059
|
+
@encoded.align 8
|
1060
|
+
|
1061
|
+
@sections.each { |sec|
|
1062
|
+
next if not sec.encoded
|
1063
|
+
binding[sec.offset] = @encoded.length
|
1064
|
+
sec.encoded.fixup sec.encoded.binding
|
1065
|
+
@encoded << sec.encoded
|
1066
|
+
@encoded.align 8
|
1067
|
+
}
|
1068
|
+
|
1069
|
+
@encoded.fixup! binding
|
1070
|
+
@encoded.data
|
1071
|
+
end
|
1072
|
+
|
982
1073
|
def parse_init
|
983
1074
|
# allow the user to specify a section, falls back to .text if none specified
|
984
1075
|
if not defined? @cursource or not @cursource
|
@@ -0,0 +1,65 @@
|
|
1
|
+
# This file is part of Metasm, the Ruby assembly manipulation suite
|
2
|
+
# Copyright (C) 2006-2009 Yoann GUILLOT
|
3
|
+
#
|
4
|
+
# Licence is LGPL, see LICENCE in the top-level directory
|
5
|
+
|
6
|
+
|
7
|
+
require 'metasm/exe_format/main'
|
8
|
+
require 'metasm/encode'
|
9
|
+
require 'metasm/decode'
|
10
|
+
|
11
|
+
|
12
|
+
module Metasm
|
13
|
+
# GameBoy ROM file format
|
14
|
+
class GameBoyRom < ExeFormat
|
15
|
+
class Header < SerialStruct
|
16
|
+
# starts at 0x104 in the file
|
17
|
+
mem :logo, 0x30
|
18
|
+
str :title, 0x10
|
19
|
+
byte :sgb_flag
|
20
|
+
byte :cartridge_type
|
21
|
+
byte :rom_size # n => (n+1) * 32k bytes
|
22
|
+
byte :ram_size
|
23
|
+
byte :destination_code
|
24
|
+
byte :old_licensee_code
|
25
|
+
byte :mask_rom_version
|
26
|
+
byte :header_checksum
|
27
|
+
byte :checksum_hi
|
28
|
+
byte :checksum_lo
|
29
|
+
end
|
30
|
+
|
31
|
+
def encode_byte(val) Expression[val].encode(:u8, @endianness) end
|
32
|
+
def decode_byte(edata = @encoded) edata.decode_imm(:u8, @endianness) end
|
33
|
+
def sizeof_byte ; 1 ; end
|
34
|
+
|
35
|
+
|
36
|
+
attr_accessor :header
|
37
|
+
|
38
|
+
def initialize(cpu=nil)
|
39
|
+
@endianness = (cpu ? cpu.endianness : :little)
|
40
|
+
super(cpu)
|
41
|
+
end
|
42
|
+
|
43
|
+
def decode_header
|
44
|
+
@encoded.ptr = 0x104
|
45
|
+
@header = Header.decode(self)
|
46
|
+
end
|
47
|
+
|
48
|
+
def decode
|
49
|
+
decode_header
|
50
|
+
@encoded.add_export('entrypoint', 0x100)
|
51
|
+
end
|
52
|
+
|
53
|
+
def cpu_from_headers
|
54
|
+
Z80.new('gb')
|
55
|
+
end
|
56
|
+
|
57
|
+
def each_section
|
58
|
+
yield @encoded, 0
|
59
|
+
end
|
60
|
+
|
61
|
+
def get_default_entrypoints
|
62
|
+
['entrypoint']
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,424 @@
|
|
1
|
+
# This file is part of Metasm, the Ruby assembly manipulation suite
|
2
|
+
# Copyright (C) 2006-2009 Yoann GUILLOT
|
3
|
+
#
|
4
|
+
# Licence is LGPL, see LICENCE in the top-level directory
|
5
|
+
|
6
|
+
require 'metasm/exe_format/main'
|
7
|
+
require 'metasm/encode'
|
8
|
+
require 'metasm/decode'
|
9
|
+
|
10
|
+
module Metasm
|
11
|
+
|
12
|
+
class JavaClass < ExeFormat
|
13
|
+
MAGIC = "\xCA\xFE\xBA\xBE"
|
14
|
+
|
15
|
+
CONSTANT_TAG = {0x1 => 'Utf8', 0x3 => 'Integer',
|
16
|
+
0x4 => 'Float', 0x5 => 'Long',
|
17
|
+
0x6 => 'Double', 0x7 => 'Class',
|
18
|
+
0x8 => 'String', 0x9 => 'Fieldref',
|
19
|
+
0xa => 'Methodref', 0xb => 'InterfaceMethodref',
|
20
|
+
0xc => 'NameAndType' }
|
21
|
+
|
22
|
+
class SerialStruct < Metasm::SerialStruct
|
23
|
+
new_int_field :u1, :u2, :u4
|
24
|
+
end
|
25
|
+
|
26
|
+
class Header < SerialStruct
|
27
|
+
mem :magic, 4, MAGIC
|
28
|
+
u2 :minor_version
|
29
|
+
u2 :major_version
|
30
|
+
end
|
31
|
+
|
32
|
+
class ConstantPool < SerialStruct
|
33
|
+
u2 :constant_pool_count
|
34
|
+
attr_accessor :constant_pool
|
35
|
+
|
36
|
+
def decode(c)
|
37
|
+
super(c)
|
38
|
+
|
39
|
+
@constant_pool = [nil]
|
40
|
+
|
41
|
+
i = 1
|
42
|
+
while i < @constant_pool_count
|
43
|
+
entry = ConstantPoolInfo.decode(c)
|
44
|
+
entry.idx = i
|
45
|
+
@constant_pool << entry
|
46
|
+
i += 1
|
47
|
+
|
48
|
+
if entry.tag =~ /Long|Double/
|
49
|
+
# we must insert a phantom cell
|
50
|
+
# for long and double constants
|
51
|
+
@constant_pool << nil
|
52
|
+
i += 1
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def encode(c)
|
58
|
+
cp = super(c)
|
59
|
+
|
60
|
+
@constant_pool.each { |entry|
|
61
|
+
next if entry.nil?
|
62
|
+
cp << entry.encode(c)
|
63
|
+
}
|
64
|
+
cp
|
65
|
+
end
|
66
|
+
|
67
|
+
def [](idx)
|
68
|
+
@constant_pool[idx]
|
69
|
+
end
|
70
|
+
|
71
|
+
def []=(idx, val)
|
72
|
+
raise 'cannot be used to add a cp entry' if @constant_pool[idx].nil?
|
73
|
+
@constant_pool[idx] = val
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
class ConstantPoolInfo < SerialStruct
|
78
|
+
u1 :tag
|
79
|
+
fld_enum :tag, CONSTANT_TAG
|
80
|
+
attr_accessor :info, :idx
|
81
|
+
|
82
|
+
def decode(c)
|
83
|
+
super(c)
|
84
|
+
|
85
|
+
case @tag
|
86
|
+
when 'Utf8'
|
87
|
+
@info = ConstantUtf8.decode(c)
|
88
|
+
when /Integer|Float/
|
89
|
+
@info = ConstantIntFloat.decode(c)
|
90
|
+
when /Long|Double/
|
91
|
+
@info = ConstantLongDouble.decode(c)
|
92
|
+
when /Class|String/
|
93
|
+
@info = ConstantIndex.decode(c)
|
94
|
+
when /ref$/
|
95
|
+
@info = ConstantRef.decode(c)
|
96
|
+
when 'NameAndType'
|
97
|
+
@info = ConstantNameAndType.decode(c)
|
98
|
+
else
|
99
|
+
raise 'unkown constant tag'
|
100
|
+
return
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def encode(c)
|
105
|
+
super(c) << @info.encode(c)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
class ConstantUtf8 < SerialStruct
|
110
|
+
u2 :length
|
111
|
+
attr_accessor :bytes
|
112
|
+
|
113
|
+
def decode(c)
|
114
|
+
super(c)
|
115
|
+
@bytes = c.encoded.read(@length)
|
116
|
+
end
|
117
|
+
|
118
|
+
def encode(c)
|
119
|
+
super(c) << @bytes
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
class ConstantIntFloat < SerialStruct
|
124
|
+
u4 :bytes
|
125
|
+
end
|
126
|
+
|
127
|
+
class ConstantLongDouble < SerialStruct
|
128
|
+
u4 :high_bytes
|
129
|
+
u4 :low_bytes
|
130
|
+
end
|
131
|
+
|
132
|
+
class ConstantIndex < SerialStruct
|
133
|
+
u2 :index
|
134
|
+
end
|
135
|
+
|
136
|
+
class ConstantRef < SerialStruct
|
137
|
+
u2 :class_index
|
138
|
+
u2 :name_and_type_index
|
139
|
+
end
|
140
|
+
|
141
|
+
class ConstantNameAndType < SerialStruct
|
142
|
+
u2 :name_index
|
143
|
+
u2 :descriptor_index
|
144
|
+
end
|
145
|
+
|
146
|
+
class ClassInfo < SerialStruct
|
147
|
+
u2 :access_flags
|
148
|
+
u2 :this_class
|
149
|
+
u2 :super_class
|
150
|
+
end
|
151
|
+
|
152
|
+
class Interfaces < SerialStruct
|
153
|
+
u2 :interfaces_count
|
154
|
+
attr_accessor :interfaces
|
155
|
+
|
156
|
+
def decode(c)
|
157
|
+
super(c)
|
158
|
+
|
159
|
+
@interfaces = []
|
160
|
+
@interfaces_count.times {
|
161
|
+
@interfaces << ConstantIndex.decode(c)
|
162
|
+
}
|
163
|
+
end
|
164
|
+
|
165
|
+
def encode(c)
|
166
|
+
ret = super(c)
|
167
|
+
|
168
|
+
@interfaces.each { |e|
|
169
|
+
ret << e.encode(c)
|
170
|
+
}
|
171
|
+
ret
|
172
|
+
end
|
173
|
+
|
174
|
+
def [](idx)
|
175
|
+
@interfaces[idx]
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
class Fields < SerialStruct
|
180
|
+
u2 :fields_count
|
181
|
+
attr_accessor :fields
|
182
|
+
|
183
|
+
def decode(c)
|
184
|
+
super(c)
|
185
|
+
@fields = []
|
186
|
+
@fields_count.times {
|
187
|
+
@fields << FieldMethodInfo.decode(c)
|
188
|
+
}
|
189
|
+
end
|
190
|
+
|
191
|
+
def encode(c)
|
192
|
+
ret = super(c)
|
193
|
+
|
194
|
+
@fields.each { |e|
|
195
|
+
ret << e.encode(c)
|
196
|
+
}
|
197
|
+
ret
|
198
|
+
end
|
199
|
+
|
200
|
+
def [](idx)
|
201
|
+
@fields[idx]
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
class Methods < SerialStruct
|
206
|
+
u2 :methods_count
|
207
|
+
attr_accessor :methods
|
208
|
+
|
209
|
+
def decode(c)
|
210
|
+
super(c)
|
211
|
+
@methods = []
|
212
|
+
@methods_count.times {
|
213
|
+
@methods << FieldMethodInfo.decode(c)
|
214
|
+
}
|
215
|
+
end
|
216
|
+
|
217
|
+
def encode(c)
|
218
|
+
ret = super(c)
|
219
|
+
|
220
|
+
@methods.each { |e|
|
221
|
+
ret << e.encode(c)
|
222
|
+
}
|
223
|
+
ret
|
224
|
+
end
|
225
|
+
|
226
|
+
def [](idx)
|
227
|
+
@methods[idx]
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
class FieldMethodInfo < SerialStruct
|
232
|
+
u2 :access_flags
|
233
|
+
u2 :name_index
|
234
|
+
u2 :descriptor_index
|
235
|
+
attr_accessor :attributes
|
236
|
+
|
237
|
+
def decode(c)
|
238
|
+
super(c)
|
239
|
+
@attributes = Attributes.decode(c)
|
240
|
+
end
|
241
|
+
|
242
|
+
def encode(c)
|
243
|
+
super(c) << @attributes.encode(c)
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
247
|
+
class Attributes < SerialStruct
|
248
|
+
u2 :attributes_count
|
249
|
+
attr_accessor :attributes
|
250
|
+
|
251
|
+
def decode(c)
|
252
|
+
super(c)
|
253
|
+
|
254
|
+
@attributes = []
|
255
|
+
@attributes_count.times { |i|
|
256
|
+
@attributes << AttributeInfo.decode(c)
|
257
|
+
}
|
258
|
+
end
|
259
|
+
|
260
|
+
def encode(c)
|
261
|
+
ret = super(c)
|
262
|
+
|
263
|
+
@attributes.each { |e|
|
264
|
+
ret << e.encode(c)
|
265
|
+
}
|
266
|
+
ret
|
267
|
+
end
|
268
|
+
|
269
|
+
def [](idx)
|
270
|
+
@attributes[idx]
|
271
|
+
end
|
272
|
+
end
|
273
|
+
|
274
|
+
class AttributeInfo < SerialStruct
|
275
|
+
u2 :attribute_name_index
|
276
|
+
u4 :attribute_length
|
277
|
+
attr_accessor :data
|
278
|
+
|
279
|
+
def decode(c)
|
280
|
+
super(c)
|
281
|
+
@data = c.encoded.read(@attribute_length)
|
282
|
+
end
|
283
|
+
|
284
|
+
def encode(c)
|
285
|
+
super(c) << @data
|
286
|
+
end
|
287
|
+
end
|
288
|
+
|
289
|
+
def encode_u1(val) Expression[val].encode(:u8, @endianness) end
|
290
|
+
def encode_u2(val) Expression[val].encode(:u16, @endianness) end
|
291
|
+
def encode_u4(val) Expression[val].encode(:u32, @endianness) end
|
292
|
+
def decode_u1(edata = @encoded) edata.decode_imm(:u8, @endianness) end
|
293
|
+
def decode_u2(edata = @encoded) edata.decode_imm(:u16, @endianness) end
|
294
|
+
def decode_u4(edata = @encoded) edata.decode_imm(:u32, @endianness) end
|
295
|
+
def sizeof_u1 ; 1 ; end
|
296
|
+
def sizeof_u2 ; 2 ; end
|
297
|
+
def sizeof_u4 ; 4 ; end
|
298
|
+
|
299
|
+
attr_accessor :header, :constant_pool, :class_info, :interfaces, :fields, :methods, :attributes
|
300
|
+
|
301
|
+
def initialize(endianness=:big)
|
302
|
+
@endianness = endianness
|
303
|
+
@encoded = EncodedData.new
|
304
|
+
super()
|
305
|
+
end
|
306
|
+
|
307
|
+
def decode
|
308
|
+
@header = Header.decode(self)
|
309
|
+
@constant_pool = ConstantPool.decode(self)
|
310
|
+
@class_info = ClassInfo.decode(self)
|
311
|
+
@interfaces = Interfaces.decode(self)
|
312
|
+
@fields = Fields.decode(self)
|
313
|
+
@methods = Methods.decode(self)
|
314
|
+
@attributes = Attributes.decode(self)
|
315
|
+
end
|
316
|
+
|
317
|
+
def encode
|
318
|
+
@encoded = EncodedData.new
|
319
|
+
@encoded << @header.encode(self)
|
320
|
+
@encoded << @constant_pool.encode(self)
|
321
|
+
@encoded << @class_info.encode(self)
|
322
|
+
@encoded << @interfaces.encode(self)
|
323
|
+
@encoded << @fields.encode(self)
|
324
|
+
@encoded << @methods.encode(self)
|
325
|
+
@encoded << @attributes.encode(self)
|
326
|
+
@encoded.data
|
327
|
+
end
|
328
|
+
|
329
|
+
def cpu_from_headers
|
330
|
+
raise 'JVM'
|
331
|
+
end
|
332
|
+
|
333
|
+
def each_section
|
334
|
+
raise 'n/a'
|
335
|
+
end
|
336
|
+
|
337
|
+
def get_default_entrypoints
|
338
|
+
[]
|
339
|
+
end
|
340
|
+
|
341
|
+
def string_at(idx)
|
342
|
+
loop do
|
343
|
+
tmp = @constant_pool[idx].info
|
344
|
+
return tmp.bytes if tmp.kind_of? ConstantUtf8
|
345
|
+
idx = tmp.index
|
346
|
+
end
|
347
|
+
end
|
348
|
+
|
349
|
+
def decode_methodref(mref)
|
350
|
+
class_idx = mref.info.class_index
|
351
|
+
nt_idx = mref.info.name_and_type_index
|
352
|
+
name_idx = @constant_pool[nt_idx].info.name_index
|
353
|
+
desc_idx = @constant_pool[nt_idx].info.descriptor_index
|
354
|
+
|
355
|
+
string_at(class_idx) + '/' + string_at(name_idx) + string_at(desc_idx)
|
356
|
+
end
|
357
|
+
|
358
|
+
def cp_add(cpi, tag)
|
359
|
+
cpe = ConstantPoolInfo.new
|
360
|
+
cpe.tag = tag
|
361
|
+
cpe.info = cpi
|
362
|
+
cpe.idx = @constant_pool.constant_pool_count
|
363
|
+
|
364
|
+
@constant_pool.constant_pool << cpe
|
365
|
+
@constant_pool.constant_pool_count += 1
|
366
|
+
@constant_pool.constant_pool_count += 1 if tag =~ /Long|Double/
|
367
|
+
|
368
|
+
cpe.idx
|
369
|
+
end
|
370
|
+
|
371
|
+
def cp_find(tag)
|
372
|
+
constant_pool.constant_pool.each { |e|
|
373
|
+
next if !e or e.tag != tag
|
374
|
+
if yield(e.info)
|
375
|
+
return e.idx
|
376
|
+
end
|
377
|
+
}
|
378
|
+
nil
|
379
|
+
end
|
380
|
+
|
381
|
+
|
382
|
+
def cp_auto_utf8(string)
|
383
|
+
if idx = cp_find('Utf8') { |i| i.bytes == string }
|
384
|
+
return idx
|
385
|
+
end
|
386
|
+
|
387
|
+
cpi = ConstantUtf8.new
|
388
|
+
cpi.bytes = string
|
389
|
+
cpi.length = string.length
|
390
|
+
cp_add(cpi, 'Utf8')
|
391
|
+
end
|
392
|
+
|
393
|
+
def cp_auto_class(classname)
|
394
|
+
if idx = cp_find('Class') { |i| string_at(i.index) == classname }
|
395
|
+
return idx
|
396
|
+
end
|
397
|
+
|
398
|
+
cpi = ConstantIndex.new
|
399
|
+
cpi.index = cp_auto_utf8(classname)
|
400
|
+
cp_add(cpi, 'Class')
|
401
|
+
end
|
402
|
+
|
403
|
+
def cp_add_methodref(classname, name, descriptor)
|
404
|
+
nat = ConstantNameAndType.new
|
405
|
+
nat.name_index = cp_auto_utf8(name)
|
406
|
+
nat.descriptor_index = cp_auto_utf8(descriptor)
|
407
|
+
natidx = cp_add(nat, 'NameAndType')
|
408
|
+
|
409
|
+
cpi = ConstantRef.new
|
410
|
+
cpi.class_index = cp_auto_class(classname)
|
411
|
+
cpi.name_and_type_index = natidx
|
412
|
+
|
413
|
+
cp_add(cpi, 'Methodref')
|
414
|
+
end
|
415
|
+
|
416
|
+
def attribute_create(name, data)
|
417
|
+
a = AttributeInfo.new
|
418
|
+
a.attribute_name_index = cp_auto_utf8(name)
|
419
|
+
a.attribute_length = data.size
|
420
|
+
a.data = data
|
421
|
+
a
|
422
|
+
end
|
423
|
+
end
|
424
|
+
end
|