metasm 1.0.0 → 1.0.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (276) hide show
  1. checksums.yaml +7 -0
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +3 -0
  4. data/.gitignore +3 -0
  5. data/.hgtags +3 -0
  6. data/Gemfile +3 -0
  7. data/INSTALL +61 -0
  8. data/LICENCE +458 -0
  9. data/README +29 -21
  10. data/Rakefile +10 -0
  11. data/TODO +10 -12
  12. data/doc/code_organisation.txt +3 -1
  13. data/doc/core/DynLdr.txt +247 -0
  14. data/doc/core/ExeFormat.txt +43 -0
  15. data/doc/core/Expression.txt +220 -0
  16. data/doc/core/GNUExports.txt +27 -0
  17. data/doc/core/Ia32.txt +236 -0
  18. data/doc/core/SerialStruct.txt +108 -0
  19. data/doc/core/VirtualString.txt +145 -0
  20. data/doc/core/WindowsExports.txt +61 -0
  21. data/doc/core/index.txt +1 -0
  22. data/doc/style.css +6 -3
  23. data/doc/usage/debugger.txt +327 -0
  24. data/doc/usage/index.txt +1 -0
  25. data/doc/use_cases.txt +2 -2
  26. data/metasm.gemspec +23 -0
  27. data/{lib/metasm.rb → metasm.rb} +15 -3
  28. data/{lib/metasm → metasm}/compile_c.rb +15 -9
  29. data/metasm/cpu/arc.rb +8 -0
  30. data/metasm/cpu/arc/decode.rb +404 -0
  31. data/metasm/cpu/arc/main.rb +191 -0
  32. data/metasm/cpu/arc/opcodes.rb +588 -0
  33. data/metasm/cpu/arm.rb +14 -0
  34. data/{lib/metasm → metasm/cpu}/arm/debug.rb +2 -2
  35. data/{lib/metasm → metasm/cpu}/arm/decode.rb +15 -18
  36. data/{lib/metasm → metasm/cpu}/arm/encode.rb +23 -8
  37. data/{lib/metasm → metasm/cpu}/arm/main.rb +3 -6
  38. data/metasm/cpu/arm/opcodes.rb +324 -0
  39. data/{lib/metasm → metasm/cpu}/arm/parse.rb +25 -13
  40. data/{lib/metasm → metasm/cpu}/arm/render.rb +2 -2
  41. data/metasm/cpu/arm64.rb +15 -0
  42. data/metasm/cpu/arm64/debug.rb +38 -0
  43. data/metasm/cpu/arm64/decode.rb +285 -0
  44. data/metasm/cpu/arm64/encode.rb +41 -0
  45. data/metasm/cpu/arm64/main.rb +105 -0
  46. data/metasm/cpu/arm64/opcodes.rb +232 -0
  47. data/metasm/cpu/arm64/parse.rb +20 -0
  48. data/metasm/cpu/arm64/render.rb +95 -0
  49. data/{lib/metasm/mips/compile_c.rb → metasm/cpu/bpf.rb} +4 -2
  50. data/metasm/cpu/bpf/decode.rb +110 -0
  51. data/metasm/cpu/bpf/main.rb +60 -0
  52. data/metasm/cpu/bpf/opcodes.rb +81 -0
  53. data/metasm/cpu/bpf/render.rb +30 -0
  54. data/{lib/metasm/ppc.rb → metasm/cpu/cy16.rb} +2 -4
  55. data/metasm/cpu/cy16/decode.rb +247 -0
  56. data/metasm/cpu/cy16/main.rb +63 -0
  57. data/metasm/cpu/cy16/opcodes.rb +78 -0
  58. data/metasm/cpu/cy16/render.rb +30 -0
  59. data/metasm/cpu/dalvik.rb +11 -0
  60. data/{lib/metasm → metasm/cpu}/dalvik/decode.rb +34 -34
  61. data/{lib/metasm → metasm/cpu}/dalvik/main.rb +71 -4
  62. data/{lib/metasm → metasm/cpu}/dalvik/opcodes.rb +21 -12
  63. data/{lib/metasm/mips.rb → metasm/cpu/ebpf.rb} +3 -4
  64. data/metasm/cpu/ebpf/debug.rb +61 -0
  65. data/metasm/cpu/ebpf/decode.rb +142 -0
  66. data/metasm/cpu/ebpf/main.rb +58 -0
  67. data/metasm/cpu/ebpf/opcodes.rb +97 -0
  68. data/metasm/cpu/ebpf/render.rb +36 -0
  69. data/metasm/cpu/ia32.rb +17 -0
  70. data/{lib/metasm → metasm/cpu}/ia32/compile_c.rb +23 -9
  71. data/{lib/metasm → metasm/cpu}/ia32/debug.rb +44 -6
  72. data/{lib/metasm → metasm/cpu}/ia32/decode.rb +342 -128
  73. data/{lib/metasm → metasm/cpu}/ia32/decompile.rb +75 -53
  74. data/{lib/metasm → metasm/cpu}/ia32/encode.rb +19 -13
  75. data/{lib/metasm → metasm/cpu}/ia32/main.rb +66 -8
  76. data/metasm/cpu/ia32/opcodes.rb +1424 -0
  77. data/{lib/metasm → metasm/cpu}/ia32/parse.rb +55 -17
  78. data/{lib/metasm → metasm/cpu}/ia32/render.rb +32 -5
  79. data/metasm/cpu/mcs51.rb +8 -0
  80. data/metasm/cpu/mcs51/decode.rb +99 -0
  81. data/metasm/cpu/mcs51/main.rb +87 -0
  82. data/metasm/cpu/mcs51/opcodes.rb +120 -0
  83. data/metasm/cpu/mips.rb +14 -0
  84. data/metasm/cpu/mips/debug.rb +42 -0
  85. data/{lib/metasm → metasm/cpu}/mips/decode.rb +59 -38
  86. data/{lib/metasm → metasm/cpu}/mips/encode.rb +4 -3
  87. data/{lib/metasm → metasm/cpu}/mips/main.rb +13 -6
  88. data/{lib/metasm → metasm/cpu}/mips/opcodes.rb +87 -18
  89. data/{lib/metasm → metasm/cpu}/mips/parse.rb +1 -1
  90. data/{lib/metasm → metasm/cpu}/mips/render.rb +1 -1
  91. data/{lib/metasm/dalvik.rb → metasm/cpu/msp430.rb} +1 -1
  92. data/metasm/cpu/msp430/decode.rb +243 -0
  93. data/metasm/cpu/msp430/main.rb +62 -0
  94. data/metasm/cpu/msp430/opcodes.rb +101 -0
  95. data/metasm/cpu/openrisc.rb +11 -0
  96. data/metasm/cpu/openrisc/debug.rb +106 -0
  97. data/metasm/cpu/openrisc/decode.rb +182 -0
  98. data/metasm/cpu/openrisc/decompile.rb +350 -0
  99. data/metasm/cpu/openrisc/main.rb +70 -0
  100. data/metasm/cpu/openrisc/opcodes.rb +109 -0
  101. data/metasm/cpu/openrisc/render.rb +37 -0
  102. data/{lib/metasm → metasm/cpu}/pic16c/decode.rb +6 -7
  103. data/{lib/metasm → metasm/cpu}/pic16c/main.rb +0 -0
  104. data/{lib/metasm → metasm/cpu}/pic16c/opcodes.rb +1 -1
  105. data/metasm/cpu/ppc.rb +11 -0
  106. data/{lib/metasm → metasm/cpu}/ppc/decode.rb +18 -37
  107. data/{lib/metasm → metasm/cpu}/ppc/decompile.rb +3 -3
  108. data/{lib/metasm → metasm/cpu}/ppc/encode.rb +2 -2
  109. data/{lib/metasm → metasm/cpu}/ppc/main.rb +23 -18
  110. data/{lib/metasm → metasm/cpu}/ppc/opcodes.rb +11 -6
  111. data/metasm/cpu/ppc/parse.rb +55 -0
  112. data/metasm/cpu/python.rb +8 -0
  113. data/metasm/cpu/python/decode.rb +116 -0
  114. data/metasm/cpu/python/main.rb +36 -0
  115. data/metasm/cpu/python/opcodes.rb +180 -0
  116. data/{lib/metasm → metasm/cpu}/sh4.rb +1 -1
  117. data/{lib/metasm → metasm/cpu}/sh4/decode.rb +50 -23
  118. data/{lib/metasm → metasm/cpu}/sh4/main.rb +38 -27
  119. data/{lib/metasm → metasm/cpu}/sh4/opcodes.rb +7 -8
  120. data/metasm/cpu/st20.rb +9 -0
  121. data/metasm/cpu/st20/decode.rb +173 -0
  122. data/metasm/cpu/st20/decompile.rb +283 -0
  123. data/metasm/cpu/st20/main.rb +37 -0
  124. data/metasm/cpu/st20/opcodes.rb +140 -0
  125. data/{lib/metasm/arm.rb → metasm/cpu/webasm.rb} +4 -5
  126. data/metasm/cpu/webasm/debug.rb +31 -0
  127. data/metasm/cpu/webasm/decode.rb +321 -0
  128. data/metasm/cpu/webasm/decompile.rb +386 -0
  129. data/metasm/cpu/webasm/encode.rb +104 -0
  130. data/metasm/cpu/webasm/main.rb +81 -0
  131. data/metasm/cpu/webasm/opcodes.rb +214 -0
  132. data/metasm/cpu/x86_64.rb +15 -0
  133. data/{lib/metasm → metasm/cpu}/x86_64/compile_c.rb +40 -25
  134. data/{lib/metasm → metasm/cpu}/x86_64/debug.rb +4 -4
  135. data/{lib/metasm → metasm/cpu}/x86_64/decode.rb +58 -15
  136. data/{lib/metasm → metasm/cpu}/x86_64/encode.rb +59 -28
  137. data/{lib/metasm → metasm/cpu}/x86_64/main.rb +18 -6
  138. data/metasm/cpu/x86_64/opcodes.rb +138 -0
  139. data/{lib/metasm → metasm/cpu}/x86_64/parse.rb +12 -4
  140. data/metasm/cpu/x86_64/render.rb +35 -0
  141. data/metasm/cpu/z80.rb +9 -0
  142. data/metasm/cpu/z80/decode.rb +286 -0
  143. data/metasm/cpu/z80/main.rb +67 -0
  144. data/metasm/cpu/z80/opcodes.rb +224 -0
  145. data/metasm/cpu/z80/render.rb +48 -0
  146. data/{lib/metasm/os/main.rb → metasm/debug.rb} +201 -407
  147. data/{lib/metasm → metasm}/decode.rb +104 -24
  148. data/{lib/metasm → metasm}/decompile.rb +804 -478
  149. data/{lib/metasm → metasm}/disassemble.rb +385 -170
  150. data/{lib/metasm → metasm}/disassemble_api.rb +684 -105
  151. data/{lib/metasm → metasm}/dynldr.rb +231 -138
  152. data/{lib/metasm → metasm}/encode.rb +20 -5
  153. data/{lib/metasm → metasm}/exe_format/a_out.rb +9 -6
  154. data/{lib/metasm → metasm}/exe_format/autoexe.rb +3 -0
  155. data/{lib/metasm → metasm}/exe_format/bflt.rb +57 -27
  156. data/{lib/metasm → metasm}/exe_format/coff.rb +35 -7
  157. data/{lib/metasm → metasm}/exe_format/coff_decode.rb +70 -23
  158. data/{lib/metasm → metasm}/exe_format/coff_encode.rb +24 -22
  159. data/{lib/metasm → metasm}/exe_format/dex.rb +26 -8
  160. data/{lib/metasm → metasm}/exe_format/dol.rb +1 -0
  161. data/{lib/metasm → metasm}/exe_format/elf.rb +108 -58
  162. data/{lib/metasm → metasm}/exe_format/elf_decode.rb +202 -36
  163. data/{lib/metasm → metasm}/exe_format/elf_encode.rb +126 -32
  164. data/metasm/exe_format/gb.rb +65 -0
  165. data/metasm/exe_format/javaclass.rb +424 -0
  166. data/{lib/metasm → metasm}/exe_format/macho.rb +218 -16
  167. data/{lib/metasm → metasm}/exe_format/main.rb +28 -3
  168. data/{lib/metasm → metasm}/exe_format/mz.rb +2 -0
  169. data/{lib/metasm → metasm}/exe_format/nds.rb +7 -4
  170. data/{lib/metasm → metasm}/exe_format/pe.rb +96 -11
  171. data/metasm/exe_format/pyc.rb +167 -0
  172. data/{lib/metasm → metasm}/exe_format/serialstruct.rb +67 -14
  173. data/{lib/metasm → metasm}/exe_format/shellcode.rb +7 -3
  174. data/metasm/exe_format/shellcode_rwx.rb +114 -0
  175. data/metasm/exe_format/swf.rb +205 -0
  176. data/metasm/exe_format/wasm.rb +402 -0
  177. data/{lib/metasm → metasm}/exe_format/xcoff.rb +7 -7
  178. data/metasm/exe_format/zip.rb +335 -0
  179. data/metasm/gui.rb +13 -0
  180. data/{lib/metasm → metasm}/gui/cstruct.rb +35 -41
  181. data/{lib/metasm → metasm}/gui/dasm_coverage.rb +11 -11
  182. data/{lib/metasm → metasm}/gui/dasm_decomp.rb +177 -114
  183. data/{lib/metasm → metasm}/gui/dasm_funcgraph.rb +0 -0
  184. data/metasm/gui/dasm_graph.rb +1754 -0
  185. data/{lib/metasm → metasm}/gui/dasm_hex.rb +16 -12
  186. data/{lib/metasm → metasm}/gui/dasm_listing.rb +43 -28
  187. data/{lib/metasm → metasm}/gui/dasm_main.rb +360 -77
  188. data/{lib/metasm → metasm}/gui/dasm_opcodes.rb +5 -19
  189. data/{lib/metasm → metasm}/gui/debug.rb +109 -34
  190. data/{lib/metasm → metasm}/gui/gtk.rb +174 -44
  191. data/{lib/metasm → metasm}/gui/qt.rb +14 -4
  192. data/{lib/metasm → metasm}/gui/win32.rb +180 -43
  193. data/{lib/metasm → metasm}/gui/x11.rb +59 -59
  194. data/{lib/metasm → metasm}/main.rb +421 -286
  195. data/metasm/os/emulator.rb +175 -0
  196. data/{lib/metasm/os/remote.rb → metasm/os/gdbremote.rb} +146 -54
  197. data/{lib/metasm → metasm}/os/gnu_exports.rb +1 -1
  198. data/{lib/metasm → metasm}/os/linux.rb +628 -151
  199. data/metasm/os/main.rb +335 -0
  200. data/{lib/metasm → metasm}/os/windows.rb +151 -58
  201. data/{lib/metasm → metasm}/os/windows_exports.rb +141 -0
  202. data/{lib/metasm → metasm}/parse.rb +49 -36
  203. data/{lib/metasm → metasm}/parse_c.rb +405 -246
  204. data/{lib/metasm → metasm}/preprocessor.rb +71 -41
  205. data/{lib/metasm → metasm}/render.rb +14 -38
  206. data/misc/hexdump.rb +4 -3
  207. data/misc/lint.rb +58 -0
  208. data/misc/objdiff.rb +4 -1
  209. data/misc/objscan.rb +1 -1
  210. data/misc/openrisc-parser.rb +79 -0
  211. data/misc/txt2html.rb +9 -7
  212. data/samples/bindiff.rb +3 -4
  213. data/samples/dasm-plugins/bindiff.rb +15 -0
  214. data/samples/dasm-plugins/bookmark.rb +133 -0
  215. data/samples/dasm-plugins/c_constants.rb +57 -0
  216. data/samples/dasm-plugins/colortheme_solarized.rb +125 -0
  217. data/samples/dasm-plugins/cppobj_funcall.rb +60 -0
  218. data/samples/dasm-plugins/dasm_all.rb +70 -0
  219. data/samples/dasm-plugins/demangle_cpp.rb +31 -0
  220. data/samples/dasm-plugins/deobfuscate.rb +251 -0
  221. data/samples/dasm-plugins/dump_text.rb +35 -0
  222. data/samples/dasm-plugins/export_graph_svg.rb +86 -0
  223. data/samples/dasm-plugins/findgadget.rb +75 -0
  224. data/samples/dasm-plugins/hl_opcode.rb +32 -0
  225. data/samples/dasm-plugins/hotfix_gtk_dbg.rb +19 -0
  226. data/samples/dasm-plugins/imm2off.rb +34 -0
  227. data/samples/dasm-plugins/match_libsigs.rb +93 -0
  228. data/samples/dasm-plugins/patch_file.rb +95 -0
  229. data/samples/dasm-plugins/scanfuncstart.rb +36 -0
  230. data/samples/dasm-plugins/scanxrefs.rb +29 -0
  231. data/samples/dasm-plugins/selfmodify.rb +197 -0
  232. data/samples/dasm-plugins/stringsxrefs.rb +28 -0
  233. data/samples/dasmnavig.rb +1 -1
  234. data/samples/dbg-apihook.rb +24 -9
  235. data/samples/dbg-plugins/heapscan.rb +283 -0
  236. data/samples/dbg-plugins/heapscan/compiled_heapscan_lin.c +155 -0
  237. data/samples/dbg-plugins/heapscan/compiled_heapscan_win.c +128 -0
  238. data/samples/dbg-plugins/heapscan/graphheap.rb +616 -0
  239. data/samples/dbg-plugins/heapscan/heapscan.rb +709 -0
  240. data/samples/dbg-plugins/heapscan/winheap.h +174 -0
  241. data/samples/dbg-plugins/heapscan/winheap7.h +307 -0
  242. data/samples/dbg-plugins/trace_func.rb +214 -0
  243. data/samples/disassemble-gui.rb +48 -7
  244. data/samples/disassemble.rb +31 -6
  245. data/samples/dump_upx.rb +24 -12
  246. data/samples/dynamic_ruby.rb +35 -27
  247. data/samples/elfencode.rb +15 -0
  248. data/samples/emubios.rb +251 -0
  249. data/samples/emudbg.rb +127 -0
  250. data/samples/exeencode.rb +6 -5
  251. data/samples/factorize-headers-peimports.rb +1 -1
  252. data/samples/lindebug.rb +186 -391
  253. data/samples/metasm-shell.rb +68 -57
  254. data/samples/peldr.rb +2 -2
  255. data/tests/all.rb +1 -1
  256. data/tests/arc.rb +26 -0
  257. data/tests/dynldr.rb +22 -4
  258. data/tests/expression.rb +57 -0
  259. data/tests/graph_layout.rb +285 -0
  260. data/tests/ia32.rb +80 -26
  261. data/tests/mcs51.rb +27 -0
  262. data/tests/mips.rb +10 -3
  263. data/tests/preprocessor.rb +18 -0
  264. data/tests/x86_64.rb +66 -18
  265. metadata +465 -219
  266. metadata.gz.sig +2 -0
  267. data/lib/metasm/arm/opcodes.rb +0 -177
  268. data/lib/metasm/gui.rb +0 -23
  269. data/lib/metasm/gui/dasm_graph.rb +0 -1354
  270. data/lib/metasm/ia32.rb +0 -14
  271. data/lib/metasm/ia32/opcodes.rb +0 -872
  272. data/lib/metasm/ppc/parse.rb +0 -52
  273. data/lib/metasm/x86_64.rb +0 -12
  274. data/lib/metasm/x86_64/opcodes.rb +0 -118
  275. data/samples/gdbclient.rb +0 -583
  276. data/samples/rubstop.rb +0 -399
