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.
Files changed (235) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +1 -0
  3. data/.hgtags +3 -0
  4. data/Gemfile +1 -0
  5. data/INSTALL +61 -0
  6. data/LICENCE +458 -0
  7. data/README +29 -21
  8. data/Rakefile +10 -0
  9. data/TODO +10 -12
  10. data/doc/code_organisation.txt +2 -0
  11. data/doc/core/DynLdr.txt +247 -0
  12. data/doc/core/ExeFormat.txt +43 -0
  13. data/doc/core/Expression.txt +220 -0
  14. data/doc/core/GNUExports.txt +27 -0
  15. data/doc/core/Ia32.txt +236 -0
  16. data/doc/core/SerialStruct.txt +108 -0
  17. data/doc/core/VirtualString.txt +145 -0
  18. data/doc/core/WindowsExports.txt +61 -0
  19. data/doc/core/index.txt +1 -0
  20. data/doc/style.css +6 -3
  21. data/doc/usage/debugger.txt +327 -0
  22. data/doc/usage/index.txt +1 -0
  23. data/doc/use_cases.txt +2 -2
  24. data/metasm.gemspec +22 -0
  25. data/{lib/metasm.rb → metasm.rb} +11 -3
  26. data/{lib/metasm → metasm}/compile_c.rb +13 -7
  27. data/metasm/cpu/arc.rb +8 -0
  28. data/metasm/cpu/arc/decode.rb +425 -0
  29. data/metasm/cpu/arc/main.rb +191 -0
  30. data/metasm/cpu/arc/opcodes.rb +588 -0
  31. data/{lib/metasm → metasm/cpu}/arm.rb +7 -5
  32. data/{lib/metasm → metasm/cpu}/arm/debug.rb +2 -2
  33. data/{lib/metasm → metasm/cpu}/arm/decode.rb +13 -12
  34. data/{lib/metasm → metasm/cpu}/arm/encode.rb +23 -8
  35. data/{lib/metasm → metasm/cpu}/arm/main.rb +0 -3
  36. data/metasm/cpu/arm/opcodes.rb +324 -0
  37. data/{lib/metasm → metasm/cpu}/arm/parse.rb +25 -13
  38. data/{lib/metasm → metasm/cpu}/arm/render.rb +2 -2
  39. data/metasm/cpu/arm64.rb +15 -0
  40. data/metasm/cpu/arm64/debug.rb +38 -0
  41. data/metasm/cpu/arm64/decode.rb +289 -0
  42. data/metasm/cpu/arm64/encode.rb +41 -0
  43. data/metasm/cpu/arm64/main.rb +105 -0
  44. data/metasm/cpu/arm64/opcodes.rb +232 -0
  45. data/metasm/cpu/arm64/parse.rb +20 -0
  46. data/metasm/cpu/arm64/render.rb +95 -0
  47. data/{lib/metasm/ppc.rb → metasm/cpu/bpf.rb} +2 -4
  48. data/metasm/cpu/bpf/decode.rb +142 -0
  49. data/metasm/cpu/bpf/main.rb +60 -0
  50. data/metasm/cpu/bpf/opcodes.rb +81 -0
  51. data/metasm/cpu/bpf/render.rb +41 -0
  52. data/metasm/cpu/cy16.rb +9 -0
  53. data/metasm/cpu/cy16/decode.rb +253 -0
  54. data/metasm/cpu/cy16/main.rb +63 -0
  55. data/metasm/cpu/cy16/opcodes.rb +78 -0
  56. data/metasm/cpu/cy16/render.rb +41 -0
  57. data/metasm/cpu/dalvik.rb +11 -0
  58. data/{lib/metasm → metasm/cpu}/dalvik/decode.rb +35 -13
  59. data/{lib/metasm → metasm/cpu}/dalvik/main.rb +51 -2
  60. data/{lib/metasm → metasm/cpu}/dalvik/opcodes.rb +19 -11
  61. data/metasm/cpu/ia32.rb +17 -0
  62. data/{lib/metasm → metasm/cpu}/ia32/compile_c.rb +5 -7
  63. data/{lib/metasm → metasm/cpu}/ia32/debug.rb +5 -5
  64. data/{lib/metasm → metasm/cpu}/ia32/decode.rb +246 -59
  65. data/{lib/metasm → metasm/cpu}/ia32/decompile.rb +7 -7
  66. data/{lib/metasm → metasm/cpu}/ia32/encode.rb +19 -13
  67. data/{lib/metasm → metasm/cpu}/ia32/main.rb +51 -8
  68. data/metasm/cpu/ia32/opcodes.rb +1424 -0
  69. data/{lib/metasm → metasm/cpu}/ia32/parse.rb +47 -16
  70. data/{lib/metasm → metasm/cpu}/ia32/render.rb +31 -4
  71. data/metasm/cpu/mips.rb +14 -0
  72. data/{lib/metasm → metasm/cpu}/mips/compile_c.rb +1 -1
  73. data/metasm/cpu/mips/debug.rb +42 -0
  74. data/{lib/metasm → metasm/cpu}/mips/decode.rb +46 -16
  75. data/{lib/metasm → metasm/cpu}/mips/encode.rb +4 -3
  76. data/{lib/metasm → metasm/cpu}/mips/main.rb +11 -4
  77. data/{lib/metasm → metasm/cpu}/mips/opcodes.rb +86 -17
  78. data/{lib/metasm → metasm/cpu}/mips/parse.rb +1 -1
  79. data/{lib/metasm → metasm/cpu}/mips/render.rb +1 -1
  80. data/{lib/metasm/dalvik.rb → metasm/cpu/msp430.rb} +1 -1
  81. data/metasm/cpu/msp430/decode.rb +247 -0
  82. data/metasm/cpu/msp430/main.rb +62 -0
  83. data/metasm/cpu/msp430/opcodes.rb +101 -0
  84. data/{lib/metasm → metasm/cpu}/pic16c/decode.rb +6 -7
  85. data/{lib/metasm → metasm/cpu}/pic16c/main.rb +0 -0
  86. data/{lib/metasm → metasm/cpu}/pic16c/opcodes.rb +1 -1
  87. data/{lib/metasm/mips.rb → metasm/cpu/ppc.rb} +4 -4
  88. data/{lib/metasm → metasm/cpu}/ppc/decode.rb +18 -12
  89. data/{lib/metasm → metasm/cpu}/ppc/decompile.rb +3 -3
  90. data/{lib/metasm → metasm/cpu}/ppc/encode.rb +2 -2
  91. data/{lib/metasm → metasm/cpu}/ppc/main.rb +17 -12
  92. data/{lib/metasm → metasm/cpu}/ppc/opcodes.rb +11 -5
  93. data/metasm/cpu/ppc/parse.rb +55 -0
  94. data/metasm/cpu/python.rb +8 -0
  95. data/metasm/cpu/python/decode.rb +136 -0
  96. data/metasm/cpu/python/main.rb +36 -0
  97. data/metasm/cpu/python/opcodes.rb +180 -0
  98. data/{lib/metasm → metasm/cpu}/sh4.rb +1 -1
  99. data/{lib/metasm → metasm/cpu}/sh4/decode.rb +48 -17
  100. data/{lib/metasm → metasm/cpu}/sh4/main.rb +13 -4
  101. data/{lib/metasm → metasm/cpu}/sh4/opcodes.rb +7 -8
  102. data/metasm/cpu/x86_64.rb +15 -0
  103. data/{lib/metasm → metasm/cpu}/x86_64/compile_c.rb +28 -17
  104. data/{lib/metasm → metasm/cpu}/x86_64/debug.rb +4 -4
  105. data/{lib/metasm → metasm/cpu}/x86_64/decode.rb +57 -15
  106. data/{lib/metasm → metasm/cpu}/x86_64/encode.rb +55 -26
  107. data/{lib/metasm → metasm/cpu}/x86_64/main.rb +14 -6
  108. data/metasm/cpu/x86_64/opcodes.rb +136 -0
  109. data/{lib/metasm → metasm/cpu}/x86_64/parse.rb +10 -2
  110. data/metasm/cpu/x86_64/render.rb +35 -0
  111. data/metasm/cpu/z80.rb +9 -0
  112. data/metasm/cpu/z80/decode.rb +313 -0
  113. data/metasm/cpu/z80/main.rb +67 -0
  114. data/metasm/cpu/z80/opcodes.rb +224 -0
  115. data/metasm/cpu/z80/render.rb +59 -0
  116. data/{lib/metasm/os/main.rb → metasm/debug.rb} +160 -401
  117. data/{lib/metasm → metasm}/decode.rb +35 -4
  118. data/{lib/metasm → metasm}/decompile.rb +15 -16
  119. data/{lib/metasm → metasm}/disassemble.rb +201 -45
  120. data/{lib/metasm → metasm}/disassemble_api.rb +651 -87
  121. data/{lib/metasm → metasm}/dynldr.rb +220 -133
  122. data/{lib/metasm → metasm}/encode.rb +10 -1
  123. data/{lib/metasm → metasm}/exe_format/a_out.rb +9 -6
  124. data/{lib/metasm → metasm}/exe_format/autoexe.rb +1 -0
  125. data/{lib/metasm → metasm}/exe_format/bflt.rb +57 -27
  126. data/{lib/metasm → metasm}/exe_format/coff.rb +11 -3
  127. data/{lib/metasm → metasm}/exe_format/coff_decode.rb +53 -20
  128. data/{lib/metasm → metasm}/exe_format/coff_encode.rb +11 -13
  129. data/{lib/metasm → metasm}/exe_format/dex.rb +13 -5
  130. data/{lib/metasm → metasm}/exe_format/dol.rb +1 -0
  131. data/{lib/metasm → metasm}/exe_format/elf.rb +93 -57
  132. data/{lib/metasm → metasm}/exe_format/elf_decode.rb +143 -34
  133. data/{lib/metasm → metasm}/exe_format/elf_encode.rb +122 -31
  134. data/metasm/exe_format/gb.rb +65 -0
  135. data/metasm/exe_format/javaclass.rb +424 -0
  136. data/{lib/metasm → metasm}/exe_format/macho.rb +204 -16
  137. data/{lib/metasm → metasm}/exe_format/main.rb +26 -3
  138. data/{lib/metasm → metasm}/exe_format/mz.rb +1 -0
  139. data/{lib/metasm → metasm}/exe_format/nds.rb +7 -4
  140. data/{lib/metasm → metasm}/exe_format/pe.rb +71 -8
  141. data/metasm/exe_format/pyc.rb +167 -0
  142. data/{lib/metasm → metasm}/exe_format/serialstruct.rb +67 -14
  143. data/{lib/metasm → metasm}/exe_format/shellcode.rb +7 -3
  144. data/metasm/exe_format/shellcode_rwx.rb +114 -0
  145. data/metasm/exe_format/swf.rb +205 -0
  146. data/{lib/metasm → metasm}/exe_format/xcoff.rb +7 -7
  147. data/metasm/exe_format/zip.rb +335 -0
  148. data/metasm/gui.rb +13 -0
  149. data/{lib/metasm → metasm}/gui/cstruct.rb +35 -41
  150. data/{lib/metasm → metasm}/gui/dasm_coverage.rb +11 -11
  151. data/{lib/metasm → metasm}/gui/dasm_decomp.rb +7 -20
  152. data/{lib/metasm → metasm}/gui/dasm_funcgraph.rb +0 -0
  153. data/metasm/gui/dasm_graph.rb +1695 -0
  154. data/{lib/metasm → metasm}/gui/dasm_hex.rb +12 -8
  155. data/{lib/metasm → metasm}/gui/dasm_listing.rb +43 -28
  156. data/{lib/metasm → metasm}/gui/dasm_main.rb +310 -53
  157. data/{lib/metasm → metasm}/gui/dasm_opcodes.rb +5 -19
  158. data/{lib/metasm → metasm}/gui/debug.rb +93 -27
  159. data/{lib/metasm → metasm}/gui/gtk.rb +162 -40
  160. data/{lib/metasm → metasm}/gui/qt.rb +12 -2
  161. data/{lib/metasm → metasm}/gui/win32.rb +179 -42
  162. data/{lib/metasm → metasm}/gui/x11.rb +59 -59
  163. data/{lib/metasm → metasm}/main.rb +389 -264
  164. data/{lib/metasm/os/remote.rb → metasm/os/gdbremote.rb} +146 -54
  165. data/{lib/metasm → metasm}/os/gnu_exports.rb +1 -1
  166. data/{lib/metasm → metasm}/os/linux.rb +628 -151
  167. data/metasm/os/main.rb +330 -0
  168. data/{lib/metasm → metasm}/os/windows.rb +132 -42
  169. data/{lib/metasm → metasm}/os/windows_exports.rb +141 -0
  170. data/{lib/metasm → metasm}/parse.rb +26 -24
  171. data/{lib/metasm → metasm}/parse_c.rb +221 -116
  172. data/{lib/metasm → metasm}/preprocessor.rb +55 -40
  173. data/{lib/metasm → metasm}/render.rb +14 -38
  174. data/misc/hexdump.rb +2 -1
  175. data/misc/lint.rb +58 -0
  176. data/misc/txt2html.rb +9 -7
  177. data/samples/bindiff.rb +3 -4
  178. data/samples/dasm-plugins/bindiff.rb +15 -0
  179. data/samples/dasm-plugins/bookmark.rb +133 -0
  180. data/samples/dasm-plugins/c_constants.rb +57 -0
  181. data/samples/dasm-plugins/colortheme_solarized.rb +125 -0
  182. data/samples/dasm-plugins/cppobj_funcall.rb +60 -0
  183. data/samples/dasm-plugins/dasm_all.rb +70 -0
  184. data/samples/dasm-plugins/demangle_cpp.rb +31 -0
  185. data/samples/dasm-plugins/deobfuscate.rb +251 -0
  186. data/samples/dasm-plugins/dump_text.rb +35 -0
  187. data/samples/dasm-plugins/export_graph_svg.rb +86 -0
  188. data/samples/dasm-plugins/findgadget.rb +75 -0
  189. data/samples/dasm-plugins/hl_opcode.rb +32 -0
  190. data/samples/dasm-plugins/hotfix_gtk_dbg.rb +19 -0
  191. data/samples/dasm-plugins/imm2off.rb +34 -0
  192. data/samples/dasm-plugins/match_libsigs.rb +93 -0
  193. data/samples/dasm-plugins/patch_file.rb +95 -0
  194. data/samples/dasm-plugins/scanfuncstart.rb +36 -0
  195. data/samples/dasm-plugins/scanxrefs.rb +26 -0
  196. data/samples/dasm-plugins/selfmodify.rb +197 -0
  197. data/samples/dasm-plugins/stringsxrefs.rb +28 -0
  198. data/samples/dasmnavig.rb +1 -1
  199. data/samples/dbg-apihook.rb +24 -9
  200. data/samples/dbg-plugins/heapscan.rb +283 -0
  201. data/samples/dbg-plugins/heapscan/compiled_heapscan_lin.c +155 -0
  202. data/samples/dbg-plugins/heapscan/compiled_heapscan_win.c +128 -0
  203. data/samples/dbg-plugins/heapscan/graphheap.rb +616 -0
  204. data/samples/dbg-plugins/heapscan/heapscan.rb +709 -0
  205. data/samples/dbg-plugins/heapscan/winheap.h +174 -0
  206. data/samples/dbg-plugins/heapscan/winheap7.h +307 -0
  207. data/samples/dbg-plugins/trace_func.rb +214 -0
  208. data/samples/disassemble-gui.rb +35 -5
  209. data/samples/disassemble.rb +31 -6
  210. data/samples/dump_upx.rb +24 -12
  211. data/samples/dynamic_ruby.rb +12 -3
  212. data/samples/exeencode.rb +6 -5
  213. data/samples/factorize-headers-peimports.rb +1 -1
  214. data/samples/lindebug.rb +175 -381
  215. data/samples/metasm-shell.rb +1 -2
  216. data/samples/peldr.rb +2 -2
  217. data/tests/all.rb +1 -1
  218. data/tests/arc.rb +26 -0
  219. data/tests/dynldr.rb +22 -4
  220. data/tests/expression.rb +55 -0
  221. data/tests/graph_layout.rb +285 -0
  222. data/tests/ia32.rb +79 -26
  223. data/tests/mips.rb +9 -2
  224. data/tests/x86_64.rb +66 -18
  225. metadata +330 -218
  226. data/lib/metasm/arm/opcodes.rb +0 -177
  227. data/lib/metasm/gui.rb +0 -23
  228. data/lib/metasm/gui/dasm_graph.rb +0 -1354
  229. data/lib/metasm/ia32.rb +0 -14
  230. data/lib/metasm/ia32/opcodes.rb +0 -873
  231. data/lib/metasm/ppc/parse.rb +0 -52
  232. data/lib/metasm/x86_64.rb +0 -12
  233. data/lib/metasm/x86_64/opcodes.rb +0 -118
  234. data/samples/gdbclient.rb +0 -583
  235. 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 >= edata.data.length
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
- val << edata.decode_imm(:u16, @endianness)
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
- Method.new(@dex, val.last)
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
- :callstack => Expression[:callstack, :+, sz]
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
- bd = binding[di, *a]
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? Method and m.off
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 =~ /return/
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 Method
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.method == m }
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 << :canthrow
65
- @valid_args = [:i16, :i16_32hi, :i16_64hi, :i32, :iaa, :ib, :icc, :u16, :u32, :u64,
66
- :r16, :ra, :raa, :rb, :rbb, :rcc, :rlist16, :rlist4, :rlist5, :m16]
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
- :fmt10t
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', 'const_class', 'check_cast',
123
- 'new_instance', 'sget', 'sget_wide', 'sget_object',
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
- :fmt21c
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 :fmt21c; op.args << :raa << :u16
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 << :u16
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
- # rlist = :r16, :r16+1, :r16+2, ..., :r16+:iaa-1
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) | ...