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
@@ -4,7 +4,7 @@
4
4
  # Licence is LGPL, see LICENCE in the top-level directory
5
5
 
6
6
 
7
- require 'metasm/pic16c/main'
7
+ require 'metasm/cpu/pic16c/main'
8
8
 
9
9
  module Metasm
10
10
  class Pic16c
@@ -5,7 +5,7 @@
5
5
 
6
6
 
7
7
  require 'metasm/main'
8
- require 'metasm/mips/parse'
9
- require 'metasm/mips/encode'
10
- require 'metasm/mips/decode'
11
- require 'metasm/mips/render'
8
+ require 'metasm/cpu/ppc/parse'
9
+ require 'metasm/cpu/ppc/encode'
10
+ require 'metasm/cpu/ppc/decode'
11
+ require 'metasm/cpu/ppc/decompile'
@@ -4,7 +4,7 @@
4
4
  # Licence is LGPL, see LICENCE in the top-level directory
5
5
 
6
6
 
7
- require 'metasm/ppc/opcodes'
7
+ require 'metasm/cpu/ppc/opcodes'
8
8
  require 'metasm/decode'
9
9
 
10
10
  module Metasm
@@ -13,8 +13,8 @@ class PowerPC
13
13
  # bit = 0 if can be mutated by an field value, 1 if fixed by opcode
14
14
  return if not op.bin.kind_of? Integer
15
15
  op.bin_mask = 0
16
- op.args.each { |f|
17
- op.bin_mask |= @fields_mask[f] << @fields_shift[f]
16
+ op.fields.each { |k, (m, s)|
17
+ op.bin_mask |= m << s
18
18
  }
19
19
  op.bin_mask = 0xffff_ffff ^ op.bin_mask
20
20
  end
@@ -37,7 +37,7 @@ class PowerPC
37
37
  end
38
38
 
39
39
  def decode_findopcode(edata)
40
- return if edata.ptr >= edata.data.length
40
+ return if edata.ptr+4 > edata.length
41
41
  di = DecodedInstruction.new(self)
42
42
  val = edata.decode_imm(:u32, @endianness)
43
43
  edata.ptr -= 4
@@ -67,14 +67,20 @@ class PowerPC
67
67
  when :fra, :frb, :frc, :frs, :frt; FPR.new field_val[a]
68
68
  when :ra_i16, :ra_i16s, :ra_i16q
69
69
  i = field_val[{:ra_i16 => :d, :ra_i16s => :ds, :ra_i16q => :dq}[a]]
70
- Memref.new GPR.new(field_val[:ra]), Expression[i]
71
- when :bd, :d, :ds, :dq, :si, :ui, :li, :sh, :ma, :mb, :me, :ma_, :mb_, :me_; Expression[field_val[a]]
72
- when :ign_bo_zzz, :ign_bo_z, :ign_bo_at, :ign_bo_at2, :ign_bi, :aa, :lk, :oe, :rc, :l; next
70
+ Memref.new GPR.new(field_val[:ra]), Expression[i]
71
+ when :bd, :d, :ds, :dq, :si, :ui, :li, :sh, :mb, :me, :mb_, :me_, :u; Expression[field_val[a]]
72
+ when :ba, :bf, :bfa, :bt; CR.new field_val[a]
73
+ when :bb, :bh, :flm, :fxm, :l_, :l__, :lev, :nb, :sh_, :spr, :sr, :tbr, :th, :to
74
+ puts "PPC.decode: unsupported argument #{a.inspect}" if $VERBOSE # TODO
75
+ Expression[field_val[a]]
73
76
  else raise SyntaxError, "Internal error: invalid argument #{a} in #{op.name}"
74
77
  end
75
78
  }
79
+
76
80
  di.bin_length += edata.ptr - before_ptr
77
81
 
82
+ return if edata.ptr > edata.length
83
+
78
84
  decode_aliases(di.instruction)
79
85
 
80
86
  di
@@ -84,8 +90,8 @@ class PowerPC
84
90
  case i.opname
85
91
  when /^n?or\.?$/
86
92
  if i.args[1] == i.args[2]
87
- i.args.pop
88
- i.opname = {'or' => 'mr', 'or.' => 'mr.', 'nor' => 'not', 'nor.' => 'not.'}[i.opname]
93
+ i.args.pop
94
+ i.opname = {'or' => 'mr', 'or.' => 'mr.', 'nor' => 'not', 'nor.' => 'not.'}[i.opname]
89
95
  end
90
96
  when /^addi/