@@ -0,0 +1,81 @@
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/main'
7
+
8
+ module Metasm
9
+
10
+ class WebAsm < CPU
11
+ attr_accessor :wasm_file
12
+ def initialize(*args)
13
+ super()
14
+ @size = args.grep(Integer).first || 64
15
+ @wasm_file = args.grep(ExeFormat).first
16
+ @endianness = args.delete(:little) || args.delete(:big) || (@wasm_file ? @wasm_file.endianness : :little)
17
+ end
18
+
19
+ class Memref
20
+ attr_accessor :off
21
+
22
+ def initialize(off)
23
+ @off = Expression[off]
24
+ end
25
+
26
+ def symbolic(di=nil)
27
+ sz = 8
28
+ off = Expression[:mem, :+, [@off]]
29
+ if di and di.opcode.name =~ /(32|64)\.(load|store)(8|16|32)?/
30
+ opsz, op, mode = $1, $2, $3
31
+ sz = mode ? mode.to_i/8 : opsz.to_i/8
32
+ stack_off = (op == 'store' ? [:opstack, :+, 8] : [:opstack])
33
+ off = Expression[Indirection[stack_off, 4], :+, off]
34
+ end
35
+ Indirection[off, sz, (di.address if di)]
36
+ end
37
+
38
+ include Renderable
39
+ def render
40
+ ['[', @off, ']']
41
+ end
42
+ end
43
+
44
+ class BrTable
45
+ attr_accessor :ary, :default
46
+ def initialize(ary, default)
47
+ @ary = ary
48
+ @default = default
49
+ end
50
+
51
+ include Renderable
52
+ def render
53
+ out = ['[']
54
+ @ary.each { |a| out << a << ', ' }
55
+ out.pop if out.length > 1
56
+ out << ']' << ' or ' << @default
57
+ end
58
+ end
59
+
60
+ class BlockSignature
61
+ attr_accessor :id
62
+
63
+ def initialize(id)
64
+ @id = id
65
+ end
66
+
67
+ def symbolic(di=nil)
68
+ Expression[@id]
69
+ end
70
+
71
+ include Renderable
72
+ def render
73
+ [WasmFile::TYPE.fetch(@id, Expression[@id])]
74
+ end
75
+ end
76
+
77
+ def init_opcode_list
78
+ init
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,214 @@
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/webasm/main'
7
+
8
+ module Metasm
9
+ class WebAsm
10
+ def addop(name, bin, *args)
11
+ o = Opcode.new name, bin
12
+
13
+ args.each { |a|
14
+ if a == :mem
15
+ o.args << :uleb << :memoff
16
+ elsif @valid_props[a]
17
+ o.props[a] = true
18
+ else
19
+ o.args << a
20
+ end
21
+ }
22
+
23
+ @opcode_list << o
24
+ end
25
+
26
+ def init
27
+ @opcode_list = []
28
+ @valid_props = { :setip => true, :stopexec => true, :saveip => true }
29
+
30
+ addop 'unreachable', 0x00, :stopexec
31
+ addop 'nop', 0x01
32
+ addop 'block', 0x02, :blocksig # arg = signature (block_type)
33
+ addop 'loop', 0x03, :blocksig # ^
34
+ addop 'if', 0x04, :blocksig, :setip # ^
35
+ addop 'else', 0x05, :setip, :stopexec
36
+ addop 'end', 0x0b, :stopexec # end of function (default with no function context)
37
+ addop 'end', 0x0b # end of if/else/block/loop
38
+ addop 'br', 0x0c, :uleb, :setip, :stopexec # arg = depth to break up to
39
+ addop 'br_if', 0x0d, :uleb, :setip
40
+ addop 'br_table', 0x0e, :br_table, :setip, :stopexec
41
+ addop 'return', 0x0f, :stopexec
42
+ addop 'call', 0x10, :uleb, :setip, :saveip, :stopexec # function index
43
+ addop 'call_indirect', 0x11, :uleb, :uleb, :setip, :saveip, :stopexec # type index for target function signature ; table index where the function indexes come from (fixed 0)
44
+
45
+ addop 'drop', 0x1a
46
+ addop 'select', 0x1b
47
+
48
+ addop 'get_local', 0x20, :uleb
49
+ addop 'set_local', 0x21, :uleb
50
+ addop 'tee_local', 0x22, :uleb
51
+ addop 'get_global', 0x23, :uleb
52
+ addop 'set_global', 0x24, :uleb
53
+
54
+ addop 'i32.load', 0x28, :mem
55
+ addop 'i64.load', 0x29, :mem
56
+ addop 'f32.load', 0x2a, :mem
57
+ addop 'f64.load', 0x2b, :mem
58
+ addop 'i32.load8_s', 0x2c, :mem
59
+ addop 'i32.load8_u', 0x2d, :mem
60
+ addop 'i32.load16_s', 0x2e, :mem
61
+ addop 'i32.load16_u', 0x2f, :mem
62
+ addop 'i64.load8_s', 0x30, :mem
63
+ addop 'i64.load8_u', 0x31, :mem
64
+ addop 'i64.load16_s', 0x32, :mem
65
+ addop 'i64.load16_u', 0x33, :mem
66
+ addop 'i64.load32_s', 0x34, :mem
67
+ addop 'i64.load32_u', 0x35, :mem
68
+ addop 'i32.store', 0x36, :mem
69
+ addop 'i64.store', 0x37, :mem
70
+ addop 'f32.store', 0x38, :mem
71
+ addop 'f64.store', 0x39, :mem
72
+ addop 'i32.store8', 0x3a, :mem
73
+ addop 'i32.store16', 0x3b, :mem
74
+ addop 'i64.store8', 0x3c, :mem
75
+ addop 'i64.store16', 0x3d, :mem
76
+ addop 'i64.store32', 0x3e, :mem
77
+ addop 'current_memory', 0x3f, :uleb # resv1
78
+ addop 'grow_memory', 0x40, :uleb # resv1
79
+
80
+ addop 'i32.const', 0x41, :sleb
81
+ addop 'i64.const', 0x42, :sleb
82
+ addop 'f32.const', 0x43, :f32
83
+ addop 'f64.const', 0x44, :f64
84
+
85
+ addop 'i32.eqz', 0x45
86
+ addop 'i32.eq', 0x46
87
+ addop 'i32.ne', 0x47
88
+ addop 'i32.lt_s', 0x48
89
+ addop 'i32.lt_u', 0x49
90
+ addop 'i32.gt_s', 0x4a
91
+ addop 'i32.gt_u', 0x4b
92
+ addop 'i32.le_s', 0x4c
93
+ addop 'i32.le_u', 0x4d
94
+ addop 'i32.ge_s', 0x4e
95
+ addop 'i32.ge_u', 0x4f
96
+ addop 'i64.eqz', 0x50
97
+ addop 'i64.eq', 0x51
98
+ addop 'i64.ne', 0x52
99
+ addop 'i64.lt_s', 0x53
100
+ addop 'i64.lt_u', 0x54
101
+ addop 'i64.gt_s', 0x55
102
+ addop 'i64.gt_u', 0x56
103
+ addop 'i64.le_s', 0x57
104
+ addop 'i64.le_u', 0x58
105
+ addop 'i64.ge_s', 0x59
106
+ addop 'i64.ge_u', 0x5a
107
+ addop 'f32.eq', 0x5b
108
+ addop 'f32.ne', 0x5c
109
+ addop 'f32.lt', 0x5d
110
+ addop 'f32.gt', 0x5e
111
+ addop 'f32.le', 0x5f
112
+ addop 'f32.ge', 0x60
113
+ addop 'f64.eq', 0x61
114
+ addop 'f64.ne', 0x62
115
+ addop 'f64.lt', 0x63
116
+ addop 'f64.gt', 0x64
117
+ addop 'f64.le', 0x65
118
+ addop 'f64.ge', 0x66
119
+
120
+ addop 'i32.clz', 0x67
121
+ addop 'i32.ctz', 0x68
122
+ addop 'i32.popcnt', 0x69
123
+ addop 'i32.add', 0x6a
124
+ addop 'i32.sub', 0x6b
125
+ addop 'i32.mul', 0x6c
126
+ addop 'i32.div_s', 0x6d
127
+ addop 'i32.div_u', 0x6e
128
+ addop 'i32.rem_s', 0x6f
129
+ addop 'i32.rem_u', 0x70
130
+ addop 'i32.and', 0x71
131
+ addop 'i32.or', 0x72
132
+ addop 'i32.xor', 0x73
133
+ addop 'i32.shl', 0x74
134
+ addop 'i32.shr_s', 0x75
135
+ addop 'i32.shr_u', 0x76
136
+ addop 'i32.rotl', 0x77
137
+ addop 'i32.rotr', 0x78
138
+ addop 'i64.clz', 0x79
139
+ addop 'i64.ctz', 0x7a
140
+ addop 'i64.popcnt', 0x7b
141
+ addop 'i64.add', 0x7c
142
+ addop 'i64.sub', 0x7d
143
+ addop 'i64.mul', 0x7e
144
+ addop 'i64.div_s', 0x7f
145
+ addop 'i64.div_u', 0x80
146
+ addop 'i64.rem_s', 0x81
147
+ addop 'i64.rem_u', 0x82
148
+ addop 'i64.and', 0x83
149
+ addop 'i64.or', 0x84
150
+ addop 'i64.xor', 0x85
151
+ addop 'i64.shl', 0x86
152
+ addop 'i64.shr_s', 0x87
153
+ addop 'i64.shr_u', 0x88
154
+ addop 'i64.rotl', 0x89
155
+ addop 'i64.rotr', 0x8a
156
+ addop 'f32.abs', 0x8b
157
+ addop 'f32.neg', 0x8c
158
+ addop 'f32.ceil', 0x8d
159
+ addop 'f32.floor', 0x8e
160
+ addop 'f32.trunc', 0x8f
161
+ addop 'f32.nearest', 0x90
162
+ addop 'f32.sqrt', 0x91
163
+ addop 'f32.add', 0x92
164
+ addop 'f32.sub', 0x93
165
+ addop 'f32.mul', 0x94
166
+ addop 'f32.div', 0x95
167
+ addop 'f32.min', 0x96
168
+ addop 'f32.max', 0x97
169
+ addop 'f32.copysign', 0x98
170
+ addop 'f64.abs', 0x99
171
+ addop 'f64.neg', 0x9a
172
+ addop 'f64.ceil', 0x9b
173
+ addop 'f64.floor', 0x9c
174
+ addop 'f64.trunc', 0x9d
175
+ addop 'f64.nearest', 0x9e
176
+ addop 'f64.sqrt', 0x9f
177
+ addop 'f64.add', 0xa0
178
+ addop 'f64.sub', 0xa1
179
+ addop 'f64.mul', 0xa2
180
+ addop 'f64.div', 0xa3
181
+ addop 'f64.min', 0xa4
182
+ addop 'f64.max', 0xa5
183
+ addop 'f64.copysign', 0xa6
184
+
185
+ addop 'i32.wrap/i64', 0xa7
186
+ addop 'i32.trunc_s/f32', 0xa8
187
+ addop 'i32.trunc_u/f32', 0xa9
188
+ addop 'i32.trunc_s/f64', 0xaa
189
+ addop 'i32.trunc_u/f64', 0xab
190
+ addop 'i64.extend_s/i32', 0xac
191
+ addop 'i64.extend_u/i32', 0xad
192
+ addop 'i64.trunc_s/f32', 0xae
193
+ addop 'i64.trunc_u/f32', 0xaf
194
+ addop 'i64.trunc_s/f64', 0xb0
195
+ addop 'i64.trunc_u/f64', 0xb1
196
+ addop 'f32.convert_s/i32', 0xb2
197
+ addop 'f32.convert_u/i32', 0xb3
198
+ addop 'f32.convert_s/i64', 0xb4
199
+ addop 'f32.convert_u/i64', 0xb5
200
+ addop 'f32.demote/f64', 0xb6
201
+ addop 'f64.convert_s/i32', 0xb7
202
+ addop 'f64.convert_u/i32', 0xb8
203
+ addop 'f64.convert_s/i64', 0xb9
204
+ addop 'f64.convert_u/i64', 0xba
205
+ addop 'f64.promote/f32', 0xbb
206
+
207
+ addop 'i32.reinterpret/f32', 0xbc
208
+ addop 'i64.reinterpret/f64', 0xbd
209
+ addop 'f32.reinterpret/i32', 0xbe
210
+ addop 'f64.reinterpret/i64', 0xbf
211
+ end
212
+
213
+ end
214
+ end
@@ -0,0 +1,15 @@
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
+ class Metasm::X86_64 < Metasm::Ia32
7
+ end
8
+
9
+ require 'metasm/main'
10
+ require 'metasm/cpu/x86_64/parse'
11
+ require 'metasm/cpu/x86_64/encode'
12
+ require 'metasm/cpu/x86_64/decode'
13
+ require 'metasm/cpu/x86_64/render'
14
+ require 'metasm/cpu/x86_64/debug'
15
+ require 'metasm/cpu/x86_64/compile_c'
@@ -4,7 +4,7 @@
4
4
  # Licence is LGPL, see LICENCE in the top-level directory
