metasm 1.0.1 → 1.0.2

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