91
97
  if a = i.args[2].reduce and a.kind_of? Integer and a < 0
@@ -107,7 +113,7 @@ class PowerPC
107
113
  # else just add the offset +off+ of the instruction + its length (off may be an Expression)
108
114
  # assumes edata.ptr points just after the instruction (as decode_instr_op left it)
109
115
  # do not call twice on the same di !
110
- def decode_instr_interpret(di, addr)
116
+ def decode_instr_interpret(di, addr)
111
117
  if di.opcode.props[:setip] and di.instruction.args.last.kind_of? Expression and di.opcode.name[0] != ?t and di.opcode.name[-1] != ?a
112
118
  arg = Expression[addr, :+, di.instruction.args.last].reduce
113
119
  di.instruction.args[-1] = Expression[arg]
@@ -191,11 +197,11 @@ class PowerPC
191
197
  ptr = m.pointer.externals.grep(Symbol).first
192
198
  ret[ptr] = m.pointer if ptr != a0
193
199
  ret
194
- }
200
+ }
195
201
  when 'lwz'; lambda { |di, a0, m| { a0 => Expression[m] } }
196
202
  when 'stwu'; lambda { |di, a0, m|
197
203
  { m => Expression[a0], m.pointer.externals.grep(Symbol).first => m.pointer }
198
- }
204
+ }
199
205
  when 'stw'; lambda { |di, a0, m| { m => Expression[a0] } }
200
206
  when 'rlwinm'; lambda { |di, a0, a1, sh, mb, me|
201
207
  mb, me = mb.reduce, me.reduce
@@ -4,7 +4,7 @@
4
4
  # Licence is LGPL, see LICENCE in the top-level directory
5
5
 
6
6
 
7
- require 'metasm/ppc/main'
7
+ require 'metasm/cpu/ppc/main'
8
8
 
9
9
  module Metasm
10
10
  class PowerPC
@@ -25,7 +25,7 @@ class PowerPC
25
25
  # returns { blockaddr => [list of vars that are needed by a following block] }
26
26
  def decompile_func_finddeps(dcmp, blocks, func)
27
27
  deps_r = {} ; deps_w = {} ; deps_to = {}
28
- deps_subfunc = {} # things read/written by subfuncs
28
+ deps_subfunc = {} # things read/written by subfuncs
29
29
 
30
30
  # find read/writes by each block
31
31
  blocks.each { |b, to|
@@ -43,7 +43,7 @@ class PowerPC
43
43
  end
44
44
  }
45
45
  #a << :eax if di.opcode.name == 'ret' # standard ABI
46
-
46
+
47
47
  deps_r[b] |= a.map { |ee| Expression[ee].externals.grep(::Symbol) }.flatten - [:unknown] - deps_w[b]
48
48
  deps_w[b] |= w.map { |ee| Expression[ee].externals.grep(::Symbol) }.flatten - [:unknown]
49
49
  }
@@ -4,7 +4,7 @@
4
4
  # Licence is LGPL, see LICENCE in the top-level directory
5
5
 
6
6
 
7
- require 'metasm/ppc/opcodes'
7
+ require 'metasm/cpu/ppc/opcodes'
8
8
  require 'metasm/encode'
9
9
 
10
10
  module Metasm
@@ -31,7 +31,7 @@ class PowerPC
31
31
 
