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
|
@@ -0,0 +1,63 @@
|
|
|
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/main'
|
|
8
|
+
|
|
9
|
+
module Metasm
|
|
10
|
+
class CY16 < CPU
|
|
11
|
+
class Reg
|
|
12
|
+
class << self
|
|
13
|
+
attr_accessor :s_to_i, :i_to_s
|
|
14
|
+
end
|
|
15
|
+
@i_to_s = (0..14).inject({}) { |h, i| h.update i => "r#{i}" }
|
|
16
|
+
@i_to_s[15] = 'sp'
|
|
17
|
+
@s_to_i = @i_to_s.invert
|
|
18
|
+
|
|
19
|
+
attr_accessor :i
|
|
20
|
+
def initialize(i)
|
|
21
|
+
@i = i
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def symbolic(orig=nil) ; to_s.to_sym ; end
|
|
25
|
+
|
|
26
|
+
def self.from_str(s)
|
|
27
|
+
raise "Bad name #{s.inspect}" if not x = @s_to_i[s]
|
|
28
|
+
new(x)
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
class Memref
|
|
33
|
+
attr_accessor :base, :offset, :sz, :autoincr
|
|
34
|
+
def initialize(base, offset, sz=nil, autoincr=nil)
|
|
35
|
+
@base = base
|
|
36
|
+
offset = Expression[offset] if offset
|
|
37
|
+
@offset = offset
|
|
38
|
+
@sz = sz
|
|
39
|
+
@autoincr = autoincr
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def symbolic(orig)
|
|
43
|
+
p = nil
|
|
44
|
+
p = Expression[p, :+, @base.symbolic] if base
|
|
45
|
+
p = Expression[p, :+, @offset] if offset
|
|
46
|
+
Indirection[p.reduce, @sz, orig]
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def initialize(family = :latest)
|
|
51
|
+
super()
|
|
52
|
+
@endianness = :little
|
|
53
|
+
@size = 16
|
|
54
|
+
@family = family
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def init_opcode_list
|
|
58
|
+
send("init_#@family")
|
|
59
|
+
@opcode_list
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
@@ -0,0 +1,78 @@
|
|
|
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/cpu/cy16/main'
|
|
7
|
+
|
|
8
|
+
module Metasm
|
|
9
|
+
|
|
10
|
+
class CY16
|
|
11
|
+
def addop(name, bin, *args)
|
|
12
|
+
o = Opcode.new name, bin
|
|
13
|
+
args.each { |a|
|
|
14
|
+
o.args << a if @fields_mask[a] or @valid_args[a]
|
|
15
|
+
o.props[a] = true if @valid_props[a]
|
|
16
|
+
o.fields[a] = @fields_shift[a] if @fields_mask[a]
|
|
17
|
+
raise "wtf #{a.inspect}" unless @valid_args[a] or @valid_props[a] or @fields_mask[a]
|
|
18
|
+
}
|
|
19
|
+
@opcode_list << o
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def addop_macrocc(name, bin, *args)
|
|
23
|
+
%w[z nz b ae s ns o no a be g ge l le].each_with_index { |cc, i|
|
|
24
|
+
dbin = bin
|
|
25
|
+
dbin |= i << 8
|
|
26
|
+
addop name + cc, dbin, *args
|
|
27
|
+
}
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def init_cy16
|
|
31
|
+
@opcode_list = []
|
|
32
|
+
@valid_args.update [:rs, :rd, :o7
|
|
33
|
+
].inject({}) { |h, v| h.update v => true }
|
|
34
|
+
@fields_mask.update :rs => 0x3f, :rd => 0x3f, :o7 => 0x7f, :x7 => 0x7f, :u3 => 7
|
|
35
|
+
@fields_shift.update :rs => 6, :rd => 0, :o7 => 0, :x7 => 0, :u3 => 6
|
|
36
|
+
|
|
37
|
+
addop 'mov', 0<<12, :rs, :rd
|
|
38
|
+
addop 'add', 1<<12, :rs, :rd
|
|
39
|
+
addop 'adc', 2<<12, :rs, :rd
|
|
40
|
+
addop 'addc',2<<12, :rs, :rd
|
|
41
|
+
addop 'sub', 3<<12, :rs, :rd
|
|
42
|
+
addop 'sbb', 4<<12, :rs, :rd
|
|
43
|
+
addop 'subb',4<<12, :rs, :rd
|
|
44
|
+
addop 'cmp', 5<<12, :rs, :rd
|
|
45
|
+
addop 'and', 6<<12, :rs, :rd
|
|
46
|
+
addop 'test',7<<12, :rs, :rd
|
|
47
|
+
addop 'or', 8<<12, :rs, :rd
|
|
48
|
+
addop 'xor', 9<<12, :rs, :rd
|
|
49
|
+
|
|
50
|
+
addop_macrocc 'int', (10<<12), :x7
|
|
51
|
+
addop 'int', (10<<12) | (15<<8), :x7
|
|
52
|
+
addop_macrocc 'c', (10<<12) | (1<<7), :setip, :saveip, :rd
|
|
53
|
+
addop 'call',(10<<12) | (15<<8) | (1<<7), :setip, :stopexec, :saveip, :rd
|
|
54
|
+
addop_macrocc 'r', (12<<12) | (1<<7) | 0b010111, :setip # must come before absolute jmp
|
|
55
|
+
addop 'ret', (12<<12) | (15<<8) | (1<<7) | 0b010111, :setip, :stopexec
|
|
56
|
+
addop_macrocc 'j', (12<<12), :setip, :o7 # relative
|
|
57
|
+
addop 'jmp', (12<<12) | (15<<8), :setip, :stopexec, :o7 # relative
|
|
58
|
+
addop_macrocc 'j', (12<<12) | (1<<7), :setip, :rd # absolute
|
|
59
|
+
addop 'jmp', (12<<12) | (15<<8) | (1<<7), :setip, :stopexec, :rd # absolute
|
|
60
|
+
|
|
61
|
+
addop 'shr', (13<<12) | (0<<9), :u3, :rd
|
|
62
|
+
addop 'shl', (13<<12) | (1<<9), :u3, :rd
|
|
63
|
+
addop 'ror', (13<<12) | (2<<9), :u3, :rd
|
|
64
|
+
addop 'rol', (13<<12) | (3<<9), :u3, :rd
|
|
65
|
+
addop 'addi',(13<<12) | (4<<9), :u3, :rd
|
|
66
|
+
addop 'subi',(13<<12) | (5<<9), :u3, :rd
|
|
67
|
+
addop 'not', (13<<12) | (7<<9) | (0<<6), :rd
|
|
68
|
+
addop 'neg', (13<<12) | (7<<9) | (1<<6), :rd
|
|
69
|
+
addop 'cbw', (13<<12) | (7<<9) | (4<<6), :rd
|
|
70
|
+
addop 'sti', (13<<12) | (7<<9) | (7<<6) | 0
|
|
71
|
+
addop 'cli', (13<<12) | (7<<9) | (7<<6) | 1
|
|
72
|
+
addop 'stc', (13<<12) | (7<<9) | (7<<6) | 2
|
|
73
|
+
addop 'clc', (13<<12) | (7<<9) | (7<<6) | 3
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
alias init_latest init_cy16
|
|
77
|
+
end
|
|
78
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
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/cpu/cy16/opcodes'
|
|
8
|
+
require 'metasm/render'
|
|
9
|
+
|
|
10
|
+
module Metasm
|
|
11
|
+
class CY16
|
|
12
|
+
class Reg
|
|
13
|
+
include Renderable
|
|
14
|
+
def render ; [self.class.i_to_s[@i]] end
|
|
15
|
+
end
|
|
16
|
+
class Memref
|
|
17
|
+
include Renderable
|
|
18
|
+
def render
|
|
19
|
+
r = []
|
|
20
|
+
r << (@sz == 1 ? 'byte ptr ' : 'word ptr ')
|
|
21
|
+
r << '['
|
|
22
|
+
r << @base if @base
|
|
23
|
+
r << '++' if @autoincr
|
|
24
|
+
r << ' + ' if @base and @offset
|
|
25
|
+
r << @offset if @offset
|
|
26
|
+
r << ']'
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def render_instruction(i)
|
|
31
|
+
r = []
|
|
32
|
+
r << i.opname
|
|
33
|
+
if not i.args.empty?
|
|
34
|
+
r << ' '
|
|
35
|
+
i.args.each { |a_| r << a_ << ', ' }
|
|
36
|
+
r.pop
|
|
37
|
+
end
|
|
38
|
+
r
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
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
|
+
class Metasm::Dalvik < Metasm::CPU
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
require 'metasm/main'
|
|
11
|
+
require 'metasm/cpu/dalvik/decode'
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
#
|
|
4
4
|
# Licence is LGPL, see LICENCE in the top-level directory
|
|
5
5
|
|
|
6
|
-
require 'metasm/dalvik/opcodes'
|
|
6
|
+
require 'metasm/cpu/dalvik/opcodes'
|
|
7
7
|
require 'metasm/decode'
|
|
8
8
|
|
|
9
9
|
module Metasm
|
|
@@ -12,7 +12,7 @@ class Dalvik
|
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
def decode_findopcode(edata)
|
|
15
|
-
return if edata.ptr
|
|
15
|
+
return if edata.ptr+2 > edata.length
|
|
16
16
|
di = DecodedInstruction.new(self)
|
|
17
17
|
di.opcode = opcode_list[edata.decode_imm(:u16, @endianness) & 0xff]
|
|
18
18
|
edata.ptr -= 2
|
|
@@ -22,7 +22,7 @@ class Dalvik
|
|
|
22
22
|
def decode_instr_op(edata, di)
|
|
23
23
|
op = di.opcode
|
|
24
24
|
di.instruction.opname = op.name
|
|
25
|
-
|
|
25
|
+
|
|
26
26
|
val = [edata.decode_imm(:u16, @endianness)]
|
|
27
27
|
|
|
28
28
|
op.args.each { |a|
|
|
@@ -80,7 +80,7 @@ class Dalvik
|
|
|
80
80
|
Expression[Expression.make_signed((val[1] >> 8) & 0xff, 8)]
|
|
81
81
|
when :rlist4, :rlist5
|
|
82
82
|
cnt = (val[0] >> 12) & 0xf
|
|
83
|
-
|
|
83
|
+
val << edata.decode_imm(:u16, @endianness)
|
|
84
84
|
[cnt, 4].min.times {
|
|
85
85
|
di.instruction.args << Reg.new(val[-1] & 0xf)
|
|
86
86
|
val[-1] >>= 4
|
|
@@ -96,20 +96,40 @@ class Dalvik
|
|
|
96
96
|
next
|
|
97
97
|
when :m16
|
|
98
98
|
val << edata.decode_imm(:u16, @endianness)
|
|
99
|
-
|
|
99
|
+
DexMethod.new(@dex, val.last)
|
|
100
|
+
when :fld16
|
|
101
|
+
val << edata.decode_imm(:u16, @endianness)
|
|
102
|
+
DexField.new(@dex, val.last)
|
|
103
|
+
when :typ16
|
|
104
|
+
val << edata.decode_imm(:u16, @endianness)
|
|
105
|
+
DexType.new(@dex, val.last)
|
|
106
|
+
when :str16
|
|
107
|
+
val << edata.decode_imm(:u16, @endianness)
|
|
108
|
+
DexString.new(@dex, val.last)
|
|
100
109
|
else raise SyntaxError, "Internal error: invalid argument #{a} in #{op.name}"
|
|
101
110
|
end
|
|
102
111
|
}
|
|
103
112
|
|
|
104
113
|
di.bin_length = val.length*2
|
|
105
114
|
|
|
115
|
+
return if edata.ptr > edata.length
|
|
116
|
+
|
|
117
|
+
di
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def decode_instr_interpret(di, addr)
|
|
121
|
+
if di.opcode.props[:setip] and di.instruction.args.last.kind_of? Expression and di.instruction.opname =~ /^if|^goto/
|
|
122
|
+
arg = Expression[addr, :+, [di.instruction.args.last, :*, 2]].reduce
|
|
123
|
+
di.instruction.args[-1] = Expression[arg]
|
|
124
|
+
end
|
|
125
|
+
|
|
106
126
|
di
|
|
107
127
|
end
|
|
108
128
|
|
|
109
129
|
def backtrace_binding
|
|
110
130
|
@backtrace_binding ||= init_backtrace_binding
|
|
111
131
|
end
|
|
112
|
-
|
|
132
|
+
|
|
113
133
|
def init_backtrace_binding
|
|
114
134
|
@backtrace_binding ||= {}
|
|
115
135
|
sz = @size/8
|
|
@@ -117,12 +137,12 @@ class Dalvik
|
|
|
117
137
|
case op.name
|
|
118
138
|
when /invoke/
|
|
119
139
|
@backtrace_binding[op.name] = lambda { |di, *args| {
|
|
120
|
-
:callstack => Expression[:callstack, :-, sz],
|
|
140
|
+
:callstack => Expression[:callstack, :-, sz],
|
|
121
141
|
Indirection[:callstack, sz] => Expression[di.next_addr]
|
|
122
142
|
} }
|
|
123
143
|
when /return/
|
|
124
144
|
@backtrace_binding[op.name] = lambda { |di, *args| {
|
|
125
|
-
|
|
145
|
+
:callstack => Expression[:callstack, :+, sz]
|
|
126
146
|
} }
|
|
127
147
|
end
|
|
128
148
|
}
|
|
@@ -136,9 +156,9 @@ class Dalvik
|
|
|
136
156
|
else arg
|
|
137
157
|
end
|
|
138
158
|
}
|
|
139
|
-
|
|
159
|
+
|
|
140
160
|
if binding = backtrace_binding[di.opcode.name]
|
|
141
|
-
|
|
161
|
+
binding[di, *a]
|
|
142
162
|
else
|
|
143
163
|
puts "unhandled instruction to backtrace: #{di}" if $VERBOSE
|
|
144
164
|
# assume nothing except the 1st arg is modified
|
|
@@ -150,18 +170,20 @@ class Dalvik
|
|
|
150
170
|
end
|
|
151
171
|
|
|
152
172
|
end
|
|
153
|
-
|
|
173
|
+
|
|
154
174
|
def get_xrefs_x(dasm, di)
|
|
155
175
|
if di.opcode.props[:saveip]
|
|
156
176
|
m = di.instruction.args.first
|
|
157
|
-
if m.kind_of?
|
|
177
|
+
if m.kind_of?(DexMethod) and m.off
|
|
158
178
|
[m.off]
|
|
159
179
|
else
|
|
160
180
|
[:default]
|
|
161
181
|
end
|
|
162
182
|
elsif di.opcode.props[:setip]
|
|
163
|
-
if di.opcode.name =~
|
|
183
|
+
if di.opcode.name =~ /^return/
|
|
164
184
|
[Indirection[:callstack, @size/8]]
|
|
185
|
+
elsif di.opcode.name =~ /^if|^goto/
|
|
186
|
+
[di.instruction.args.last]
|
|
165
187
|
else
|
|
166
188
|
[] # [di.instruction.args.last]
|
|
167
189
|
end
|
|
@@ -23,13 +23,14 @@ class Dalvik < CPU
|
|
|
23
23
|
end
|
|
24
24
|
end
|
|
25
25
|
|
|
26
|
-
class
|
|
26
|
+
class DexMethod
|
|
27
27
|
attr_accessor :dex, :midx, :off
|
|
28
28
|
def initialize(dex, midx)
|
|
29
29
|
@dex = dex
|
|
30
30
|
@midx = midx
|
|
31
31
|
if @dex and m = @dex.methods[midx] and c = @dex.classes[m.classidx] and c.data and
|
|
32
|
-
me = (c.data.direct_methods+c.data.virtual_methods).find { |mm| mm.
|
|
32
|
+
me = (c.data.direct_methods+c.data.virtual_methods).find { |mm| mm.methodid == midx }
|
|
33
|
+
# FIXME this doesnt work
|
|
33
34
|
@off = me.codeoff + me.code.insns_off
|
|
34
35
|
end
|
|
35
36
|
end
|
|
@@ -44,6 +45,54 @@ class Dalvik < CPU
|
|
|
44
45
|
end
|
|
45
46
|
end
|
|
46
47
|
|
|
48
|
+
class DexField
|
|
49
|
+
attr_accessor :dex, :fidx
|
|
50
|
+
def initialize(dex, fidx)
|
|
51
|
+
@dex = dex
|
|
52
|
+
@fidx = fidx
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def to_s
|
|
56
|
+
if @dex and f = @dex.fields[@fidx]
|
|
57
|
+
@dex.types[f.classidx] + '->' + @dex.strings[f.nameidx]
|
|
58
|
+
else
|
|
59
|
+
"field_#@fidx"
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
class DexType
|
|
65
|
+
attr_accessor :dex, :tidx
|
|
66
|
+
def initialize(dex, tidx)
|
|
67
|
+
@dex = dex
|
|
68
|
+
@tidx = tidx
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def to_s
|
|
72
|
+
if @dex and f = @dex.types[@tidx]
|
|
73
|
+
f
|
|
74
|
+
else
|
|
75
|
+
"type_#@tidx"
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
class DexString
|
|
81
|
+
attr_accessor :dex, :sidx
|
|
82
|
+
def initialize(dex, sidx)
|
|
83
|
+
@dex = dex
|
|
84
|
+
@sidx = sidx
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def to_s
|
|
88
|
+
if @dex and f = @dex.strings[@sidx]
|
|
89
|
+
f.inspect
|
|
90
|
+
else
|
|
91
|
+
"string_#@sidx"
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
47
96
|
def initialize(*args)
|
|
48
97
|
super()
|
|
49
98
|
@size = args.grep(Integer).first || 32
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
# the opcode number is in the low-order byte, and determines the
|
|
12
12
|
# argument format, which may take up to 4 other words
|
|
13
13
|
|
|
14
|
-
require 'metasm/dalvik/main'
|
|
14
|
+
require 'metasm/cpu/dalvik/main'
|
|
15
15
|
|
|
16
16
|
module Metasm
|
|
17
17
|
class Dalvik
|
|
@@ -61,9 +61,11 @@ invoke_virtual_quick invoke_virtual_quick_range invoke_super_quick invoke_super_
|
|
|
61
61
|
unused_fc unused_fd unused_fe unused_ff]
|
|
62
62
|
|
|
63
63
|
def init_dalvik
|
|
64
|
-
@valid_props
|
|
65
|
-
|
|
66
|
-
|
|
64
|
+
@valid_props[:canthrow] = true
|
|
65
|
+
[:i16, :i16_32hi, :i16_64hi, :i32, :iaa, :ib, :icc, :u16, :u32, :u64,
|
|
66
|
+
:r16, :ra, :raa, :rb, :rbb, :rcc, :rlist16, :rlist4, :rlist5,
|
|
67
|
+
:m16, :fld16, :typ16, :str16
|
|
68
|
+
].each { |a| @valid_args[a] = true }
|
|
67
69
|
@opcode_list = []
|
|
68
70
|
|
|
69
71
|
OPCODES.each_with_index { |n, b|
|
|
@@ -80,7 +82,7 @@ unused_fc unused_fd unused_fe unused_ff]
|
|
|
80
82
|
def addop_args(op)
|
|
81
83
|
fmt = case op.name
|
|
82
84
|
when 'goto'
|
|
83
|
-
|
|
85
|
+
:fmt10t
|
|
84
86
|
when 'nop', 'return_void'
|
|
85
87
|
:fmt10x
|
|
86
88
|
when 'const_4'
|
|
@@ -119,12 +121,16 @@ unused_fc unused_fd unused_fe unused_ff]
|
|
|
119
121
|
:fmt20t
|
|
120
122
|
when 'goto_32'
|
|
121
123
|
:fmt30t
|
|
122
|
-
when 'const_string'
|
|
123
|
-
|
|
124
|
+
when 'const_string'
|
|
125
|
+
:fmt21c_str
|
|
126
|
+
when 'const_class', 'check_cast',
|
|
127
|
+
'new_instance'
|
|
128
|
+
:fmt21c_typ
|
|
129
|
+
when 'sget', 'sget_wide', 'sget_object',
|
|
124
130
|
'sget_boolean', 'sget_byte', 'sget_char', 'sget_short',
|
|
125
131
|
'sput', 'sput_wide', 'sput_object', 'sput_boolean',
|
|
126
132
|
'sput_byte', 'sput_char', 'sput_short'
|
|
127
|
-
:
|
|
133
|
+
:fmt21c_fld
|
|
128
134
|
when 'const_16', 'const_wide_16'
|
|
129
135
|
:fmt21s
|
|
130
136
|
when 'if_eqz', 'if_nez', 'if_ltz', 'if_gez', 'if_gtz', 'if_lez'
|
|
@@ -214,7 +220,9 @@ unused_fc unused_fd unused_fe unused_ff]
|
|
|
214
220
|
when :fmt10t; op.args << :iaa
|
|
215
221
|
when :fmt20t; op.args << :i16
|
|
216
222
|
when :fmt20bc; op.args << :iaa << :u16
|
|
217
|
-
when :
|
|
223
|
+
when :fmt21c_str; op.args << :raa << :str16
|
|
224
|
+
when :fmt21c_typ; op.args << :raa << :typ16
|
|
225
|
+
when :fmt21c_fld; op.args << :raa << :fld16
|
|
218
226
|
when :fmt22x; op.args << :raa << :r16
|
|
219
227
|
when :fmt21s, :fmt21t; op.args << :raa << :i16
|
|
220
228
|
when :fmt21h; op.args << :raa << :i16_32hi
|
|
@@ -222,7 +230,7 @@ unused_fc unused_fd unused_fe unused_ff]
|
|
|
222
230
|
when :fmt23x; op.args << :raa << :rbb << :rcc
|
|
223
231
|
when :fmt22b; op.args << :raa << :rbb << :icc
|
|
224
232
|
when :fmt22s, :fmt22t; op.args << :ra << :rb << :i16
|
|
225
|
-
when :fmt22c, :fmt22cs; op.args << :ra << :rb << :
|
|
233
|
+
when :fmt22c, :fmt22cs; op.args << :ra << :rb << :fld16
|
|
226
234
|
when :fmt30t; op.args << :i32
|
|
227
235
|
when :fmt31t, :fmt31c; op.args << :raa << :u32
|
|
228
236
|
when :fmt32x; op.args << :r16 << :r16
|
|
@@ -238,7 +246,7 @@ unused_fc unused_fd unused_fe unused_ff]
|
|
|
238
246
|
when :fmt3inline
|
|
239
247
|
op.args << :r16 << :rlist4
|
|
240
248
|
when :fmt3rc, :fmt3rms
|
|
241
|
-
|
|
249
|
+
# rlist = :r16, :r16+1, :r16+2, ..., :r16+:iaa-1
|
|
242
250
|
op.args << :r16 << :rlist16
|
|
243
251
|
when :fmt51l
|
|
244
252
|
# u64 = u16 | (u16 << 16) | ...
|