5
5
 
6
6
 
7
- require 'metasm/x86_64/parse'
7
+ require 'metasm/cpu/x86_64/parse'
8
8
  require 'metasm/compile_c'
9
9
 
10
10
  module Metasm
@@ -32,6 +32,8 @@ class CCompiler < C::Compiler
32
32
  attr_accessor :regargs
33
33
  # stack space reserved for subfunction in ABI
34
34
  attr_accessor :args_space
35
+ # ensure stack is 16byte aligned before calls
36
+ attr_accessor :stack_align16
35
37
  # list of reg values that are not kept across function call
36
38
  attr_accessor :abi_flushregs_call
37
39
  # list of regs we can trash without restoring them
@@ -52,6 +54,7 @@ class CCompiler < C::Compiler
52
54
  @bound = {}
53
55
  @regargs = []
54
56
  @args_space = 0
57
+ @stack_align16 = true
55
58
  @abi_flushregs_call = [0, 1, 2, 6, 7, 8, 9, 10, 11]
56
59
  @abi_trashregs = @abi_flushregs_call.dup
57
60
  end
@@ -236,7 +239,7 @@ class CCompiler < C::Compiler
236
239
  e2
237
240
  elsif type.float?
238
241
  raise 'float unhandled'
239
- else raise
242
+ else raise "cannot cast #{e} to #{type}"
240
243
  end
