metasm 1.0.1 → 1.0.2

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