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
data/lib/metasm/ia32.rb DELETED
@@ -1,14 +0,0 @@
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
- require 'metasm/ia32/parse'
9
- require 'metasm/ia32/encode'
10
- require 'metasm/ia32/decode'
11
- require 'metasm/ia32/render'
12
- require 'metasm/ia32/compile_c'
13
- require 'metasm/ia32/decompile'
14
- require 'metasm/ia32/debug'
@@ -1,872 +0,0 @@
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/ia32/main'
8
-
9
- module Metasm
10
- class Ia32
11
- def init_cpu_constants
12
- @opcode_list ||= []
13
- @fields_mask.update :w => 1, :s => 1, :d => 1, :modrm => 0xc7,
14
- :reg => 7, :eeec => 7, :eeed => 7, :seg2 => 3, :seg3 => 7,
15
- :regfp => 7, :regmmx => 7, :regxmm => 7
16
- @fields_mask[:seg2A] = @fields_mask[:seg2]
17
- @fields_mask[:seg3A] = @fields_mask[:seg3]
18
- @fields_mask[:modrmA] = @fields_mask[:modrm]
19
-
20
- @valid_args.concat [:i, :i8, :u8, :u16, :reg, :seg2, :seg2A,
21
- :seg3, :seg3A, :eeec, :eeed, :modrm, :modrmA, :mrm_imm,
22
- :farptr, :imm_val1, :imm_val3, :reg_cl, :reg_eax,
23
- :reg_dx, :regfp, :regfp0, :modrmmmx, :regmmx,
24
- :modrmxmm, :regxmm] - @valid_args
25
-
26
- @valid_props.concat [:strop, :stropz, :opsz, :argsz, :setip,
27
- :stopexec, :saveip, :unsigned_imm, :random, :needpfx,
28
- :xmmx] - @valid_props
29
- end
30
-
31
- # only most common instructions from the 386 instruction set
32
- # inexhaustive list :
33
- # no aaa, arpl, mov crX, call/jmp/ret far, in/out, bts, xchg...
34
- def init_386_common_only
35
- init_cpu_constants
36
-
37
- addop_macro1 'adc', 2
38
- addop_macro1 'add', 0
39
- addop_macro1 'and', 4, :u
40
- addop 'bswap', [0x0F, 0xC8], :reg
41
- addop 'call', [0xE8], nil, {}, :stopexec, :setip, :i, :saveip
42
- addop 'call', [0xFF], 2, {}, :stopexec, :setip, :saveip
43
- addop('cbw', [0x98]) { |o| o.props[:opsz] = 16 }
44
- addop('cwde', [0x98]) { |o| o.props[:opsz] = 32 }
45
- addop('cdqe', [0x98]) { |o| o.props[:opsz] = 64 }
46
- addop('cwd', [0x99]) { |o| o.props[:opsz] = 16 }
47
- addop('cdq', [0x99]) { |o| o.props[:opsz] = 32 }
48
- addop('cqo', [0x99]) { |o| o.props[:opsz] = 64 }
49
- addop_macro1 'cmp', 7
50
- addop_macrostr 'cmps', [0xA6], :stropz
51
- addop 'dec', [0x48], :reg
52
- addop 'dec', [0xFE], 1, {:w => [0, 0]}
53
- addop 'div', [0xF6], 6, {:w => [0, 0]}
54
- addop 'enter', [0xC8], nil, {}, :u16, :u8
55
- addop 'idiv', [0xF6], 7, {:w => [0, 0]}
56
- addop 'imul', [0xF6], 5, {:w => [0, 0]}, :reg_eax
57
- addop 'imul', [0x0F, 0xAF], :mrm
58
- addop 'imul', [0x69], :mrm, {:s => [0, 1]}, :i
59
- addop 'inc', [0x40], :reg
60
- addop 'inc', [0xFE], 0, {:w => [0, 0]}
61
- addop 'int', [0xCC], nil, {}, :imm_val3, :stopexec
62
- addop 'int', [0xCD], nil, {}, :u8
63
- addop_macrotttn 'j', [0x70], nil, {}, :setip, :i8
64
- addop_macrotttn 'j', [0x0F, 0x80], nil, {}, :setip, :i
65
- addop 'jmp', [0xE9], nil, {:s => [0, 1]}, :setip, :i, :stopexec
66
- addop 'jmp', [0xFF], 4, {}, :setip, :stopexec
67
- addop 'lea', [0x8D], :mrmA
68
- addop 'leave', [0xC9]
69
- addop_macrostr 'lods', [0xAC], :strop
70
- addop 'loop', [0xE2], nil, {}, :setip, :i8
71
- addop 'loopz', [0xE1], nil, {}, :setip, :i8
72
- addop 'loope', [0xE1], nil, {}, :setip, :i8
73
- addop 'loopnz',[0xE0], nil, {}, :setip, :i8
74
- addop 'loopne',[0xE0], nil, {}, :setip, :i8
75
- addop 'mov', [0xA0], nil, {:w => [0, 0], :d => [0, 1]}, :mrm_imm, :reg_eax
76
- addop 'mov', [0x88], :mrmw,{:d => [0, 1]}
77
- addop 'mov', [0xB0], :reg, {:w => [0, 3]}, :u
78
- addop 'mov', [0xC6], 0, {:w => [0, 0]}, :u
79
- addop_macrostr 'movs', [0xA4], :strop
80
- addop 'movsx', [0x0F, 0xBE], :mrmw
81
- addop 'movzx', [0x0F, 0xB6], :mrmw
82
- addop 'mul', [0xF6], 4, {:w => [0, 0]}
83
- addop 'neg', [0xF6], 3, {:w => [0, 0]}
84
- addop 'nop', [0x90]
85
- addop 'not', [0xF6], 2, {:w => [0, 0]}
86
- addop_macro1 'or', 1, :u
87
- addop 'pop', [0x58], :reg
88
- addop 'pop', [0x8F], 0
89
- addop 'push', [0x50], :reg
90
- addop 'push', [0xFF], 6
91
- addop 'push', [0x68], nil, {:s => [0, 1]}, :u
92
- addop 'ret', [0xC3], nil, {}, :stopexec, :setip
93
- addop 'ret', [0xC2], nil, {}, :stopexec, :u16, :setip
94
- addop_macro3 'rol', 0
95
- addop_macro3 'ror', 1
96
- addop_macro3 'sar', 7
97
- addop_macro1 'sbb', 3
98
- addop_macrostr 'scas', [0xAE], :stropz
99
- addop_macrotttn('set', [0x0F, 0x90], 0) { |o| o.props[:argsz] = 8 }
100
- addop_macrotttn('set', [0x0F, 0x90], :mrm) { |o| o.props[:argsz] = 8 ; o.args.reverse! } # :reg field is unused
101
- addop_macro3 'shl', 4
102
- addop_macro3 'sal', 6
103
- addop 'shld', [0x0F, 0xA4], :mrm, {}, :u8
104
- addop 'shld', [0x0F, 0xA5], :mrm, {}, :reg_cl
105
- addop_macro3 'shr', 5
106
- addop 'shrd', [0x0F, 0xAC], :mrm, {}, :u8
107
- addop 'shrd', [0x0F, 0xAD], :mrm, {}, :reg_cl
108
- addop_macrostr 'stos', [0xAA], :strop
109
- addop_macro1 'sub', 5
110
- addop 'test', [0x84], :mrmw
111
- addop 'test', [0xA8], nil, {:w => [0, 0]}, :reg_eax, :u
112
- addop 'test', [0xF6], 0, {:w => [0, 0]}, :u
113
- addop 'xchg', [0x90], :reg, {}, :reg_eax
114
- addop('xchg', [0x90], :reg, {}, :reg_eax) { |o| o.args.reverse! } # xchg eax, ebx == xchg ebx, eax)
115
- addop 'xchg', [0x86], :mrmw
116
- addop('xchg', [0x86], :mrmw) { |o| o.args.reverse! }
117
- addop_macro1 'xor', 6, :u
118
- end
119
-
120
- def init_386_only
121
- init_cpu_constants
122
-
123
- addop 'aaa', [0x37]
124
- addop 'aad', [0xD5, 0x0A]
125
- addop 'aam', [0xD4, 0x0A]
126
- addop 'aas', [0x3F]
127
- addop('arpl', [0x63], :mrm) { |o| o.props[:argsz] = 16 ; o.args.reverse! }
128
- addop 'bound', [0x62], :mrmA
129
- addop 'bsf', [0x0F, 0xBC], :mrm
130
- addop 'bsr', [0x0F, 0xBD], :mrm
131
- addop_macro2 'bt' , 0
132
- addop_macro2 'btc', 3
133
- addop_macro2 'btr', 2
134
- addop_macro2 'bts', 1
135
- addop 'call', [0x9A], nil, {}, :stopexec, :setip, :farptr, :saveip
136
- addop 'callf', [0x9A], nil, {}, :stopexec, :setip, :farptr, :saveip
137
- addop 'callf', [0xFF], 3, {}, :stopexec, :setip, :saveip
138
- addop 'clc', [0xF8]
139
- addop 'cld', [0xFC]
140
- addop 'cli', [0xFA]
141
- addop 'clts', [0x0F, 0x06]
142
- addop 'cmc', [0xF5]
143
- addop('cmpxchg',[0x0F, 0xB0], :mrmw) { |o| o.args.reverse! }
144
- addop 'cpuid', [0x0F, 0xA2]
145
- addop 'daa', [0x27]
146
- addop 'das', [0x2F]
147
- addop 'hlt', [0xF4], nil, {}, :stopexec
148
- addop 'in', [0xE4], nil, {:w => [0, 0]}, :reg_eax, :u8
149
- addop 'in', [0xE4], nil, {:w => [0, 0]}, :u8
150
- addop 'in', [0xEC], nil, {:w => [0, 0]}, :reg_eax, :reg_dx
151
- addop 'in', [0xEC], nil, {:w => [0, 0]}, :reg_eax
152
- addop 'in', [0xEC], nil, {:w => [0, 0]}
153
- addop_macrostr 'ins', [0x6C], :strop
154
- addop 'into', [0xCE]
155
- addop 'invd', [0x0F, 0x08]
156
- addop 'invlpg',[0x0F, 0x01, 7<<3], :modrmA
157
- addop 'iret', [0xCF], nil, {}, :stopexec, :setip
158
- addop 'iretd', [0xCF], nil, {}, :stopexec, :setip
159
- addop('jcxz', [0xE3], nil, {}, :setip, :i8) { |o| o.props[:opsz] = 16 }
160
- addop('jecxz', [0xE3], nil, {}, :setip, :i8) { |o| o.props[:opsz] = 32 }
161
- addop 'jmp', [0xEA], nil, {}, :farptr, :setip, :stopexec
162
- addop 'jmpf', [0xEA], nil, {}, :farptr, :setip, :stopexec
163
- addop 'jmpf', [0xFF], 5, {}, :stopexec, :setip # reg ?
164
- addop 'lahf', [0x9F]
165
- addop 'lar', [0x0F, 0x02], :mrm
166
- addop 'lds', [0xC5], :mrmA
167
- addop 'les', [0xC4], :mrmA
168
- addop 'lfs', [0x0F, 0xB4], :mrmA
169
- addop 'lgs', [0x0F, 0xB5], :mrmA
170
- addop 'lgdt', [0x0F, 0x01], 2
171
- addop 'lidt', [0x0F, 0x01, 3<<3], :modrmA
172
- addop 'lldt', [0x0F, 0x00], 2
173
- addop 'lmsw', [0x0F, 0x01], 6
174
- # prefix addop 'lock', [0xF0]
175
- addop 'lsl', [0x0F, 0x03], :mrm
176
- addop 'lss', [0x0F, 0xB2], :mrmA
177
- addop 'ltr', [0x0F, 0x00], 3
178
- addop('mov', [0x0F, 0x20, 0xC0], :reg, {:d => [1, 1], :eeec => [2, 3]}, :eeec) { |op| op.args.reverse! }
179
- addop('mov', [0x0F, 0x21, 0xC0], :reg, {:d => [1, 1], :eeed => [2, 3]}, :eeed) { |op| op.args.reverse! }
180
- addop('mov', [0x8C], 0, {:d => [0, 1], :seg3 => [1, 3]}, :seg3) { |op| op.args.reverse! }
181
- addop 'out', [0xE6], nil, {:w => [0, 0]}, :u8, :reg_eax
182
- addop 'out', [0xE6], nil, {:w => [0, 0]}, :reg_eax, :u8
183
- addop 'out', [0xE6], nil, {:w => [0, 0]}, :u8
184
- addop 'out', [0xEE], nil, {:w => [0, 0]}, :reg_dx, :reg_eax
185
- addop 'out', [0xEE], nil, {:w => [0, 0]}, :reg_eax, :reg_dx
186
- addop 'out', [0xEE], nil, {:w => [0, 0]}, :reg_eax # implicit arguments
187
- addop 'out', [0xEE], nil, {:w => [0, 0]}
188
- addop_macrostr 'outs', [0x6E], :strop
189
- addop 'pop', [0x07], nil, {:seg2A => [0, 3]}, :seg2A
190
- addop 'pop', [0x0F, 0x81], nil, {:seg3A => [1, 3]}, :seg3A
191
- addop('popa', [0x61]) { |o| o.props[:opsz] = 16 }
192
- addop('popad', [0x61]) { |o| o.props[:opsz] = 32 }
193
- addop('popf', [0x9D]) { |o| o.props[:opsz] = 16 }
194
- addop('popfd', [0x9D]) { |o| o.props[:opsz] = 32 }
195
- addop 'push', [0x06], nil, {:seg2 => [0, 3]}, :seg2
196
- addop 'push', [0x0F, 0x80], nil, {:seg3A => [1, 3]}, :seg3A
197
- addop('pusha', [0x60]) { |o| o.props[:opsz] = 16 }
198
- addop('pushad',[0x60]) { |o| o.props[:opsz] = 32 }
199
- addop('pushf', [0x9C]) { |o| o.props[:opsz] = 16 }
200
- addop('pushfd',[0x9C]) { |o| o.props[:opsz] = 32 }
201
- addop_macro3 'rcl', 2
202
- addop_macro3 'rcr', 3
203
- addop 'rdmsr', [0x0F, 0x32]
204
- addop 'rdpmc', [0x0F, 0x33]
205
- addop 'rdtsc', [0x0F, 0x31], nil, {}, :random
206
- addop 'retf', [0xCB], nil, {}, :stopexec, :setip
207
- addop 'retf', [0xCA], nil, {}, :stopexec, :u16, :setip
208
- addop 'rsm', [0x0F, 0xAA], nil, {}, :stopexec
209
- addop 'sahf', [0x9E]
210
- addop 'sgdt', [0x0F, 0x01, 0<<3], :modrmA
211
- addop 'sidt', [0x0F, 0x01, 1<<3], :modrmA
212
- addop 'sldt', [0x0F, 0x00], 0
213
- addop 'smsw', [0x0F, 0x01], 4
214
- addop 'stc', [0xF9]
215
- addop 'std', [0xFD]
216
- addop 'sti', [0xFB]
217
- addop 'str', [0x0F, 0x00], 1
218
- addop 'ud2', [0x0F, 0x0B]
219
- addop 'verr', [0x0F, 0x00], 4
220
- addop 'verw', [0x0F, 0x00], 5
221
- addop 'wait', [0x9B]
222
- addop 'wbinvd',[0x0F, 0x09]
223
- addop 'wrmsr', [0x0F, 0x30]
224
- addop('xadd', [0x0F, 0xC0], :mrmw) { |o| o.args.reverse! }
225
- addop 'xlat', [0xD7]
226
-
227
- # pfx: addrsz = 0x67, lock = 0xf0, opsz = 0x66, repnz = 0xf2, rep/repz = 0xf3
228
- # cs/nojmp = 0x2E, ds/jmp = 0x3E, es = 0x26, fs = 0x64, gs = 0x65, ss = 0x36
229
- # undocumented opcodes
230
- # TODO put these in the right place (486/P6/...)
231
- addop 'aam', [0xD4], nil, {}, :u8
232
- addop 'aad', [0xD5], nil, {}, :u8
233
- addop 'setalc', [0xD6]
234
- addop 'salc', [0xD6]
235
- addop 'icebp', [0xF1]
236
- #addop 'loadall',[0x0F, 0x07] # conflict with syscall
237
- addop 'ud2', [0x0F, 0xB9]
238
- addop 'umov', [0x0F, 0x10], :mrmw,{:d => [1, 1]}
239
- end
240
-
241
- def init_387_only
242
- init_cpu_constants
243
-
244
- addop 'f2xm1', [0xD9, 0xF0]
245
- addop 'fabs', [0xD9, 0xE1]
246
- addop_macrofpu1 'fadd', 0
247
- addop 'faddp', [0xDE, 0xC0], :regfp
248
- addop 'faddp', [0xDE, 0xC1]
249
- addop('fbld', [0xDF, 4<<3], :modrmA, {}, :regfp0) { |o| o.props[:argsz] = 80 }
250
- addop('fbstp', [0xDF, 6<<3], :modrmA, {}, :regfp0) { |o| o.props[:argsz] = 80 }
251
- addop 'fchs', [0xD9, 0xE0], nil, {}, :regfp0
252
- addop 'fnclex', [0xDB, 0xE2]
253
- addop_macrofpu1 'fcom', 2
254
- addop_macrofpu1 'fcomp', 3
255
- addop 'fcompp',[0xDE, 0xD9]
256
- addop 'fcomip',[0xDF, 0xF0], :regfp
257
- addop 'fcos', [0xD9, 0xFF], nil, {}, :regfp0
258
- addop 'fdecstp', [0xD9, 0xF6]
259
- addop_macrofpu1 'fdiv', 6
260
- addop_macrofpu1 'fdivr', 7
261
- addop 'fdivp', [0xDE, 0xF8], :regfp
262
- addop 'fdivp', [0xDE, 0xF9]
263
- addop 'fdivrp',[0xDE, 0xF0], :regfp
264
- addop 'fdivrp',[0xDE, 0xF1]
265
- addop 'ffree', [0xDD, 0xC0], nil, {:regfp => [1, 0]}, :regfp
266
- addop_macrofpu2 'fiadd', 0
267
- addop_macrofpu2 'fimul', 1
268
- addop_macrofpu2 'ficom', 2
269
- addop_macrofpu2 'ficomp',3
270
- addop_macrofpu2 'fisub', 4
271
- addop_macrofpu2 'fisubr',5
272
- addop_macrofpu2 'fidiv', 6
273
- addop_macrofpu2 'fidivr',7
274
- addop 'fincstp', [0xD9, 0xF7]
275
- addop 'fninit', [0xDB, 0xE3]
276
- addop_macrofpu2 'fist', 2, 1
277
- addop_macrofpu3 'fild', 0
278
- addop_macrofpu3 'fistp',3
279
- addop('fld', [0xD9, 0<<3], :modrmA, {}, :regfp0) { |o| o.props[:argsz] = 32 }
280
- addop('fld', [0xDD, 0<<3], :modrmA, {}, :regfp0) { |o| o.props[:argsz] = 64 }
281
- addop('fld', [0xDB, 5<<3], :modrmA, {}, :regfp0) { |o| o.props[:argsz] = 80 }
282
- addop 'fld', [0xD9, 0xC0], :regfp
283
-
284
- addop('fldcw', [0xD9, 5<<3], :modrmA) { |o| o.props[:argsz] = 16 }
285
- addop 'fldenv', [0xD9, 4<<3], :modrmA
286
- addop 'fld1', [0xD9, 0xE8]
287
- addop 'fldl2t', [0xD9, 0xE9]
288
- addop 'fldl2e', [0xD9, 0xEA]
289
- addop 'fldpi', [0xD9, 0xEB]
290
- addop 'fldlg2', [0xD9, 0xEC]
291
- addop 'fldln2', [0xD9, 0xED]
292
- addop 'fldz', [0xD9, 0xEE]
293
- addop_macrofpu1 'fmul', 1
294
- addop 'fmulp', [0xDE, 0xC8], :regfp
295
- addop 'fmulp', [0xDE, 0xC9]
296
- addop 'fnop', [0xD9, 0xD0]
297
- addop 'fpatan', [0xD9, 0xF3]
298
- addop 'fprem', [0xD9, 0xF8]
299
- addop 'fprem1', [0xD9, 0xF5]
300
- addop 'fptan', [0xD9, 0xF2]
301
- addop 'frndint',[0xD9, 0xFC]
302
- addop 'frstor', [0xDD, 4<<3], :modrmA
303
- addop 'fnsave', [0xDD, 6<<3], :modrmA
304
- addop('fnstcw', [0xD9, 7<<3], :modrmA) { |o| o.props[:argsz] = 16 }
305
- addop 'fnstenv',[0xD9, 6<<3], :modrmA
306
- addop 'fnstsw', [0xDF, 0xE0]
307
- addop('fnstsw', [0xDD, 7<<3], :modrmA) { |o| o.props[:argsz] = 16 }
308
- addop 'fscale', [0xD9, 0xFD]
309
- addop 'fsin', [0xD9, 0xFE]
310
- addop 'fsincos',[0xD9, 0xFB]
311
- addop 'fsqrt', [0xD9, 0xFA]
312
- addop('fst', [0xD9, 2<<3], :modrmA, {}, :regfp0) { |o| o.props[:argsz] = 32 }
313
- addop('fst', [0xDD, 2<<3], :modrmA, {}, :regfp0) { |o| o.props[:argsz] = 64 }
314
- addop 'fst', [0xD9, 0xD0], :regfp
315
- addop('fstp', [0xD9, 3<<3], :modrmA, {}, :regfp0) { |o| o.props[:argsz] = 32 }
316
- addop('fstp', [0xDD, 3<<3], :modrmA, {}, :regfp0) { |o| o.props[:argsz] = 64 }
317
- addop('fstp', [0xDB, 7<<3], :modrmA, {}, :regfp0) { |o| o.props[:argsz] = 80 }
318
- addop 'fstp', [0xDD, 0xD8], :regfp
319
- addop_macrofpu1 'fsub', 4
320
- addop 'fsubp', [0xDE, 0xE8], :regfp
321
- addop 'fsubp', [0xDE, 0xE9]
322
- addop_macrofpu1 'fsubp', 5
323
- addop 'fsubrp', [0xDE, 0xE0], :regfp
324
- addop 'fsubrp', [0xDE, 0xE1]
325
- addop 'ftst', [0xD9, 0xE4]
326
- addop 'fucom', [0xDD, 0xE0], :regfp
327
- addop 'fucomp', [0xDD, 0xE8], :regfp
328
- addop 'fucompp',[0xDA, 0xE9]
329
- addop 'fucomi', [0xDB, 0xE8], :regfp
330
- addop 'fxam', [0xD9, 0xE5]
331
- addop 'fxch', [0xD9, 0xC8], :regfp
332
- addop 'fxtract',[0xD9, 0xF4]
333
- addop 'fyl2x', [0xD9, 0xF1]
334
- addop 'fyl2xp1',[0xD9, 0xF9]
335
- # fwait prefix
336
- addop 'fclex', [0x9B, 0xDB, 0xE2]
337
- addop 'finit', [0x9B, 0xDB, 0xE3]
338
- addop 'fsave', [0x9B, 0xDD, 6<<3], :modrmA
339
- addop('fstcw', [0x9B, 0xD9, 7<<3], :modrmA) { |o| o.props[:argsz] = 16 }
340
- addop 'fstenv', [0x9B, 0xD9, 6<<3], :modrmA
341
- addop 'fstsw', [0x9B, 0xDF, 0xE0]
342
- addop('fstsw', [0x9B, 0xDD, 7<<3], :modrmA) { |o| o.props[:argsz] = 16 }
343
- addop 'fwait', [0x9B]
344
- end
345
-
346
- def init_486_only
347
- init_cpu_constants
348
- # TODO add new segments (fs/gs) ?
349
- end
350
-
351
- def init_pentium_only
352
- init_cpu_constants
353
-
354
- addop 'cmpxchg8b', [0x0F, 0xC7], 1
355
- # lock cmpxchg8b eax
356
- #addop 'f00fbug', [0xF0, 0x0F, 0xC7, 0xC8]
357
-
358
- # mmx
359
- addop 'emms', [0x0F, 0x77]
360
- addop('movd', [0x0F, 0x6E], :mrmmmx, {:d => [1, 4]}) { |o| o.args[o.args.index(:modrmmmx)] = :modrm ; o.args.reverse! }
361
- addop('movq', [0x0F, 0x6F], :mrmmmx, {:d => [1, 4]}) { |o| o.args.reverse! }
362
- addop 'packssdw', [0x0F, 0x6B], :mrmmmx
363
- addop 'packsswb', [0x0F, 0x63], :mrmmmx
364
- addop 'packuswb', [0x0F, 0x67], :mrmmmx
365
- addop_macrogg 0..2, 'padd', [0x0F, 0xFC], :mrmmmx
366
- addop_macrogg 0..1, 'padds', [0x0F, 0xEC], :mrmmmx
367
- addop_macrogg 0..1, 'paddus',[0x0F, 0xDC], :mrmmmx
368
- addop 'pand', [0x0F, 0xDB], :mrmmmx
369
- addop 'pandn', [0x0F, 0xDF], :mrmmmx
370
- addop_macrogg 0..2, 'pcmpeq',[0x0F, 0x74], :mrmmmx
371
- addop_macrogg 0..2, 'pcmpgt',[0x0F, 0x64], :mrmmmx
372
- addop 'pmaddwd', [0x0F, 0xF5], :mrmmmx
373
- addop 'pmulhuw', [0x0F, 0xE4], :mrmmmx
374
- addop 'pmulhw',[0x0F, 0xE5], :mrmmmx
375
- addop 'pmullw',[0x0F, 0xD5], :mrmmmx
376
- addop 'por', [0x0F, 0xEB], :mrmmmx
377
- addop_macrommx 1..3, 'psll', 3
378
- addop_macrommx 1..2, 'psra', 2
379
- addop_macrommx 1..3, 'psrl', 1
380
- addop_macrogg 0..2, 'psub', [0x0F, 0xF8], :mrmmmx
381
- addop_macrogg 0..1, 'psubs', [0x0F, 0xE8], :mrmmmx
382
- addop_macrogg 0..1, 'psubus',[0x0F, 0xD8], :mrmmmx
383
- addop_macrogg 1..3, 'punchkh', [0x0F, 0x68], :mrmmmx
384
- addop_macrogg 1..3, 'punpckl', [0x0F, 0x60], :mrmmmx
385
- addop 'pxor', [0x0F, 0xEF], :mrmmmx
386
- end
387
-
388
- def init_p6_only
389
- addop_macrotttn 'cmov', [0x0F, 0x40], :mrm
390
-
391
- %w{b e be u}.each_with_index { |tt, i|
392
- addop 'fcmov' + tt, [0xDA, 0xC0 | (i << 3)], :regfp
393
- addop 'fcmovn'+ tt, [0xDB, 0xC0 | (i << 3)], :regfp
394
- }
395
- addop 'fcomi', [0xDB, 0xF0], :regfp
396
- addop('fxrstor', [0x0F, 0xAE, 1<<3], :modrmA) { |o| o.props[:argsz] = 512*8 }
397
- addop('fxsave', [0x0F, 0xAE, 0<<3], :modrmA) { |o| o.props[:argsz] = 512*8 }
398
- addop 'sysenter',[0x0F, 0x34]
399
- addop 'sysexit', [0x0F, 0x35]
400
-
401
- addop 'syscall', [0x0F, 0x05] # AMD
402
- addop 'sysret', [0x0F, 0x07] # AMD
403
- end
404
-
405
- def init_3dnow_only
406
- init_cpu_constants
407
-
408
- [['pavgusb', 0xBF], ['pfadd', 0x9E], ['pfsub', 0x9A],
409
- ['pfsubr', 0xAA], ['pfacc', 0xAE], ['pfcmpge', 0x90],
410
- ['pfcmpgt', 0xA0], ['fpcmpeq', 0xB0], ['pfmin', 0x94],
411
- ['pfmax', 0xA4], ['pi2fd', 0x0D], ['pf2id', 0x1D],
412
- ['pfrcp', 0x96], ['pfrsqrt', 0x97], ['pfmul', 0xB4],
413
- ['pfrcpit1', 0xA6], ['pfrsqit1', 0xA7], ['pfrcpit2', 0xB6],
414
- ['pmulhrw', 0xB7]].each { |str, bin|
415
- addop str, [0x0F, 0x0F, bin], :mrmmmx
416
- }
417
- # 3dnow prefix fallback
418
- addop '3dnow', [0x0F, 0x0F], :mrmmmx, {}, :u8
419
-
420
- addop 'femms', [0x0F, 0x0E]
421
- addop 'prefetch', [0x0F, 0x0D, 0<<3], :modrmA
422
- addop 'prefetchw', [0x0F, 0x0D, 1<<3], :modrmA
423
- end
424
-
425
- def init_sse_only
426
- init_cpu_constants
427
-
428
- addop_macrossps 'addps', [0x0F, 0xA8], :mrmxmm
429
- addop 'andnps', [0x0F, 0xAA], :mrmxmm
430
- addop 'andps', [0x0F, 0xA4], :mrmxmm
431
- addop_macrossps 'cmpps', [0x0F, 0xC2], :mrmxmm
432
- addop 'comiss', [0x0F, 0x2F], :mrmxmm
433
-
434
- [['pi2ps', 0x2A], ['ps2pi', 0x2D], ['tps2pi', 0x2C]].each { |str, bin|
435
- addop('cvt' << str, [0x0F, bin], :mrmxmm) { |o| o.args[o.args.index(:modrmxmm)] = :modrmmmx }
436
- addop('cvt' << str.tr('p', 's'), [0x0F, bin], :mrmxmm) { |o| o.args[o.args.index(:modrmxmm)] = :modrm ; o.props[:needpfx] = 0xF3 }
437
- }
438
-
439
- addop_macrossps 'divps', [0x0F, 0x5E], :mrmxmm
440
- addop 'ldmxcsr', [0x0F, 0xAE, 2<<3], :modrmA
441
- addop_macrossps 'maxps', [0x0F, 0x5F], :mrmxmm
442
- addop_macrossps 'minps', [0x0F, 0x5D], :mrmxmm
443
- addop('movaps', [0x0F, 0x28], :mrmxmm, {:d => [1, 0]}) { |o| o.args.reverse! }
444
- addop('movd', [0x0F, 0x6E], :mrmxmm, {:d => [1, 4]}) { |o| o.args[o.args.index(:modrmxmm)] = :modrm ; o.args.reverse! ; o.props[:needpfx] = 0x66 }
445
- addop('movdqa', [0x0F, 0x6F], :mrmxmm, {:d => [1, 4]}) { |o| o.args.reverse! ; o.props[:needpfx] = 0x66 }
446
-
447
- # movhlps(reg, reg){nomem} == movlps(reg, mrm){no restriction}...
448
- addop 'movhlps', [0x0F, 0x12], :mrmxmm, {:d => [1, 0]}
449
- addop 'movlps', [0x0F, 0x12], :mrmxmm, {:d => [1, 0]}
450
- addop 'movlhps', [0x0F, 0x16], :mrmxmm, {:d => [1, 0]}
451
- addop 'movhps', [0x0F, 0x16], :mrmxmm, {:d => [1, 0]}
452
-
453
- addop 'movmskps',[0x0F, 0x50, 0xC0], nil, {:reg => [2, 3], :regxmm => [2, 0]}, :regxmm, :reg
454
- addop('movss', [0x0F, 0x10], :mrmxmm, {:d => [1, 0]}) { |o| o.props[:needpfx] = 0xF3 }
455
- addop 'movups', [0x0F, 0x10], :mrmxmm, {:d => [1, 0]}
456
- addop_macrossps 'mulps', [0x0F, 0x59], :mrmxmm
457
- addop 'orps', [0x0F, 0x56], :mrmxmm
458
- addop_macrossps 'rcpps', [0x0F, 0x53], :mrmxmm
459
- addop_macrossps 'rsqrtps',[0x0F, 0x52], :mrmxmm
460
- addop 'shufps', [0x0F, 0xC6], :mrmxmm, {}, :u8
461
- addop_macrossps 'sqrtps', [0x0F, 0x51], :mrmxmm
462
- addop 'stmxcsr', [0x0F, 0xAE, 3<<3], :modrmA
463
- addop_macrossps 'subps', [0x0F, 0x5C], :mrmxmm
464
- addop 'ucomiss', [0x0F, 0x2E], :mrmxmm
465
- addop 'unpckhps',[0x0F, 0x15], :mrmxmm
466
- addop 'unpcklps',[0x0F, 0x14], :mrmxmm
467
- addop 'xorps', [0x0F, 0x57], :mrmxmm
468
-
469
- # start of integer instruction (accept opsz override prefix to access xmm)
470
- addop('pavgb', [0x0F, 0xE0], :mrmmmx) { |o| o.props[:xmmx] = true }
471
- addop('pavgw', [0x0F, 0xE3], :mrmmmx) { |o| o.props[:xmmx] = true }
472
- # TODO addop('pextrw', [0x0F, 0xC5], :mrmmmx) { |o| o.fields[:reg] = o.fields.delete(:regmmx) } { |o| o.props[:xmmx] = true ; o.args << :u8 }
473
- # addop('pinsrw', [0x0F, 0xC4], :mrmmmx) { |o| o.fields[:reg] = o.fields.delete(:regmmx) } { |o| o.props[:xmmx] = true ; o.args << :u8 }
474
- addop('pmaxsw', [0x0F, 0xEE], :mrmmmx) { |o| o.props[:xmmx] = true }
475
- addop('pmaxub', [0x0F, 0xDE], :mrmmmx) { |o| o.props[:xmmx] = true }
476
- addop('pminsw', [0x0F, 0xEA], :mrmmmx) { |o| o.props[:xmmx] = true }
477
- addop('pminub', [0x0F, 0xDA], :mrmmmx) { |o| o.props[:xmmx] = true }
478
- # addop('pmovmskb',[0x0F, 0xD4], :mrmmmx) { |o| o.fields[:reg] = o.fields.delete(:regmmx) } ) { |o| o.props[:xmmx] = true } # no mem ref in the mrm
479
- addop('pmulhuw', [0x0F, 0xE4], :mrmmmx) { |o| o.props[:xmmx] = true }
480
- addop('psadbw', [0x0F, 0xF6], :mrmmmx) { |o| o.props[:xmmx] = true }
481
- addop('pshufw', [0x0F, 0x70], :mrmmmx) { |o| o.props[:xmmx] = true ; o.args << :u8 }
482
- addop('maskmovq',[0x0F, 0xF7], :mrmmmx) { |o| o.props[:xmmx] = true } # nomem
483
- addop('movntq', [0x0F, 0xE7], :mrmmmx) { |o| o.props[:xmmx] = true }
484
- addop 'movntps', [0x0F, 0x2B], :mrmxmm
485
- addop 'prefetcht0', [0x0F, 0x18, 1<<3], :modrmA
486
- addop 'prefetcht1', [0x0F, 0x18, 2<<3], :modrmA
487
- addop 'prefetcht2', [0x0F, 0x18, 3<<3], :modrmA
488
- addop 'prefetchnta',[0x0F, 0x18, 0<<3], :modrmA
489
- addop 'sfence', [0x0F, 0xAE, 0xF8]
490
- end
491
-
492
- # XXX must be done after init_sse (patches :regmmx opcodes)
493
- # TODO complete the list
494
- def init_sse2_only
495
- init_cpu_constants
496
-
497
- @opcode_list.each { |o| o.props[:xmmx] = true if o.args.include? :regmmx and o.args.include? :modrmmmx }
498
-
499
- # TODO <..blabla...integer...blabla..>
500
-
501
- # nomem
502
- addop('clflush', [0x0F, 0xAE, 7<<3], :modrmA) { |o| o.props[:argsz] = 8 }
503
- addop('maskmovdqu', [0x0F, 0xF7], :mrmxmm) { |o| o.props[:needpfx] = 0x66 }
504
- addop('movntpd', [0x0F, 0x2B], :mrmxmm) { |o| o.props[:needpfx] = 0x66 }
505
- addop('movntdq', [0x0F, 0xE7], :mrmxmm) { |o| o.props[:needpfx] = 0x66 }
506
- addop 'movnti', [0x0F, 0xC3], :mrm
507
- addop('pause', [0x90]) { |o| o.props[:needpfx] = 0xF3 }
508
- addop 'lfence', [0x0F, 0xAE, 0xE8]
509
- addop 'mfence', [0x0F, 0xAE, 0xF0]
510
- end
511
-
512
- def init_sse3_only
513
- init_cpu_constants
514
-
515
- addop('addsubpd', [0x0F, 0xD0], :mrmxmm) { |o| o.props[:needpfx] = 0x66 }
516
- addop('addsubps', [0x0F, 0xD0], :mrmxmm) { |o| o.props[:needpfx] = 0xF2 }
517
- addop('haddpd', [0x0F, 0x7C], :mrmxmm) { |o| o.props[:needpfx] = 0x66 }
518
- addop('haddps', [0x0F, 0x7C], :mrmxmm) { |o| o.props[:needpfx] = 0xF2 }
519
- addop('hsubpd', [0x0F, 0x7D], :mrmxmm) { |o| o.props[:needpfx] = 0x66 }
520
- addop('hsubps', [0x0F, 0x7D], :mrmxmm) { |o| o.props[:needpfx] = 0xF2 }
521
-
522
- addop 'monitor', [0x0F, 0x01, 0xC8]
523
- addop 'mwait', [0x0F, 0x01, 0xC9]
524
-
525
- addop('fisttp', [0xDF, 1<<3], :modrmA) { |o| o.props[:argsz] = 16 }
526
- addop('fisttp', [0xDB, 1<<3], :modrmA) { |o| o.props[:argsz] = 32 }
527
- addop('fisttp', [0xDD, 1<<3], :modrmA) { |o| o.props[:argsz] = 64 }
528
- addop('lddqu', [0x0F, 0xF0], :mrmxmm) { |o| o.args[o.args.index(:modrmxmm)] = :modrmA ; o.props[:needpfx] = 0xF2 }
529
- addop('movddup', [0x0F, 0x12], :mrmxmm) { |o| o.props[:needpfx] = 0xF2 }
530
- addop('movshdup', [0x0F, 0x16], :mrmxmm) { |o| o.props[:needpfx] = 0xF3 }
531
- addop('movsldup', [0x0F, 0x12], :mrmxmm) { |o| o.props[:needpfx] = 0xF3 }
532
- end
533
-
534
- def init_vmx_only
535
- init_cpu_constants
536
-
537
- addop 'vmcall', [0x0F, 0x01, 0xC1]
538
- addop 'vmlaunch', [0x0F, 0x01, 0xC2]
539
- addop 'vmresume', [0x0F, 0x01, 0xC3]
540
- addop 'vmxoff', [0x0F, 0x01, 0xC4]
541
- addop 'vmread', [0x0F, 0x78], :mrm
542
- addop 'vmwrite', [0x0F, 0x79], :mrm
543
- addop('vmclear', [0x0F, 0xC7, 6<<3], :modrmA) { |o| o.props[:argsz] = 64 ; o.props[:needpfx] = 0x66 }
544
- addop('vmxon', [0x0F, 0xC7, 6<<3], :modrmA) { |o| o.props[:argsz] = 64 ; o.props[:needpfx] = 0xF3 }
545
- addop('vmptrld', [0x0F, 0xC7, 6<<3], :modrmA) { |o| o.props[:argsz] = 64 }
546
- addop('vmptrrst', [0x0F, 0xC7, 7<<3], :modrmA) { |o| o.props[:argsz] = 64 }
547
- addop('invept', [0x0F, 0x38, 0x80], :mrmA) { |o| o.props[:needpfx] = 0x66 }
548
- addop('invvpid', [0x0F, 0x38, 0x81], :mrmA) { |o| o.props[:needpfx] = 0x66 }
549
-
550
- addop 'getsec', [0x0F, 0x37]
551
-
552
- addop('movbe', [0x0F, 0x38, 0xF0], :mrm, { :d => [2, 0] }) { |o| o.args.reverse! }
553
- addop 'xgetbv', [0x0F, 0x01, 0xD0]
554
- addop 'xsetbv', [0x0F, 0x01, 0xD1]
555
- addop 'rdtscp', [0x0F, 0x01, 0xF9]
556
- addop 'xrstor', [0x0F, 0xAE, 5<<3], :modrmA
557
- addop 'xsave', [0x0F, 0xAE, 4<<3], :modrmA
558
- addop 'nop', [0x0F, 0x1F], 0 # which family does this belong to ?
559
- end
560
-
561
- def init_sse42_only
562
- init_cpu_constants
563
-
564
- addop('crc32', [0x0F, 0x38, 0xF0], :mrmw) { |o| o.props[:needpfx] = 0xF2 }
565
- addop('pcmpestrm', [0x0F, 0x3A, 0x60], :mrmxmm, {}, :i8) { |o| o.props[:needpfx] = 0x66 }
566
- addop('pcmpestri', [0x0F, 0x3A, 0x61], :mrmxmm, {}, :i8) { |o| o.props[:needpfx] = 0x66 }
567
- addop('pcmpistrm', [0x0F, 0x3A, 0x62], :mrmxmm, {}, :i8) { |o| o.props[:needpfx] = 0x66 }
568
- addop('pcmpistri', [0x0F, 0x3A, 0x63], :mrmxmm, {}, :i8) { |o| o.props[:needpfx] = 0x66 }
569
- addop('pcmpgtq', [0x0F, 0x38, 0x37], :mrmxmm) { |o| o.props[:needpfx] = 0x66 }
570
- addop('popcnt', [0x0F, 0xB8], :mrmxmm) { |o| o.props[:needpfx] = 0xF3 }
571
- end
572
-
573
-
574
- #
575
- # CPU family dependencies
576
- #
577
-
578
- def init_386_common
579
- init_386_common_only
580
- end
581
-
582
- def init_386
583
- init_386_common
584
- init_386_only
585
- end
586
-
587
- def init_387
588
- init_387_only
589
- end
590
-
591
- def init_486
592
- init_386
593
- init_387
594
- init_486_only
595
- end
596
-
597
- def init_pentium
598
- init_486
599
- init_pentium_only
600
- end
601
-
602
- def init_3dnow
603
- init_pentium
604
- init_3dnow_only
605
- end
606
-
607
- def init_p6
608
- init_pentium
609
- init_p6_only
610
- end
611
-
612
- def init_sse
613
- init_p6
614
- init_sse_only
615
- end
616
-
617
- def init_sse2
618
- init_sse
619
- init_sse2_only
620
- end
621
-
622
- def init_sse3
623
- init_sse2
624
- init_sse3_only
625
- end
626
-
627
- def init_vmx
628
- init_sse3
629
- init_vmx_only
630
- end
631
-
632
- def init_all
633
- init_vmx
634
- init_sse42_only
635
- init_3dnow_only
636
- end
637
-
638
- alias init_latest init_all
639
-
640
-
641
- #
642
- # addop_* macros
643
- #
644
-
645
- def addop_macro1(name, num, immtype=:i)
646
- addop name, [(num << 3) | 4], nil, {:w => [0, 0]}, :reg_eax, immtype
647
- addop name, [num << 3], :mrmw, {:d => [0, 1]}
648
- addop name, [0x80], num, {:w => [0, 0], :s => [0, 1]}, immtype
649
- end
650
- def addop_macro2(name, num)
651
- addop name, [0x0F, 0xBA], (4 | num), {}, :u8
652
- addop(name, [0x0F, 0xA3 | (num << 3)], :mrm) { |op| op.args.reverse! }
653
- end
654
- def addop_macro3(name, num)
655
- addop name, [0xD0], num, {:w => [0, 0]}, :imm_val1
656
- addop name, [0xD2], num, {:w => [0, 0]}, :reg_cl
657
- addop name, [0xC0], num, {:w => [0, 0]}, :u8
658
- end
659
-
660
- def addop_macrotttn(name, bin, hint, fields = {}, *props, &blk)
661
- [%w{o}, %w{no}, %w{b nae c}, %w{nb ae nc},
662
- %w{z e}, %w{nz ne}, %w{be na}, %w{nbe a},
663
- %w{s}, %w{ns}, %w{p pe}, %w{np po},
664
- %w{l nge}, %w{nl ge}, %w{le ng}, %w{nle g}].each_with_index { |e, i|
665
- b = bin.dup
666
- if b[0] == 0x0F
667
- b[1] |= i
668
- else
669
- b[0] |= i
670
- end
671
-
672
- e.each { |k| addop(name + k, b.dup, hint, fields.dup, *props, &blk) }
673
- }
674
- end
675
-
676
- def addop_macrostr(name, bin, type)
677
- # addop(name, bin.dup, {:w => [0, 0]}) { |o| o.props[type] = true } # TODO allow segment override
678
- addop(name+'b', bin) { |o| o.props[:opsz] = 16 ; o.props[type] = true }
679
- addop(name+'b', bin) { |o| o.props[:opsz] = 32 ; o.props[type] = true }
680
- bin = bin.dup
681
- bin[0] |= 1
682
- addop(name+'w', bin) { |o| o.props[:opsz] = 16 ; o.props[type] = true }
683
- addop(name+'d', bin) { |o| o.props[:opsz] = 32 ; o.props[type] = true }
684
- end
685
-
686
- def addop_macrofpu1(name, n)
687
- addop(name, [0xD8, n<<3], :modrmA, {}, :regfp0) { |o| o.props[:argsz] = 32 }
688
- addop(name, [0xDC, n<<3], :modrmA, {}, :regfp0) { |o| o.props[:argsz] = 64 }
689
- addop name, [0xD8, 0xC0|(n<<3)], :regfp, {:d => [0, 2]}
690
- end
691
- def addop_macrofpu2(name, n, n2=0)
692
- addop(name, [0xDE|n2, n<<3], :modrmA, {}, :regfp0) { |o| o.props[:argsz] = 16 }
693
- addop(name, [0xDA|n2, n<<3], :modrmA, {}, :regfp0) { |o| o.props[:argsz] = 32 }
694
- end
695
- def addop_macrofpu3(name, n)
696
- addop_macrofpu2 name, n, 1
697
- addop(name, [0xDF, 0x28|(n<<3)], :modrmA, {}, :regfp0) { |o| o.props[:argsz] = 64 }
698
- end
699
-
700
- def addop_macrogg(ggrng, name, bin, *args, &blk)
701
- ggrng.each { |gg|
702
- bindup = bin.dup
703
- bindup[1] |= gg
704
- sfx = %w(b w d q)[gg]
705
- addop name+sfx, bindup, *args, &blk
706
- }
707
- end
708
-
709
- def addop_macrommx(ggrng, name, val)
710
- addop_macrogg ggrng, name, [0x0F, 0xC0 | (val << 4)], :mrmmmx
711
- addop_macrogg ggrng, name, [0x0F, 0x70, 0xC0 | (val << 4)], nil, {:regmmx => [2, 0]}, :u8
712
- end
713
-
714
- def addop_macrossps(name, bin, hint)
715
- # don't allow fields argument, as this will be modified by addop (.dup it if needed)
716
- addop name, bin, hint
717
- addop(name.tr('p', 's'), bin, hint) { |o| o.props[:needpfx] = 0xF3 }
718
- end
719
-
720
- # helper function: creates a new Opcode based on the arguments, eventually
721
- # yields it for further customisation, and append it to the instruction set
722
- # is responsible of the creation of disambiguating opcodes if necessary (:s flag hardcoding)
723
- def addop(name, bin, hint=nil, fields={}, *argprops)
724
- op = Opcode.new name, bin
725
- op.fields.replace fields
726
-
727
- case hint
728
- when nil
729
-
730
- when :mrm, :mrmw, :mrmA
731
- h = (hint == :mrmA ? :modrmA : :modrm)
732
- op.fields[:reg] = [bin.length, 3]
733
- op.fields[h] = [bin.length, 0]
734
- op.fields[:w] = [bin.length - 1, 0] if hint == :mrmw
735
- argprops.unshift :reg, h
736
- op.bin << 0
737
- when :reg
738
- op.fields[:reg] = [bin.length-1, 0]
739
- argprops.unshift :reg
740
- when :regfp
741
- op.fields[:regfp] = [bin.length-1, 0]
742
- argprops.unshift :regfp, :regfp0
743
- when :modrmA
744
- op.fields[:modrmA] = [bin.length-1, 0]
745
- argprops << :modrmA
746
-
747
- when Integer # mod/m, reg == opcode extension = hint
748
- op.fields[:modrm] = [bin.length, 0]
749
- op.bin << (hint << 3)
750
- argprops.unshift :modrm
751
-
752
- when :mrmmmx
753
- op.fields[:regmmx] = [bin.length, 3]
754
- op.fields[:modrm] = [bin.length, 0]
755
- bin << 0
756
- argprops.unshift :regmmx, :modrmmmx
757
- when :mrmxmm
758
- op.fields[:regxmm] = [bin.length, 3]
759
- op.fields[:modrm] = [bin.length, 0]
760
- bin << 0
761
- argprops.unshift :regxmm, :modrmxmm
762
- else
763
- raise SyntaxError, "invalid hint #{hint.inspect} for #{name}"
764
- end
765
-
766
- if argprops.index(:u)
767
- argprops << :unsigned_imm
768
- argprops[argprops.index(:u)] = :i
769
- end
770
-
771
- (argprops & @valid_props).each { |p| op.props[p] = true }
772
- argprops -= @valid_props
773
-
774
- op.args.concat(argprops & @valid_args)
775
- argprops -= @valid_args
776
-
777
- raise "Invalid opcode definition: #{name}: unknown #{argprops.inspect}" unless argprops.empty?
778
-
779
- yield op if block_given?
780
-
781
- argprops = (op.props.keys - @valid_props) + (op.args - @valid_args) + (op.fields.keys - @fields_mask.keys)
782
- raise "Invalid opcode customisation: #{name}: #{argprops.inspect}" unless argprops.empty?
783
-
784
- addop_post(op)
785
- end
786
-
787
- # this recursive method is in charge of Opcode duplication (eg to hardcode some flag)
788
- def addop_post(op)
789
- dupe = lambda { |o|
790
- dop = Opcode.new o.name.dup
791
- dop.bin, dop.fields, dop.props, dop.args = o.bin.dup, o.fields.dup, o.props.dup, o.args.dup
792
- dop
793
- }
794
- if df = op.fields.delete(:d)
795
- # hardcode the bit
796
- dop = dupe[op]
797
- dop.args.reverse!
798
- addop_post dop
799
-
800
- op.bin[df[0]] |= 1 << df[1]
801
- addop_post op
802
-
803
- return
804
- elsif wf = op.fields.delete(:w)
805
- # hardcode the bit
806
- dop = dupe[op]
807
- dop.props[:argsz] = 8
808
- addop_post dop
809
-
810
- op.bin[wf[0]] |= 1 << wf[1]
811
- addop_post op
812
-
813
- return
814
- elsif sf = op.fields.delete(:s)
815
- # add explicit choice versions, with lower precedence (so that disassembling will return the general version)
816
- # eg "jmp", "jmp.i8", "jmp.i"
817
- # also hardcode the bit
818
- op32 = op
819
- addop_post op32
820
-
821
- op8 = dupe[op]
822
- op8.bin[sf[0]] |= 1 << sf[1]
823
- op8.args.map! { |arg| arg == :i ? :i8 : arg }
824
- addop_post op8
825
-
826
- op32 = dupe[op32]
827
- op32.name << '.i'
828
- addop_post op32
829
-
830
- op8 = dupe[op8]
831
- op8.name << '.i8'
832
- addop_post op8
833
-
834
- return
835
- elsif op.args.first == :regfp0
836
- dop = dupe[op]
837
- dop.args.delete :regfp0
838
- addop_post dop
839
- end
840
-
841
- if op.props[:needpfx] and @opcode_list.find { |oo| oo.name == op.name and not oo.props[:needpfx] }
842
- @opcode_list.unshift op
843
- else
844
- @opcode_list << op
845
- end
846
-
847
- if op.args == [:i] or op.args == [:farptr] or op.name[0, 3] == 'ret'
848
- # define opsz-override version for ambiguous opcodes
849
- op16 = dupe[op]
850
- op16.name << '.i16'
851
- op16.props[:opsz] = 16
852
- @opcode_list << op16
853
- op32 = dupe[op]
854
- op32.name << '.i32'
855
- op32.props[:opsz] = 32
856
- @opcode_list << op32
857
- elsif op.props[:strop] or op.props[:stropz] or op.args.include? :mrm_imm or
858
- op.args.include? :modrm or op.args.include? :modrmA or op.name =~ /loop|xlat/
859
- # define adsz-override version for ambiguous opcodes (TODO allow movsd edi / movsd di syntax)
860
- # XXX loop pfx 67 = eip+cx, 66 = ip+ecx
861
- op16 = dupe[op]
862
- op16.name << '.a16'
863
- op16.props[:adsz] = 16
864
- @opcode_list << op16
865
- op32 = dupe[op]
866
- op32.name << '.a32'
867
- op32.props[:adsz] = 32
868
- @opcode_list << op32
869
- end
870
- end
871
- end
872
- end