32
32
  op.args.zip(instr.args).each { |sym, arg|
33
33
  case sym
34
- when :rs, :rt, :rd
34
+ when :rs, :rt, :rd, :ba, :bf, :bfa, :bt
35
35
  set_field[sym, arg.i]
36
36
  when :ft
37
37
  set_field[sym, arg.i]
@@ -11,10 +11,15 @@ module Metasm
11
11
  class PowerPC < CPU
12
12
  class Reg
13
13
  include Renderable
14
+ class << self
15
+ attr_accessor :s_to_i, :i_to_s
16
+ end
14
17
 
15
18
  def ==(o)
16
19
  o.class == self.class and (not respond_to?(:i) or o.i == i)
17
20
  end
21
+
22
+ def render ; [self.class.i_to_s[@i]] ; end
18
23
  end
19
24
 
20
25
  # general purpose reg
@@ -24,17 +29,14 @@ class PowerPC < CPU
24
29
  @i = i
25
30
  end
26
31
 
27
- Sym = (0..31).map { |i| "r#{i}".to_sym }
28
- Sym[1] = :sp
32
+ @s_to_i = (0..31).inject({}) { |h, i| h.update((i == 1 ? 'sp' : "r#{i}") => i) }
33
+ @i_to_s = @s_to_i.invert
34
+ Sym = @s_to_i.sort.transpose.last
29
35
  def symbolic ; Sym[@i] end
30
- def render ; [@i == 1 ? 'sp' : "r#@i"] end
31
36
  end
32
37
 
33
38
  # special purpose reg
34
39
  class SPR < Reg
35
- class << self
36
- attr_accessor :s_to_i, :i_to_s
37
- end
38
40
  @s_to_i = {'xer' => 1, 'lr' => 8, 'ctr' => 9, 'dec' => 22, 'srr0' => 26, 'srr1' => 27,
39
41
  'sprg0' => 272, 'sprg1' => 273, 'sprg2' => 274, 'sprg3' => 275, 'pvr' => 287}
40
42
  @i_to_s = @s_to_i.invert
@@ -50,14 +52,15 @@ class PowerPC < CPU
50
52
  end
51
53
 
52
54
  # floating point
53
- class FPR
55
+ class FPR < Reg
54
56
  attr_accessor :i
55
57
  def initialize(i)
56
58
  @i = i
57
59
  end
58
60
 
59
- include Renderable
60
- def render ; ["fp#@i"] end
61
+ @s_to_i = (0..31).inject({}) { |h, i| h.update "fp#{i}" => i }
62
+ @i_to_s = @s_to_i.invert
63
+ Sym = @s_to_i.sort.transpose.last
61
64
  end
62
65
 
63
66
  # machine state reg
@@ -73,8 +76,10 @@ class PowerPC < CPU
73
76
  @i = i
74
77
  end
75
78
 
79
+ @s_to_i = (0..31).inject({}) { |h, i| h.update "cr#{i}" => i }
80
+ @i_to_s = @s_to_i.invert
81
+ Sym = @s_to_i.sort.transpose.last
76
82
  def symbolic ; "cr#@i".to_sym end
77
- def render ; ["cr#@i"] end
78
83
  end
79
84
 
80
85
  # indirection : reg+reg or reg+16b_off
@@ -89,13 +94,13 @@ class PowerPC < CPU
89
94
  b = @base.symbolic
90
95
  b = nil if b == :r0 # XXX is it true ?
91
96
  o = @offset
92
- o = o.symbolic if o.kind_of? Reg
97
+ o = o.symbolic if o.kind_of?(Reg)
93
98
  Indirection[Expression[b, :+, o].reduce, 4, orig]
94
99
  end
95
100
 
96
101
  include Renderable
97
102
  def render
98
- if @offset.kind_of? Reg
103
+ if @offset.kind_of?(Reg)
99
104
  ['(', @base, ' + ', @offset, ')']
100
105
  else
101
106
  [@offset, '(', @base, ')']
@@ -4,14 +4,17 @@
4
4
  # Licence is LGPL, see LICENCE in the top-level directory
5
5
 
6
6
 
7
- require 'metasm/ppc/main'
7
+ require 'metasm/cpu/ppc/main'
8
8
 
9
9
  module Metasm
10
10
  class PowerPC
11
11
  def addop(name, bin, *argprops)
12
- o = Opcode.new name, bin
13
- o.args.concat(argprops & @fields_mask.keys)
14
- (argprops & @valid_props).each { |p| o.props[p] = true }
12
+ o = Opcode.new name, bin
13
+ argprops.each { |a|
14
+ o.args << a if @valid_args[a]
15
+ o.fields[a] = [@fields_mask[a], @fields_shift[a]] if @fields_mask[a]
16
+ o.props[a] = true if @valid_props[a]
17
+ }
15
18
  @opcode_list << o
16
19
  end
17
20
 
@@ -113,6 +116,9 @@ class PowerPC
113
116
  :tbr => 0x3FF, :th => 15, :to => 31, :u => 15, :ui => 0xFFFF,
114
117
  :ign_bo_zzz => 0b101111111, :ign_bo_z => 1, :ign_bo_at => 3, :ign_bo_at2 => 0b100111111
115
118
 
119
+ @valid_args = @fields_mask.dup
120
+ [:ign_bo_zzz, :ign_bo_z, :ign_bo_at, :ign_bo_at2, :aa, :lk, :oe, :rc, :l].each { |k| @valid_args.delete k }
121
+
116
122
  @fields_shift[:ra_i16] = @fields_shift[:ra_i16s] = @fields_shift[:ra_i16q] = 0
117
123
  @fields_mask[:ra_i16] = (@fields_mask[:d] << @fields_shift[:d]) | (@fields_mask[:ra] << @fields_shift[:ra])
118
124
  @fields_mask[:ra_i16s] = (@fields_mask[:ds] << @fields_shift[:d]) | (@fields_mask[:ra] << @fields_shift[:ra])
@@ -123,7 +129,7 @@ class PowerPC
123
129
  addop_branchcond 'b', 0x40000000, :bd
124
130
  addop_branchcond 'b', 0x4C000020, :lr
125
131
  addop_branchcond 'b', 0x4C000420, :ctr
126
-
132
+
127
133
  addop 'sc', 0x44000002, :lev
128
134
  addop 'crand', 0x4C000202, :bt, :ba, :bb
129
135
  addop 'crxor', 0x4C000182, :bt, :ba, :bb
@@ -0,0 +1,55 @@
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/ppc/opcodes'
8
+ require 'metasm/parse'
9
+
10
+ module Metasm
11
+ class PowerPC
12
+ # TODO
13
+ def parse_arg_valid?(op, sym, arg)
14
+ case sym
15
+ when :ra, :rb, :rs, :rt; arg.kind_of?(GPR)
16
+ when :fra, :frb, :frc, :frs, :frt; arg.kind_of?(FPR)
17
+ when :ra_i16, :ra_i16s, :ra_i16q; arg.kind_of?(Memref)
18
+ when :bd, :d, :ds, :dq, :si, :ui, :li, :sh, :mb, :me, :mb_, :me_, :u; arg.kind_of?(Expression)
19
+ when :ba, :bf, :bfa, :bt; arg.kind_of?(CR)
20
+ when :ign_bo_zzz, :ign_bo_z, :ign_bo_at, :ign_bo_at2, :aa, :lk, :oe, :rc, :l; # ?
21
+ when :bb, :bh, :flm, :fxm, :l_, :l__, :lev, :nb, :sh_, :spr, :sr, :tbr, :th, :to
22
+ # TODO
23
+ else raise "internal error: mips arg #{sym.inspect}"
24
+ end
25
+ end
26
+
27
+ def parse_argument(pgm)
28
+ pgm.skip_space
29
+ return if not tok = pgm.readtok
30
+ if tok.type == :string
31
+ return GPR.new(GPR.s_to_i[tok.raw]) if GPR.s_to_i[tok.raw]
32
+ return SPR.new(SPR.s_to_i[tok.raw]) if SPR.s_to_i[tok.raw]
33
+ return FPR.new(FPR.s_to_i[tok.raw]) if FPR.s_to_i[tok.raw]
34
+ return CR.new(CR.s_to_i[tok.raw]) if CR.s_to_i[tok.raw]
35
+ return MSR.new if tok.raw == 'msr'
36
+ end
37
+ pgm.unreadtok tok
38
+ arg = Expression.parse pgm
39
+ pgm.skip_space
40
+ # check memory indirection: 'off(base reg)' # XXX scaled index ?
41
+ if arg and pgm.nexttok and pgm.nexttok.type == :punct and pgm.nexttok.raw == '('
42
+ pgm.readtok
43
+ pgm.skip_space_eol
44
+ ntok = pgm.readtok
45
+ raise tok, "Invalid base #{ntok}" unless ntok and ntok.type == :string and GPR.s_to_i[ntok.raw]
46
+ base = GPR.new GPR.s_to_i[ntok.raw]
47
+ pgm.skip_space_eol
48
+ ntok = pgm.readtok
49
+ raise tok, "Invalid memory reference, ')' expected" if not ntok or ntok.type != :punct or ntok.raw != ')'
50
+ arg = Memref.new base, arg
51
+ end
52
+ arg
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,8 @@
1
+ # This file is part of Metasm, the Ruby assembly manipulation suite
2
+ # Copyright (C) 2006-2010 Yoann GUILLOT
3
+ #
4
+ # Licence is LGPL, see LICENCE in the top-level directory
5
+
6
+
7
+ require 'metasm/main'
8
+ require 'metasm/cpu/python/decode'
@@ -0,0 +1,136 @@
1
+ # This file is part of Metasm, the Ruby assembly manipulation suite
2
+ # Copyright (C) 2006-2010 Yoann GUILLOT
3
+ #
4
+ # Licence is LGPL, see LICENCE in the top-level directory
5
+
6
+ require 'metasm/cpu/python/opcodes'
7
+ require 'metasm/decode'
8
+
9
+ module Metasm
10
+ class Python
11
+ def build_bin_lookaside
12
+ opcode_list.inject({}) { |la, op| la.update op.bin => op }
13
+ end
14
+
15
+ def decode_findopcode(edata)
16
+ di = DecodedInstruction.new(self)
17
+
18
+ byte = edata.decode_imm(:u8, :little)
19
+
20
+ di if di.opcode = @bin_lookaside[byte]
21
+ end
22
+
23
+ def decode_instr_op(edata, di)
24
+ di.bin_length = 1
25
+
26
+ di.instruction.opname = di.opcode.name
27
+
28
+ di.opcode.args.each { |a|
29
+ case a
30
+ when :cmp
31
+ di.bin_length += 2
32
+ v = edata.decode_imm(:i16, @endianness)
33
+ di.instruction.args << (CMP_OP[v] || Expression[v])
34
+ when :i16
35
+ di.bin_length += 2
36
+ di.instruction.args << Expression[edata.decode_imm(:i16, @endianness)]
37
+ when :u8
38
+ di.bin_length += 1
39
+ di.instruction.args << Expression[edata.decode_imm(:u8, @endianness)]
40
+ else
41
+ raise "unsupported arg #{a.inspect}"
42
+ end
43
+ }
44
+
45
+ return if edata.ptr > edata.length
46
+
47
+ di
48
+ end
49
+
50
+ def decode_instr_interpret(di, addr)
51
+ case di.opcode.name
52
+ when 'LOAD_CONST'
53
+ if c = prog_code(addr)
54
+ cst = c[:consts][di.instruction.args.first.reduce]
55
+ if cst.kind_of? Hash and cst[:type] == :code
56
+ di.add_comment "lambda #{Expression[cst[:fileoff]]}"
57
+ else
58
+ di.add_comment cst.inspect
59
+ end
60
+ end
61
+ when 'LOAD_NAME', 'LOAD_ATTR', 'LOAD_GLOBAL', 'STORE_NAME', 'IMPORT_NAME', 'LOAD_FAST'
62
+ if c = prog_code(addr)
63
+ di.add_comment c[:names][di.instruction.args.first.reduce].inspect
64
+ end
65
+ end
66
+ di
67
+ end
68
+
69
+ def backtrace_binding
70
+ @backtrace_binding ||= init_backtrace_binding
71
+ end
72
+
73
+ def init_backtrace_binding
74
+ @backtrace_binding ||= {}
75
+
76
+ opcode_list.each { |op|
77
+ binding = case op
78
+ when 'nop'; lambda { |*a| {} }
79
+ end
80
+ @backtrace_binding[op] ||= binding if binding
81
+ }
82
+
83
+ @backtrace_binding
84
+ end
85
+
86
+ def get_backtrace_binding(di)
87
+ a = di.instruction.args.map { |arg|
88
+ case arg
89
+ when Var; arg.symbolic
90
+ else arg
91
+ end
92
+ }
93
+
94
+ if binding = backtrace_binding[di.opcode.basename]
95
+ binding[di, *a]
96
+ else
97
+ puts "unhandled instruction to backtrace: #{di}" if $VERBOSE
98
+ { :incomplete_binding => Expression[1] }
99
+ end
100
+ end
101
+
102
+ def get_xrefs_x(dasm, di)
103
+ return [] if not di.opcode.props[:setip]
104
+
105
+ arg = case di.opcode.name
106
+ when 'JUMP_FORWARD', 'FOR_ITER'
107
+ # relative offset
108
+ di.instruction.args.last.reduce + di.next_addr
109
+ when 'CALL_FUNCTION_VAR'
110
+ 'lol'
111
+ when /CALL/
112
+ :unknown
113
+ else
114
+ # absolute offset from :code start
115
+ off = di.instruction.args.last.reduce
116
+ if c = prog_code(di)
117
+ off += c[:fileoff]
118
+ end
119
+ off
120
+ end
121
+
122
+ [Expression[(arg.kind_of?(Var) ? arg.symbolic : arg)]]
123
+ end
124
+
125
+ def prog_code(addr)
126
+ addr = addr.address if addr.kind_of? DecodedInstruction
127
+ @last_prog_code ||= nil
128
+ return @last_prog_code if @last_prog_code and @last_prog_code[:fileoff] <= addr and @last_prog_code[:fileoff] + @last_prog_code[:code].length > addr
129
+ @last_prog_code = @program.code_at_off(addr) if @program
130
+ end
131
+
132
+ def backtrace_is_function_return(expr, di=nil)
133
+ #Expression[expr].reduce == Expression['wtf']
134
+ end
135
+ end
136
+ end