241
244
  elsif e.kind_of? Address
242
245
  make_volatile resolve_address(e), type, rsz
@@ -247,6 +250,7 @@ class CCompiler < C::Compiler
247
250
  e2
248
251
  elsif type.float?
249
252
  raise 'float unhandled'
253
+ else raise "cannot cast #{e} to #{type}"
250
254
  end
251
255
  else
252
256
  e
@@ -262,7 +266,7 @@ class CCompiler < C::Compiler
262
266
  elsif i >= (1<<64)-0x8000_0000
263
267
  v = Expression[Expression.make_signed(i, 64)]
264
268
  else
265
- v = make_volatile(v)
269
+ v = make_volatile(v, C::BaseType.new(:int))
266
270
  unuse v
267
271
  end
268
272
  end
@@ -417,7 +421,6 @@ class CCompiler < C::Compiler
417
421
  r = reg
418
422
  end
419
423
  end
420
- else raise
421
424
  end
422
425
  r
423
426
  end
@@ -491,7 +494,9 @@ class CCompiler < C::Compiler
491
494
  unuse l
492
495
  l = Address.new(l.modrm.dup)
493
496
  inuse l
494
- if l.modrm.b
497
+ if (l.modrm.b and l.modrm.b.val == 16) or (l.modrm.i and l.modrm.i.val == 16)
498
+ # cannot encode [rip+reg+imm]
499
+ elsif l.modrm.b
495
500
  if not l.modrm.i or (l.modrm.i.val == r.val and l.modrm.s == 1)
496
501
  l.modrm.i = r
497
502
  l.modrm.s = (l.modrm.s || 0) + 1
@@ -512,6 +517,7 @@ class CCompiler < C::Compiler
512
517
  end
513
518
  when :-
514
519
  r = c_cexpr_inner(expr.rexpr)
520
+ r = resolve_address r if r.kind_of? Address
515
521
  if r.kind_of? Expression
516
522
  unuse l, r
517
523
  l = Address.new(l.modrm.dup)
@@ -574,6 +580,13 @@ class CCompiler < C::Compiler
574
580
  else
575
581
  instr 'mov', l, Reg.new(r.val, l.sz)
576
582
  end
583
+ elsif l.kind_of? ModRM and r.kind_of? Expression and l.sz == 64
584
+ rval = r.reduce
585
+ if !rval.kind_of?(Integer) or rval > 0xffff_ffff or rval < -0x8000_0000
586
+ r = make_volatile(r, expr.type)
587
+ unuse r
588
+ end
589
+ instr 'mov', l, r
577
590
  else
578
591
  instr 'mov', l, r
579
592
  end
@@ -586,6 +599,7 @@ class CCompiler < C::Compiler
586
599
  l = c_cexpr_inner(expr.lexpr)
587
600
  l = make_volatile(l, expr.type)
588
601
  r = c_cexpr_inner(expr.rexpr)
602
+ r = make_volatile(r, expr.type) if r.kind_of?(ModRM) and r.sz != l.sz
589
603
  unuse r
590
604
  if expr.lexpr.type.integral? or expr.lexpr.type.pointer?
591
605
  instr 'cmp', l, i_to_i32(r)
@@ -611,7 +625,6 @@ class CCompiler < C::Compiler
611
625
  ft = ft.pointed if ft.pointer?
612
626
  ft = nil if not ft.kind_of? C::Function
613
627
 
614
- arglist = expr.rexpr.dup
615
628
  regargsmask = @state.regargs.dup
616
629
  if ft
617
630
  ft.args.each_with_index { |a, i|
@@ -638,21 +651,21 @@ class CCompiler < C::Compiler
638
651
 
639
652
  stackargs = expr.rexpr.zip(regargsmask).map { |a, r| a if not r }.compact
640
653
 
641
- # preserve 16byte stack align under windows
642
- stackalign = true if (stackargs + backup).length & 1 == 1
643
- instr 'push', rax if stackalign
654
+ stackalign = true if @state.stack_align16 and (stackargs + backup).length & 1 == 1
655
+ instr 'sub', Reg.new(4, @cpusz), Expression[8] if stackalign
644
656
 
645
657
  stackargs.reverse_each { |arg|
646
658
  raise 'arg unhandled' if not arg.type.integral? or arg.type.pointer?
647
659
  a = c_cexpr_inner(arg)
648
- a = resolve_address a if a.kind_of? Address
649
- a = make_volatile(a, arg.type) if a.kind_of? ModRM and arg.type.name != :__int64
660
+ a = resolve_address a if a.kind_of?(Address)
661
+ a = make_volatile(a, arg.type) if (a.kind_of?(ModRM) and arg.type.name != :__int64) or
662
+ (a.kind_of?(Expression) and (va = a.reduce) and (not va.kind_of?(::Integer) or va < -0x8000_0000 or va > 0x7fff_ffff))
650
663
  unuse a
651
664
  instr 'push', a
652
665
  }
653
666
 
654
667
  regargs_unuse = []
655
- regargsmask.zip(expr.rexpr).each { |ra, arg|
668
+ regargsmask.zip(expr.rexpr).reverse_each { |ra, arg|
656
669
  next if not arg or not ra
657
670
  a = c_cexpr_inner(arg)
658
671
  a = resolve_address a if a.kind_of? Address
@@ -666,9 +679,9 @@ class CCompiler < C::Compiler
666
679
 
667
680
  if ft.kind_of? C::Function and ft.varargs and @state.args_space == 0
668
681
  # gcc stores here the nr of xmm args passed, real args are passed the standard way
669
- # TODO check visualstudio/ms ABI
670
682
  instr 'xor', rax, rax
671
683
  inuse rax
684
+ regargs_unuse << rax
672
685
  end
673
686
 
674
687
 
@@ -699,6 +712,7 @@ class CCompiler < C::Compiler
699
712
  else
700
713
  instr 'pop', Reg.new(reg, 64)
701
714
  end
715
+ inuse getreg(reg)
702
716
  }
703
717
  retreg
704
718
  end
@@ -750,8 +764,10 @@ class CCompiler < C::Compiler
750
764
 
751
765
  case op
752
766
  when 'add', 'sub', 'and', 'or', 'xor'
753
- r = make_volatile(r, type) if l.kind_of? ModRM and r.kind_of? ModRM
767
+ r = make_volatile(r, type) if l.kind_of?(ModRM) and r.kind_of?(ModRM)
768
+ r = make_volatile(r, type) if r.kind_of?(ModRM) and r.sz != l.sz # add rax, word [moo]
754
769
  unuse r
770
+ r = Reg.new(r.val, l.sz) if r.kind_of?(Reg) and l.kind_of?(ModRM) and l.sz and l.sz != r.sz # add byte ptr [rax], bl
755
771
  instr op, l, i_to_i32(r)
756
772
  when 'shr', 'sar', 'shl'
757
773
  if r.kind_of? Expression
@@ -780,6 +796,7 @@ class CCompiler < C::Compiler
780
796
  end
781
797
  instr 'mov', l, ll
782
798
  else
799
+ r = make_volatile(r, type) if r.kind_of?(ModRM) and r.sz != l.sz
783
800
  instr 'imul', l, r
784
801
  end
785
802
  unuse r
@@ -866,18 +883,21 @@ class CCompiler < C::Compiler
866
883
  l = c_cexpr_inner(expr.lexpr)
867
884
  r = c_cexpr_inner(expr.rexpr)
868
885
  r = make_volatile(r, expr.type) if r.kind_of? ModRM and l.kind_of? ModRM
886
+ r = make_volatile(r, expr.type) if r.kind_of?(ModRM) and r.sz != l.sz
887
+ l = make_volatile(l, expr.type) if l.kind_of?(ModRM) and r.kind_of?(Reg) and r.sz != l.sz
869
888
  if l.kind_of? Expression
870
889
  o = { :< => :>, :> => :<, :>= => :<=, :<= => :>= }[o] || o
871
890
  l, r = r, l
872
891
  end
873
- unuse l, r
874
892
  if expr.lexpr.type.integral? or expr.lexpr.type.pointer?
875
- r = Reg.new(r.val, l.sz) if r.kind_of? Reg and r.sz != l.sz # XXX
876
- instr 'cmp', l, i_to_i32(r)
893
+ rr = i_to_i32(r)
894
+ rr = Reg.new(rr.val, l.sz) if rr.kind_of? Reg and rr.sz != l.sz # XXX
895
+ instr 'cmp', l, rr
877
896
  elsif expr.lexpr.type.float?
878
897
  raise 'float unhandled'
879
898
  else raise 'bad comparison ' + expr.to_s
880
899
  end
900
+ unuse l, r
881
901
  op = 'j' + getcc(o, expr.lexpr.type)
882
902
  instr op, Expression[target]
883
903
  when :'!'
@@ -967,8 +987,7 @@ class CCompiler < C::Compiler
967
987
  @state.dirty -= @state.abi_trashregs
968
988
  if localspc
969
989
  localspc = (localspc + 7) / 8 * 8
970
- if @state.args_space > 0 and (localspc/8 + @state.dirty.length) & 1 == 1
971
- # ensure 16-o stack align on windows
990
+ if @state.stack_align16 and (localspc/8 + @state.dirty.length) & 1 == 1
972
991
  localspc += 8
973
992
  end
974
993
  ebp = @state.saved_rbp
@@ -987,7 +1006,7 @@ class CCompiler < C::Compiler
987
1006
  v = findvar(a)
988
1007
  instr 'mov', v, Reg.new(r, v.sz)
989
1008
  }
990
- elsif @state.args_space > 0 and @state.dirty.length & 1 == 0
1009
+ elsif @state.stack_align16 and @state.dirty.length & 1 == 0
991
1010
  instr 'sub', Reg.new(4, @cpusz), Expression[8]
992
1011
  end
993
1012
  @state.dirty.each { |reg|
@@ -1003,7 +1022,7 @@ class CCompiler < C::Compiler
1003
1022
  if ebp = @state.saved_rbp
1004
1023
  instr 'mov', Reg.new(4, ebp.sz), ebp
1005
1024
  instr 'pop', ebp
1006
- elsif @state.args_space > 0 and @state.dirty.length & 1 == 0
1025
+ elsif @state.stack_align16 and @state.dirty.length & 1 == 0
1007
1026
  instr 'add', Reg.new(4, @cpusz), Expression[8]
1008
1027
  end
1009
1028
  instr 'ret'
@@ -1011,10 +1030,6 @@ class CCompiler < C::Compiler
1011
1030
 
1012
1031
  def c_program_epilog
1013
1032
  end
1014
-
1015
- def check_reserved_name(var)
1016
- Reg.s_to_i[var.name] or super(var)
1017
- end
1018
1033
  end
1019
1034
 
1020
1035
  def new_ccompiler(parser, exe=ExeFormat.new)