contrast-agent 3.8.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (500) hide show
  1. checksums.yaml +7 -0
  2. data/.clang-format +5 -0
  3. data/.dockerignore +10 -0
  4. data/.gitignore +58 -0
  5. data/.gitmodules +6 -0
  6. data/.rspec +6 -0
  7. data/.simplecov +4 -0
  8. data/Gemfile +7 -0
  9. data/LICENSE.txt +12 -0
  10. data/Rakefile +15 -0
  11. data/exe/contrast_service +29 -0
  12. data/ext/build_funchook.rb +48 -0
  13. data/ext/cs__assess_active_record_named/cs__active_record_named.c +47 -0
  14. data/ext/cs__assess_active_record_named/cs__active_record_named.h +10 -0
  15. data/ext/cs__assess_active_record_named/extconf.rb +2 -0
  16. data/ext/cs__assess_array/cs__assess_array.c +38 -0
  17. data/ext/cs__assess_array/cs__assess_array.h +9 -0
  18. data/ext/cs__assess_array/extconf.rb +2 -0
  19. data/ext/cs__assess_basic_object/cs__assess_basic_object.c +50 -0
  20. data/ext/cs__assess_basic_object/cs__assess_basic_object.h +17 -0
  21. data/ext/cs__assess_basic_object/extconf.rb +2 -0
  22. data/ext/cs__assess_fiber_track/cs__assess_fiber_track.c +86 -0
  23. data/ext/cs__assess_fiber_track/cs__assess_fiber_track.h +34 -0
  24. data/ext/cs__assess_fiber_track/extconf.rb +2 -0
  25. data/ext/cs__assess_hash/cs__assess_hash.c +64 -0
  26. data/ext/cs__assess_hash/cs__assess_hash.h +24 -0
  27. data/ext/cs__assess_hash/extconf.rb +2 -0
  28. data/ext/cs__assess_kernel/cs__assess_kernel.c +36 -0
  29. data/ext/cs__assess_kernel/cs__assess_kernel.h +10 -0
  30. data/ext/cs__assess_kernel/extconf.rb +2 -0
  31. data/ext/cs__assess_marshal_module/cs__assess_marshal_module.c +47 -0
  32. data/ext/cs__assess_marshal_module/cs__assess_marshal_module.h +18 -0
  33. data/ext/cs__assess_marshal_module/extconf.rb +2 -0
  34. data/ext/cs__assess_module/cs__assess_module.c +78 -0
  35. data/ext/cs__assess_module/cs__assess_module.h +25 -0
  36. data/ext/cs__assess_module/extconf.rb +2 -0
  37. data/ext/cs__assess_regexp/cs__assess_regexp.c +48 -0
  38. data/ext/cs__assess_regexp/cs__assess_regexp.h +22 -0
  39. data/ext/cs__assess_regexp/extconf.rb +2 -0
  40. data/ext/cs__assess_regexp_track/cs__assess_regexp_track.c +63 -0
  41. data/ext/cs__assess_regexp_track/cs__assess_regexp_track.h +29 -0
  42. data/ext/cs__assess_regexp_track/extconf.rb +2 -0
  43. data/ext/cs__assess_string/cs__assess_string.c +38 -0
  44. data/ext/cs__assess_string/cs__assess_string.h +19 -0
  45. data/ext/cs__assess_string/extconf.rb +2 -0
  46. data/ext/cs__assess_string_interpolation26/cs__assess_string_interpolation26.c +31 -0
  47. data/ext/cs__assess_string_interpolation26/cs__assess_string_interpolation26.h +13 -0
  48. data/ext/cs__assess_string_interpolation26/extconf.rb +2 -0
  49. data/ext/cs__common/cs__common.c +60 -0
  50. data/ext/cs__common/cs__common.h +28 -0
  51. data/ext/cs__common/extconf.rb +20 -0
  52. data/ext/cs__contrast_patch/cs__contrast_patch.c +445 -0
  53. data/ext/cs__contrast_patch/cs__contrast_patch.h +196 -0
  54. data/ext/cs__contrast_patch/extconf.rb +2 -0
  55. data/ext/cs__protect_kernel/cs__protect_kernel.c +37 -0
  56. data/ext/cs__protect_kernel/cs__protect_kernel.h +11 -0
  57. data/ext/cs__protect_kernel/extconf.rb +2 -0
  58. data/ext/cs__scope/cs__scope.c +96 -0
  59. data/ext/cs__scope/cs__scope.h +33 -0
  60. data/ext/cs__scope/extconf.rb +2 -0
  61. data/ext/extconf_common.rb +49 -0
  62. data/funchook/LICENSE +360 -0
  63. data/funchook/Makefile +29 -0
  64. data/funchook/Makefile.in +29 -0
  65. data/funchook/README.md +121 -0
  66. data/funchook/appveyor.yml +42 -0
  67. data/funchook/autogen.sh +3 -0
  68. data/funchook/autom4te.cache/output.0 +4976 -0
  69. data/funchook/autom4te.cache/requests +78 -0
  70. data/funchook/autom4te.cache/traces.0 +364 -0
  71. data/funchook/config.guess +1530 -0
  72. data/funchook/config.log +490 -0
  73. data/funchook/config.status +1016 -0
  74. data/funchook/config.sub +1773 -0
  75. data/funchook/configure +4976 -0
  76. data/funchook/configure.ac +59 -0
  77. data/funchook/distorm/COPYING +26 -0
  78. data/funchook/distorm/MANIFEST +25 -0
  79. data/funchook/distorm/MANIFEST.in +4 -0
  80. data/funchook/distorm/README.md +12 -0
  81. data/funchook/distorm/disOps/disOps.py +795 -0
  82. data/funchook/distorm/disOps/x86db.py +404 -0
  83. data/funchook/distorm/disOps/x86header.py +247 -0
  84. data/funchook/distorm/disOps/x86sets.py +1664 -0
  85. data/funchook/distorm/examples/cs/TestdiStorm/Program.cs +79 -0
  86. data/funchook/distorm/examples/cs/TestdiStorm/Properties/AssemblyInfo.cs +36 -0
  87. data/funchook/distorm/examples/cs/TestdiStorm/TestdiStorm.csproj +69 -0
  88. data/funchook/distorm/examples/cs/distorm-net.sln +26 -0
  89. data/funchook/distorm/examples/cs/distorm-net/CodeInfo.cs +23 -0
  90. data/funchook/distorm/examples/cs/distorm-net/DecodedInst.cs +15 -0
  91. data/funchook/distorm/examples/cs/distorm-net/DecodedResult.cs +14 -0
  92. data/funchook/distorm/examples/cs/distorm-net/DecomposedInst.cs +36 -0
  93. data/funchook/distorm/examples/cs/distorm-net/DecomposedResult.cs +14 -0
  94. data/funchook/distorm/examples/cs/distorm-net/Opcodes.cs +1268 -0
  95. data/funchook/distorm/examples/cs/distorm-net/Opcodes.tt +37 -0
  96. data/funchook/distorm/examples/cs/distorm-net/Operand.cs +25 -0
  97. data/funchook/distorm/examples/cs/distorm-net/Properties/AssemblyInfo.cs +36 -0
  98. data/funchook/distorm/examples/cs/distorm-net/diStorm3.cs +411 -0
  99. data/funchook/distorm/examples/cs/distorm-net/distorm-net.csproj +80 -0
  100. data/funchook/distorm/examples/cs/readme +3 -0
  101. data/funchook/distorm/examples/ddk/README +48 -0
  102. data/funchook/distorm/examples/ddk/distorm.ini +11 -0
  103. data/funchook/distorm/examples/ddk/dummy.c +15 -0
  104. data/funchook/distorm/examples/ddk/main.c +91 -0
  105. data/funchook/distorm/examples/ddk/makefile +1 -0
  106. data/funchook/distorm/examples/ddk/sources +10 -0
  107. data/funchook/distorm/examples/java/Makefile +23 -0
  108. data/funchook/distorm/examples/java/distorm/src/Main.java +43 -0
  109. data/funchook/distorm/examples/java/distorm/src/diStorm3/CodeInfo.java +27 -0
  110. data/funchook/distorm/examples/java/distorm/src/diStorm3/DecodedInst.java +32 -0
  111. data/funchook/distorm/examples/java/distorm/src/diStorm3/DecodedResult.java +11 -0
  112. data/funchook/distorm/examples/java/distorm/src/diStorm3/DecomposedInst.java +89 -0
  113. data/funchook/distorm/examples/java/distorm/src/diStorm3/DecomposedResult.java +11 -0
  114. data/funchook/distorm/examples/java/distorm/src/diStorm3/OpcodeEnum.java +131 -0
  115. data/funchook/distorm/examples/java/distorm/src/diStorm3/Opcodes.java +1123 -0
  116. data/funchook/distorm/examples/java/distorm/src/diStorm3/Operand.java +24 -0
  117. data/funchook/distorm/examples/java/distorm/src/diStorm3/distorm3.java +41 -0
  118. data/funchook/distorm/examples/java/jdistorm.c +405 -0
  119. data/funchook/distorm/examples/java/jdistorm.h +40 -0
  120. data/funchook/distorm/examples/java/jdistorm.sln +20 -0
  121. data/funchook/distorm/examples/java/jdistorm.vcproj +208 -0
  122. data/funchook/distorm/examples/linux/Makefile +15 -0
  123. data/funchook/distorm/examples/linux/main.c +181 -0
  124. data/funchook/distorm/examples/tests/Makefile +15 -0
  125. data/funchook/distorm/examples/tests/main.cpp +42 -0
  126. data/funchook/distorm/examples/tests/main.py +66 -0
  127. data/funchook/distorm/examples/tests/test_distorm3.py +1672 -0
  128. data/funchook/distorm/examples/tests/tests.sln +20 -0
  129. data/funchook/distorm/examples/tests/tests.vcxproj +82 -0
  130. data/funchook/distorm/examples/tests/tests.vcxproj.filters +22 -0
  131. data/funchook/distorm/examples/win32/disasm.sln +25 -0
  132. data/funchook/distorm/examples/win32/disasm.vcxproj +201 -0
  133. data/funchook/distorm/examples/win32/disasm.vcxproj.filters +14 -0
  134. data/funchook/distorm/examples/win32/main.cpp +163 -0
  135. data/funchook/distorm/include/distorm.h +482 -0
  136. data/funchook/distorm/include/mnemonics.h +301 -0
  137. data/funchook/distorm/make/linux/Makefile +28 -0
  138. data/funchook/distorm/make/mac/Makefile +24 -0
  139. data/funchook/distorm/make/win32/cdistorm.vcxproj +239 -0
  140. data/funchook/distorm/make/win32/cdistorm.vcxproj.filters +80 -0
  141. data/funchook/distorm/make/win32/distorm.sln +25 -0
  142. data/funchook/distorm/make/win32/resource.h +14 -0
  143. data/funchook/distorm/make/win32/resource.rc +99 -0
  144. data/funchook/distorm/python/distorm3/__init__.py +957 -0
  145. data/funchook/distorm/python/distorm3/sample.py +51 -0
  146. data/funchook/distorm/setup.cfg +10 -0
  147. data/funchook/distorm/setup.py +266 -0
  148. data/funchook/distorm/src/config.h +169 -0
  149. data/funchook/distorm/src/decoder.c +641 -0
  150. data/funchook/distorm/src/decoder.h +33 -0
  151. data/funchook/distorm/src/distorm.c +413 -0
  152. data/funchook/distorm/src/instructions.c +597 -0
  153. data/funchook/distorm/src/instructions.h +463 -0
  154. data/funchook/distorm/src/insts.c +7939 -0
  155. data/funchook/distorm/src/insts.h +64 -0
  156. data/funchook/distorm/src/mnemonics.c +284 -0
  157. data/funchook/distorm/src/operands.c +1290 -0
  158. data/funchook/distorm/src/operands.h +28 -0
  159. data/funchook/distorm/src/prefix.c +368 -0
  160. data/funchook/distorm/src/prefix.h +64 -0
  161. data/funchook/distorm/src/textdefs.c +172 -0
  162. data/funchook/distorm/src/textdefs.h +57 -0
  163. data/funchook/distorm/src/wstring.c +47 -0
  164. data/funchook/distorm/src/wstring.h +35 -0
  165. data/funchook/distorm/src/x86defs.h +82 -0
  166. data/funchook/include/funchook.h +123 -0
  167. data/funchook/install-sh +527 -0
  168. data/funchook/src/Makefile +70 -0
  169. data/funchook/src/Makefile.in +70 -0
  170. data/funchook/src/__strerror.h +109 -0
  171. data/funchook/src/config.h +101 -0
  172. data/funchook/src/config.h.in +100 -0
  173. data/funchook/src/decoder.o +0 -0
  174. data/funchook/src/distorm.o +0 -0
  175. data/funchook/src/funchook.c +440 -0
  176. data/funchook/src/funchook.o +0 -0
  177. data/funchook/src/funchook_internal.h +155 -0
  178. data/funchook/src/funchook_io.c +182 -0
  179. data/funchook/src/funchook_io.h +64 -0
  180. data/funchook/src/funchook_io.o +0 -0
  181. data/funchook/src/funchook_syscall.S +134 -0
  182. data/funchook/src/funchook_syscall.o +0 -0
  183. data/funchook/src/funchook_unix.c +480 -0
  184. data/funchook/src/funchook_unix.o +0 -0
  185. data/funchook/src/funchook_windows.c +397 -0
  186. data/funchook/src/funchook_x86.c +622 -0
  187. data/funchook/src/funchook_x86.o +0 -0
  188. data/funchook/src/instructions.o +0 -0
  189. data/funchook/src/insts.o +0 -0
  190. data/funchook/src/libfunchook.so +0 -0
  191. data/funchook/src/mnemonics.o +0 -0
  192. data/funchook/src/operands.o +0 -0
  193. data/funchook/src/os_func.c +115 -0
  194. data/funchook/src/os_func.h +75 -0
  195. data/funchook/src/os_func.o +0 -0
  196. data/funchook/src/os_func_unix.c +94 -0
  197. data/funchook/src/os_func_unix.o +0 -0
  198. data/funchook/src/os_func_windows.c +32 -0
  199. data/funchook/src/prefix.o +0 -0
  200. data/funchook/src/printf_base.c +1688 -0
  201. data/funchook/src/printf_base.h +46 -0
  202. data/funchook/src/printf_base.o +0 -0
  203. data/funchook/src/textdefs.o +0 -0
  204. data/funchook/src/wstring.o +0 -0
  205. data/funchook/test/Makefile +43 -0
  206. data/funchook/test/Makefile.in +43 -0
  207. data/funchook/test/funchook_test +0 -0
  208. data/funchook/test/libfunchook_test.c +25 -0
  209. data/funchook/test/libfunchook_test.so +0 -0
  210. data/funchook/test/libfunchook_test2.c +18 -0
  211. data/funchook/test/suffix.list +600 -0
  212. data/funchook/test/test_main.c +430 -0
  213. data/funchook/test/test_main.o +0 -0
  214. data/funchook/test/x86_64_test.S +10 -0
  215. data/funchook/test/x86_64_test.o +0 -0
  216. data/funchook/test/x86_test.S +339 -0
  217. data/funchook/win32/config.h +1 -0
  218. data/funchook/win32/funchook.sln +52 -0
  219. data/funchook/win32/funchook.vcxproj +188 -0
  220. data/funchook/win32/funchook.vcxproj.filters +84 -0
  221. data/funchook/win32/funchook_test.vcxproj +170 -0
  222. data/funchook/win32/funchook_test.vcxproj.filters +22 -0
  223. data/funchook/win32/funchook_test_dll.vcxproj +184 -0
  224. data/funchook/win32/funchook_test_dll.vcxproj.filters +30 -0
  225. data/funchook/win32/funchook_test_exe.def +3 -0
  226. data/lib/contrast-agent.rb +8 -0
  227. data/lib/contrast.rb +57 -0
  228. data/lib/contrast/agent.rb +80 -0
  229. data/lib/contrast/agent/assess.rb +45 -0
  230. data/lib/contrast/agent/assess/adjusted_span.rb +25 -0
  231. data/lib/contrast/agent/assess/class_reverter.rb +82 -0
  232. data/lib/contrast/agent/assess/contrast_event.rb +398 -0
  233. data/lib/contrast/agent/assess/frozen_properties.rb +41 -0
  234. data/lib/contrast/agent/assess/insulator.rb +53 -0
  235. data/lib/contrast/agent/assess/policy/dynamic_source_factory.rb +78 -0
  236. data/lib/contrast/agent/assess/policy/patcher.rb +85 -0
  237. data/lib/contrast/agent/assess/policy/policy.rb +116 -0
  238. data/lib/contrast/agent/assess/policy/policy_node.rb +289 -0
  239. data/lib/contrast/agent/assess/policy/policy_scanner.rb +44 -0
  240. data/lib/contrast/agent/assess/policy/preshift.rb +94 -0
  241. data/lib/contrast/agent/assess/policy/propagation_method.rb +260 -0
  242. data/lib/contrast/agent/assess/policy/propagation_node.rb +127 -0
  243. data/lib/contrast/agent/assess/policy/propagator.rb +35 -0
  244. data/lib/contrast/agent/assess/policy/propagator/append.rb +54 -0
  245. data/lib/contrast/agent/assess/policy/propagator/base.rb +37 -0
  246. data/lib/contrast/agent/assess/policy/propagator/center.rb +73 -0
  247. data/lib/contrast/agent/assess/policy/propagator/custom.rb +36 -0
  248. data/lib/contrast/agent/assess/policy/propagator/database_write.rb +62 -0
  249. data/lib/contrast/agent/assess/policy/propagator/insert.rb +55 -0
  250. data/lib/contrast/agent/assess/policy/propagator/keep.rb +26 -0
  251. data/lib/contrast/agent/assess/policy/propagator/next.rb +42 -0
  252. data/lib/contrast/agent/assess/policy/propagator/prepend.rb +50 -0
  253. data/lib/contrast/agent/assess/policy/propagator/remove.rb +76 -0
  254. data/lib/contrast/agent/assess/policy/propagator/replace.rb +27 -0
  255. data/lib/contrast/agent/assess/policy/propagator/reverse.rb +38 -0
  256. data/lib/contrast/agent/assess/policy/propagator/select.rb +86 -0
  257. data/lib/contrast/agent/assess/policy/propagator/splat.rb +60 -0
  258. data/lib/contrast/agent/assess/policy/propagator/split.rb +49 -0
  259. data/lib/contrast/agent/assess/policy/propagator/substitution.rb +169 -0
  260. data/lib/contrast/agent/assess/policy/propagator/trim.rb +81 -0
  261. data/lib/contrast/agent/assess/policy/rewriter_patch.rb +79 -0
  262. data/lib/contrast/agent/assess/policy/source_method.rb +209 -0
  263. data/lib/contrast/agent/assess/policy/source_node.rb +62 -0
  264. data/lib/contrast/agent/assess/policy/trigger_method.rb +209 -0
  265. data/lib/contrast/agent/assess/policy/trigger_node.rb +198 -0
  266. data/lib/contrast/agent/assess/policy/trigger_validation/ssrf_validator.rb +77 -0
  267. data/lib/contrast/agent/assess/policy/trigger_validation/trigger_validation.rb +31 -0
  268. data/lib/contrast/agent/assess/policy/trigger_validation/xss_validator.rb +40 -0
  269. data/lib/contrast/agent/assess/properties.rb +392 -0
  270. data/lib/contrast/agent/assess/rule.rb +18 -0
  271. data/lib/contrast/agent/assess/rule/base.rb +72 -0
  272. data/lib/contrast/agent/assess/rule/csrf.rb +66 -0
  273. data/lib/contrast/agent/assess/rule/csrf/csrf_action.rb +28 -0
  274. data/lib/contrast/agent/assess/rule/csrf/csrf_applicator.rb +69 -0
  275. data/lib/contrast/agent/assess/rule/csrf/csrf_watcher.rb +132 -0
  276. data/lib/contrast/agent/assess/rule/provider.rb +21 -0
  277. data/lib/contrast/agent/assess/rule/provider/hardcoded_key.rb +62 -0
  278. data/lib/contrast/agent/assess/rule/provider/hardcoded_password.rb +73 -0
  279. data/lib/contrast/agent/assess/rule/provider/hardcoded_value_rule.rb +121 -0
  280. data/lib/contrast/agent/assess/rule/redos.rb +68 -0
  281. data/lib/contrast/agent/assess/rule/response_scanning_rule.rb +47 -0
  282. data/lib/contrast/agent/assess/rule/response_watcher.rb +36 -0
  283. data/lib/contrast/agent/assess/rule/watcher.rb +36 -0
  284. data/lib/contrast/agent/assess/tag.rb +151 -0
  285. data/lib/contrast/agent/at_exit_hook.rb +33 -0
  286. data/lib/contrast/agent/class_reopener.rb +195 -0
  287. data/lib/contrast/agent/deadzone/policy/deadzone_node.rb +26 -0
  288. data/lib/contrast/agent/deadzone/policy/policy.rb +57 -0
  289. data/lib/contrast/agent/disable_reaction.rb +24 -0
  290. data/lib/contrast/agent/exclusion_matcher.rb +190 -0
  291. data/lib/contrast/agent/feature_state.rb +379 -0
  292. data/lib/contrast/agent/inventory/policy/policy.rb +32 -0
  293. data/lib/contrast/agent/inventory/policy/trigger_node.rb +22 -0
  294. data/lib/contrast/agent/logger_manager.rb +116 -0
  295. data/lib/contrast/agent/middleware.rb +352 -0
  296. data/lib/contrast/agent/module_data.rb +16 -0
  297. data/lib/contrast/agent/patching/policy/after_load_patch.rb +37 -0
  298. data/lib/contrast/agent/patching/policy/after_load_patcher.rb +58 -0
  299. data/lib/contrast/agent/patching/policy/method_policy.rb +94 -0
  300. data/lib/contrast/agent/patching/policy/module_policy.rb +116 -0
  301. data/lib/contrast/agent/patching/policy/patch.rb +312 -0
  302. data/lib/contrast/agent/patching/policy/patch_status.rb +192 -0
  303. data/lib/contrast/agent/patching/policy/patcher.rb +310 -0
  304. data/lib/contrast/agent/patching/policy/policy.rb +138 -0
  305. data/lib/contrast/agent/patching/policy/policy_node.rb +80 -0
  306. data/lib/contrast/agent/patching/policy/policy_unpatcher.rb +28 -0
  307. data/lib/contrast/agent/patching/policy/trigger_node.rb +81 -0
  308. data/lib/contrast/agent/protect/policy/policy.rb +37 -0
  309. data/lib/contrast/agent/protect/policy/trigger_node.rb +23 -0
  310. data/lib/contrast/agent/protect/rule.rb +58 -0
  311. data/lib/contrast/agent/protect/rule/base.rb +300 -0
  312. data/lib/contrast/agent/protect/rule/base_service.rb +88 -0
  313. data/lib/contrast/agent/protect/rule/cmd_injection.rb +156 -0
  314. data/lib/contrast/agent/protect/rule/csrf.rb +118 -0
  315. data/lib/contrast/agent/protect/rule/csrf/csrf_evaluator.rb +103 -0
  316. data/lib/contrast/agent/protect/rule/csrf/csrf_token_injector.rb +85 -0
  317. data/lib/contrast/agent/protect/rule/default_scanner.rb +300 -0
  318. data/lib/contrast/agent/protect/rule/deserialization.rb +193 -0
  319. data/lib/contrast/agent/protect/rule/http_method_tampering.rb +80 -0
  320. data/lib/contrast/agent/protect/rule/no_sqli.rb +101 -0
  321. data/lib/contrast/agent/protect/rule/no_sqli/mongo_no_sql_scanner.rb +40 -0
  322. data/lib/contrast/agent/protect/rule/path_traversal.rb +143 -0
  323. data/lib/contrast/agent/protect/rule/sqli.rb +101 -0
  324. data/lib/contrast/agent/protect/rule/sqli/default_sql_scanner.rb +16 -0
  325. data/lib/contrast/agent/protect/rule/sqli/mysql_sql_scanner.rb +38 -0
  326. data/lib/contrast/agent/protect/rule/sqli/postgres_sql_scanner.rb +22 -0
  327. data/lib/contrast/agent/protect/rule/sqli/sqlite_sql_scanner.rb +19 -0
  328. data/lib/contrast/agent/protect/rule/unsafe_file_upload.rb +20 -0
  329. data/lib/contrast/agent/protect/rule/xss.rb +24 -0
  330. data/lib/contrast/agent/protect/rule/xxe.rb +120 -0
  331. data/lib/contrast/agent/protect/rule/xxe/entity_wrapper.rb +82 -0
  332. data/lib/contrast/agent/railtie.rb +30 -0
  333. data/lib/contrast/agent/reaction_processor.rb +47 -0
  334. data/lib/contrast/agent/request.rb +493 -0
  335. data/lib/contrast/agent/request_context.rb +225 -0
  336. data/lib/contrast/agent/require_state.rb +61 -0
  337. data/lib/contrast/agent/response.rb +215 -0
  338. data/lib/contrast/agent/rewriter.rb +244 -0
  339. data/lib/contrast/agent/scope.rb +28 -0
  340. data/lib/contrast/agent/service_heartbeat.rb +37 -0
  341. data/lib/contrast/agent/settings_state.rb +148 -0
  342. data/lib/contrast/agent/socket_client.rb +125 -0
  343. data/lib/contrast/agent/thread.rb +26 -0
  344. data/lib/contrast/agent/tracepoint_hook.rb +51 -0
  345. data/lib/contrast/agent/version.rb +8 -0
  346. data/lib/contrast/api.rb +17 -0
  347. data/lib/contrast/api/.gitkeep +0 -0
  348. data/lib/contrast/api/connection_status.rb +49 -0
  349. data/lib/contrast/api/socket.rb +43 -0
  350. data/lib/contrast/api/speedracer.rb +206 -0
  351. data/lib/contrast/api/tcp_socket.rb +31 -0
  352. data/lib/contrast/api/unix_socket.rb +25 -0
  353. data/lib/contrast/common_agent_configuration.rb +86 -0
  354. data/lib/contrast/components/agent.rb +85 -0
  355. data/lib/contrast/components/app_context.rb +188 -0
  356. data/lib/contrast/components/assess.rb +67 -0
  357. data/lib/contrast/components/config.rb +135 -0
  358. data/lib/contrast/components/contrast_service.rb +113 -0
  359. data/lib/contrast/components/heap_dump.rb +34 -0
  360. data/lib/contrast/components/interface.rb +178 -0
  361. data/lib/contrast/components/inventory.rb +23 -0
  362. data/lib/contrast/components/logger.rb +92 -0
  363. data/lib/contrast/components/protect.rb +38 -0
  364. data/lib/contrast/components/sampling.rb +41 -0
  365. data/lib/contrast/components/scope.rb +106 -0
  366. data/lib/contrast/components/settings.rb +140 -0
  367. data/lib/contrast/config.rb +33 -0
  368. data/lib/contrast/config/agent_configuration.rb +24 -0
  369. data/lib/contrast/config/application_configuration.rb +27 -0
  370. data/lib/contrast/config/assess_configuration.rb +22 -0
  371. data/lib/contrast/config/assess_rules_configuration.rb +18 -0
  372. data/lib/contrast/config/base_configuration.rb +105 -0
  373. data/lib/contrast/config/default_value.rb +16 -0
  374. data/lib/contrast/config/exception_configuration.rb +21 -0
  375. data/lib/contrast/config/heap_dump_configuration.rb +23 -0
  376. data/lib/contrast/config/inventory_configuration.rb +20 -0
  377. data/lib/contrast/config/logger_configuration.rb +20 -0
  378. data/lib/contrast/config/protect_configuration.rb +20 -0
  379. data/lib/contrast/config/protect_rule_configuration.rb +37 -0
  380. data/lib/contrast/config/protect_rules_configuration.rb +30 -0
  381. data/lib/contrast/config/root_configuration.rb +26 -0
  382. data/lib/contrast/config/ruby_configuration.rb +39 -0
  383. data/lib/contrast/config/sampling_configuration.rb +22 -0
  384. data/lib/contrast/config/server_configuration.rb +23 -0
  385. data/lib/contrast/config/service_configuration.rb +22 -0
  386. data/lib/contrast/configuration.rb +214 -0
  387. data/lib/contrast/core_extensions/assess.rb +51 -0
  388. data/lib/contrast/core_extensions/assess/array.rb +58 -0
  389. data/lib/contrast/core_extensions/assess/assess_extension.rb +145 -0
  390. data/lib/contrast/core_extensions/assess/basic_object.rb +15 -0
  391. data/lib/contrast/core_extensions/assess/erb.rb +42 -0
  392. data/lib/contrast/core_extensions/assess/exec_trigger.rb +48 -0
  393. data/lib/contrast/core_extensions/assess/fiber.rb +125 -0
  394. data/lib/contrast/core_extensions/assess/hash.rb +22 -0
  395. data/lib/contrast/core_extensions/assess/kernel.rb +95 -0
  396. data/lib/contrast/core_extensions/assess/module.rb +14 -0
  397. data/lib/contrast/core_extensions/assess/regexp.rb +206 -0
  398. data/lib/contrast/core_extensions/assess/string.rb +75 -0
  399. data/lib/contrast/core_extensions/assess/tilt_template_trigger.rb +73 -0
  400. data/lib/contrast/core_extensions/delegator.rb +14 -0
  401. data/lib/contrast/core_extensions/eval_trigger.rb +52 -0
  402. data/lib/contrast/core_extensions/inventory.rb +22 -0
  403. data/lib/contrast/core_extensions/inventory/datastores.rb +37 -0
  404. data/lib/contrast/core_extensions/module.rb +42 -0
  405. data/lib/contrast/core_extensions/object.rb +27 -0
  406. data/lib/contrast/core_extensions/protect.rb +20 -0
  407. data/lib/contrast/core_extensions/protect/applies_command_injection_rule.rb +70 -0
  408. data/lib/contrast/core_extensions/protect/applies_deserialization_rule.rb +58 -0
  409. data/lib/contrast/core_extensions/protect/applies_no_sqli_rule.rb +81 -0
  410. data/lib/contrast/core_extensions/protect/applies_path_traversal_rule.rb +119 -0
  411. data/lib/contrast/core_extensions/protect/applies_sqli_rule.rb +63 -0
  412. data/lib/contrast/core_extensions/protect/applies_xxe_rule.rb +141 -0
  413. data/lib/contrast/core_extensions/protect/kernel.rb +30 -0
  414. data/lib/contrast/core_extensions/protect/psych.rb +7 -0
  415. data/lib/contrast/core_extensions/thread.rb +31 -0
  416. data/lib/contrast/internal_exception.rb +8 -0
  417. data/lib/contrast/rails_extensions/assess/action_controller_inheritance.rb +48 -0
  418. data/lib/contrast/rails_extensions/assess/active_record.rb +32 -0
  419. data/lib/contrast/rails_extensions/assess/active_record_named.rb +61 -0
  420. data/lib/contrast/rails_extensions/assess/configuration.rb +26 -0
  421. data/lib/contrast/rails_extensions/buffer.rb +30 -0
  422. data/lib/contrast/rails_extensions/rack.rb +45 -0
  423. data/lib/contrast/security_exception.rb +14 -0
  424. data/lib/contrast/sinatra_extensions/assess/cookie.rb +26 -0
  425. data/lib/contrast/sinatra_extensions/inventory/sinatra_base.rb +59 -0
  426. data/lib/contrast/tasks/service.rb +95 -0
  427. data/lib/contrast/utils/assess/sampling_util.rb +96 -0
  428. data/lib/contrast/utils/assess/tracking_util.rb +39 -0
  429. data/lib/contrast/utils/boolean_util.rb +33 -0
  430. data/lib/contrast/utils/cache.rb +69 -0
  431. data/lib/contrast/utils/class_util.rb +58 -0
  432. data/lib/contrast/utils/comment_range.rb +19 -0
  433. data/lib/contrast/utils/data_store_util.rb +23 -0
  434. data/lib/contrast/utils/duck_utils.rb +58 -0
  435. data/lib/contrast/utils/env_configuration_item.rb +52 -0
  436. data/lib/contrast/utils/environment_util.rb +152 -0
  437. data/lib/contrast/utils/freeze_util.rb +36 -0
  438. data/lib/contrast/utils/gemfile_reader.rb +191 -0
  439. data/lib/contrast/utils/hash_digest.rb +148 -0
  440. data/lib/contrast/utils/heap_dump_util.rb +113 -0
  441. data/lib/contrast/utils/invalid_configuration_util.rb +88 -0
  442. data/lib/contrast/utils/inventory_util.rb +126 -0
  443. data/lib/contrast/utils/io_util.rb +61 -0
  444. data/lib/contrast/utils/object_share.rb +117 -0
  445. data/lib/contrast/utils/operating_environment.rb +38 -0
  446. data/lib/contrast/utils/os.rb +49 -0
  447. data/lib/contrast/utils/path_util.rb +151 -0
  448. data/lib/contrast/utils/performs_logging.rb +152 -0
  449. data/lib/contrast/utils/preflight_util.rb +13 -0
  450. data/lib/contrast/utils/prevent_serialization.rb +52 -0
  451. data/lib/contrast/utils/rack_assess_session_cookie.rb +104 -0
  452. data/lib/contrast/utils/rails_assess_configuration.rb +95 -0
  453. data/lib/contrast/utils/random_util.rb +22 -0
  454. data/lib/contrast/utils/resource_loader.rb +23 -0
  455. data/lib/contrast/utils/ruby_ast_rewriter.rb +74 -0
  456. data/lib/contrast/utils/scope_util.rb +99 -0
  457. data/lib/contrast/utils/service_response_util.rb +116 -0
  458. data/lib/contrast/utils/service_sender_util.rb +98 -0
  459. data/lib/contrast/utils/sha256_builder.rb +69 -0
  460. data/lib/contrast/utils/sinatra_helper.rb +49 -0
  461. data/lib/contrast/utils/stack_trace_utils.rb +209 -0
  462. data/lib/contrast/utils/string_utils.rb +72 -0
  463. data/lib/contrast/utils/tag_util.rb +139 -0
  464. data/lib/contrast/utils/thread_tracker.rb +54 -0
  465. data/lib/contrast/utils/timer.rb +78 -0
  466. data/resources/assess/policy.json +1673 -0
  467. data/resources/csrf/inject.js +44 -0
  468. data/resources/deadzone/policy.json +55 -0
  469. data/resources/factory-bot-spec/spec_helper.rb +30 -0
  470. data/resources/inventory/policy.json +110 -0
  471. data/resources/protect/policy.json +417 -0
  472. data/resources/rubocops/kernel/catch_cop.rb +37 -0
  473. data/resources/rubocops/kernel/require_cop.rb +37 -0
  474. data/resources/rubocops/kernel/require_relative_cop.rb +33 -0
  475. data/resources/rubocops/module/autoload_cop.rb +37 -0
  476. data/resources/rubocops/module/const_defined_cop.rb +37 -0
  477. data/resources/rubocops/module/const_get_cop.rb +37 -0
  478. data/resources/rubocops/module/const_set_cop.rb +37 -0
  479. data/resources/rubocops/module/constants_cop.rb +37 -0
  480. data/resources/rubocops/module/name_cop.rb +37 -0
  481. data/resources/rubocops/object/class_cop.rb +37 -0
  482. data/resources/rubocops/object/freeze_cop.rb +37 -0
  483. data/resources/rubocops/object/frozen_cop.rb +37 -0
  484. data/resources/rubocops/object/is_a_cop.rb +37 -0
  485. data/resources/rubocops/object/method_cop.rb +37 -0
  486. data/resources/rubocops/object/respond_to_cop.rb +37 -0
  487. data/resources/rubocops/object/singleton_class_cop.rb +37 -0
  488. data/resources/rubocops/regexp/spelling_cop.rb +44 -0
  489. data/resources/rubocops/thread/new_cop.rb +39 -0
  490. data/resources/ruby-spec/ancestors_spec.rb +70 -0
  491. data/resources/ruby-spec/modulo_spec.rb +831 -0
  492. data/resources/ruby-spec/parameters_spec.rb +261 -0
  493. data/resources/ruby-spec/ruby_spec_spec_helper.rb +35 -0
  494. data/resources/test_marker.txt +1 -0
  495. data/ruby-agent.gemspec +129 -0
  496. data/service_executables/.gitkeep +0 -0
  497. data/service_executables/VERSION +1 -0
  498. data/service_executables/linux/contrast-service +0 -0
  499. data/service_executables/mac/contrast-service +0 -0
  500. metadata +945 -0
@@ -0,0 +1,15 @@
1
+ #
2
+ # diStorm (Linux Port) / Demo Application Makefile
3
+ #
4
+
5
+ TARGET = disasm
6
+ CC = gcc
7
+ CFLAGS = -Wall -O2 -I. -o
8
+
9
+ all: disasm
10
+
11
+ disasm:
12
+ ${CC} ${CFLAGS} ${TARGET} main.cpp ../distorm64.a
13
+
14
+ clean:
15
+ /bin/rm -rf *.o ${TARGET}
@@ -0,0 +1,42 @@
1
+ // diStorm64 library sample
2
+ // http://ragestorm.net/distorm/
3
+ // Arkon, Stefan, 2005
4
+
5
+
6
+ #include <stdio.h>
7
+ #include <stdlib.h>
8
+
9
+ #pragma comment(lib, "../../distorm.lib")
10
+
11
+ #include "../../include/distorm.h"
12
+
13
+ // The number of the array of instructions the decoder function will use to return the disassembled instructions.
14
+ // Play with this value for performance...
15
+ #define MAX_INSTRUCTIONS (1000)
16
+
17
+ int main(int argc, char **argv)
18
+ {
19
+ _DecodeResult res;
20
+ _DecodedInst decodedInstructions[1000];
21
+ unsigned int decodedInstructionsCount = 0, i = 0;
22
+ _OffsetType offset = 0;
23
+ unsigned int dver = distorm_version();
24
+ printf("diStorm version: %d.%d.%d\n", (dver >> 16), ((dver) >> 8) & 0xff, dver & 0xff);
25
+
26
+ unsigned char rawData[] = {
27
+
28
+ 0x68, 0, 0, 0, 0,
29
+ 0x9b,
30
+ 0xdf, 0xe0,
31
+ 0x66, 0xa1, 0xcc, 0xb0, 0x97, 0x7c,
32
+ 0xC7, 0xC1, 0x08, 0x00, 0x00, 0x00,
33
+ 0xc7, 0xf8, 0xaa, 0xaa, 0xaa, 0xaa,
34
+ 0x48, 0xC7, 0xC0, 0x00, 0x00, 0x00, 0x00
35
+ } ;
36
+ res = distorm_decode(offset, (const unsigned char*)rawData, sizeof(rawData), Decode64Bits, decodedInstructions, MAX_INSTRUCTIONS, &decodedInstructionsCount);
37
+ for (int i = 0; i < decodedInstructionsCount; i++) {
38
+ printf("%08I64x (%02d) %-24s %s%s%s\r\n", decodedInstructions[i].offset, decodedInstructions[i].size, (char*)decodedInstructions[i].instructionHex.p, (char*)decodedInstructions[i].mnemonic.p, decodedInstructions[i].operands.length != 0 ? " " : "", (char*)decodedInstructions[i].operands.p);
39
+ }
40
+
41
+ return 0;
42
+ }
@@ -0,0 +1,66 @@
1
+ #import distorm
2
+ from pyasm import *
3
+ from distorm3 import *
4
+
5
+ _REGS = ["RAX", "RCX", "RDX", "RBX", "RSP", "RBP", "RSI", "RDI", "R8", "R9", "R10", "R11", "R12", "R13", "R14", "R15",
6
+ "EAX", "ECX", "EDX", "EBX", "ESP", "EBP", "ESI", "EDI", "R8D", "R9D", "R10D", "R11D", "R12D", "R13D", "R14D", "R15D",
7
+ "AX", "CX", "DX", "BX", "SP", "BP", "SI", "DI", "R8W", "R9W", "R10W", "R11W", "R12W", "R13W", "R14W", "R15W",
8
+ "AL", "CL", "DL", "BL", "AH", "CH", "DH", "BH", "R8B", "R9B", "R10B", "R11B", "R12B", "R13B", "R14B", "R15B",
9
+ "SPL", "BPL", "SIL", "DIL",
10
+ "ES", "CS", "SS", "DS", "FS", "GS",
11
+ "RIP",
12
+ "ST0", "ST1", "ST2", "ST3", "ST4", "ST5", "ST6", "ST7",
13
+ "MM0", "MM1", "MM2", "MM3", "MM4", "MM5", "MM6", "MM7",
14
+ "XMM0", "XMM1", "XMM2", "XMM3", "XMM4", "XMM5", "XMM6", "XMM7", "XMM8", "XMM9", "XMM10", "XMM11", "XMM12", "XMM13", "XMM14", "XMM15",
15
+ "YMM0", "YMM1", "YMM2", "YMM3", "YMM4", "YMM5", "YMM6", "YMM7", "YMM8", "YMM9", "YMM10", "YMM11", "YMM12", "YMM13", "YMM14", "YMM15",
16
+ "CR0", "", "CR2", "CR3", "CR4", "", "", "", "CR8",
17
+ "DR0", "DR1", "DR2", "DR3", "", "", "DR6", "DR7"]
18
+
19
+ def decode(x, mode = 1):
20
+ sizes = [16, 32, 64]
21
+ x = Assemble(x, sizes[mode])
22
+ print x.encode('hex')
23
+ #print distorm.Decode(0, x, mode)
24
+ print Decode(0, x, mode)
25
+
26
+ #decode("bswap ecx", 1)
27
+ #distorm3.Decode(0, "480fc3c0".decode('hex'), 2)
28
+
29
+
30
+ def xxx(x):
31
+ buf = "".join(map(lambda txt: Assemble(txt, 32), x.split("\n")))
32
+ print ",0x".join(map(lambda x: "%02x" % ord(x), buf))
33
+ return Decode(0, buf, Decode32Bits)[0]
34
+
35
+ def yyy(inst):
36
+ print "%x (%d): " % (inst["addr"], inst["size"])
37
+ print inst
38
+ ops = filter(lambda x:x is not None, inst["ops"])
39
+ for o in ops:
40
+ if o["type"] == O_REG:
41
+ print _REGS[o["index"]]
42
+ elif o["type"] == O_IMM:
43
+ print hex(inst["imm"])
44
+ elif o["type"] == O_MEM:
45
+ print "[",
46
+ if inst["base"] != R_NONE:
47
+ print _REGS[inst["base"]],
48
+ print "+",
49
+ print _REGS[o["index"]],
50
+ if inst["scale"] != 0:
51
+ print "*%d" % inst["scale"],
52
+ if inst["dispSize"] != 0:
53
+ print " + 0x%x" % (inst["disp"]),
54
+ print "]"
55
+ elif o["type"] == O_SMEM:
56
+ print "[%s" % (_REGS[o["index"]]),
57
+ if inst["dispSize"] != 0:
58
+ print " + 0x%x" % (inst["disp"]),
59
+ print "]"
60
+ elif o["type"] == O_DISP:
61
+ print "[0x%x]" % inst["disp"]
62
+ elif o["type"] == O_PC:
63
+ print hex(inst["imm"])
64
+
65
+ #yyy(Decode(0, "0fae38".decode('hex'), Decode32Bits)[0])
66
+ yyy(xxx("mov eax, [ebp*4]"))
@@ -0,0 +1,1672 @@
1
+ #
2
+ # Gil Dabah 2006, http://ragestorm.net/distorm
3
+ # Tests for diStorm3
4
+ #
5
+ import os
6
+ import distorm3
7
+ from distorm3 import *
8
+
9
+ import struct
10
+ import unittest
11
+ import random
12
+
13
+ REG_NONE = 255
14
+ _REGISTERS = ["RAX", "RCX", "RDX", "RBX", "RSP", "RBP", "RSI", "RDI", "R8", "R9", "R10", "R11", "R12", "R13", "R14", "R15",
15
+ "EAX", "ECX", "EDX", "EBX", "ESP", "EBP", "ESI", "EDI", "R8D", "R9D", "R10D", "R11D", "R12D", "R13D", "R14D", "R15D",
16
+ "AX", "CX", "DX", "BX", "SP", "BP", "SI", "DI", "R8W", "R9W", "R10W", "R11W", "R12W", "R13W", "R14W", "R15W",
17
+ "AL", "CL", "DL", "BL", "AH", "CH", "DH", "BH", "R8B", "R9B", "R10B", "R11B", "R12B", "R13B", "R14B", "R15B",
18
+ "SPL", "BPL", "SIL", "DIL",
19
+ "ES", "CS", "SS", "DS", "FS", "GS",
20
+ "RIP",
21
+ "ST0", "ST1", "ST2", "ST3", "ST4", "ST5", "ST6", "ST7",
22
+ "MM0", "MM1", "MM2", "MM3", "MM4", "MM5", "MM6", "MM7",
23
+ "XMM0", "XMM1", "XMM2", "XMM3", "XMM4", "XMM5", "XMM6", "XMM7", "XMM8", "XMM9", "XMM10", "XMM11", "XMM12", "XMM13", "XMM14", "XMM15",
24
+ "YMM0", "YMM1", "YMM2", "YMM3", "YMM4", "YMM5", "YMM6", "YMM7", "YMM8", "YMM9", "YMM10", "YMM11", "YMM12", "YMM13", "YMM14", "YMM15",
25
+ "CR0", "", "CR2", "CR3", "CR4", "", "", "", "CR8",
26
+ "DR0", "DR1", "DR2", "DR3", "", "", "DR6", "DR7"]
27
+
28
+ class Registers(object):
29
+ def __init__(self):
30
+ for i in enumerate(_REGISTERS):
31
+ if len(i[1]):
32
+ setattr(self, i[1], i[0])
33
+ Regs = Registers()
34
+ fbin = []
35
+
36
+ def Assemble(text, mode):
37
+ lines = text.replace("\n", "\r\n")
38
+ if mode is None:
39
+ mode = 32
40
+ lines = ("bits %d\r\n" % mode) + lines
41
+ open("1.asm", "wb").write(lines)
42
+ if mode == 64:
43
+ mode = "amd64"
44
+ else:
45
+ mode = "x86"
46
+ os.system("yasm.exe -m%s 1.asm" % mode)
47
+ return open("1", "rb").read()
48
+
49
+ class InstBin(unittest.TestCase):
50
+ def __init__(self, bin, mode):
51
+ bin = bin.decode("hex")
52
+ #fbin[mode].write(bin)
53
+ self.insts = Decompose(0, bin, mode)
54
+ self.inst = self.insts[0]
55
+ def check_valid(self, instsNo = 1):
56
+ self.assertNotEqual(self.inst.rawFlags, 65535)
57
+ self.assertEqual(len(self.insts), instsNo)
58
+ def check_invalid(self):
59
+ self.assertEqual(self.inst.rawFlags, 65535)
60
+ def check_mnemonic(self, mnemonic, instNo = 0):
61
+ self.assertNotEqual(self.inst.rawFlags, 65535)
62
+ self.assertEqual(self.insts[instNo].mnemonic, mnemonic)
63
+
64
+ class Inst(unittest.TestCase):
65
+ def __init__(self, instText, mode, instNo, features):
66
+ modeSize = [16, 32, 64][mode]
67
+ bin = Assemble(instText, modeSize)
68
+ #print map(lambda x: hex(ord(x)), bin)
69
+ #fbin[mode].write(bin)
70
+ self.insts = Decompose(0, bin, mode)
71
+ self.inst = self.insts[instNo]
72
+
73
+ def check_mnemonic(self, mnemonic):
74
+ self.assertEqual(self.inst.mnemonic, mnemonic)
75
+
76
+ def check_imm(self, n, val, sz):
77
+ self.assertEqual(self.inst.operands[n].type, distorm3.OPERAND_IMMEDIATE)
78
+ self.assertEqual(self.inst.operands[n].size, sz)
79
+ self.assertEqual(self.inst.operands[n].value, val)
80
+
81
+ def check_reg(self, n, idx, sz):
82
+ self.assertEqual(self.inst.operands[n].type, distorm3.OPERAND_REGISTER)
83
+ self.assertEqual(self.inst.operands[n].size, sz)
84
+ self.assertEqual(self.inst.operands[n].index, idx)
85
+
86
+ def check_pc(self, val, sz):
87
+ self.assertEqual(self.inst.operands[0].type, distorm3.OPERAND_IMMEDIATE)
88
+ self.assertEqual(self.inst.operands[0].size, sz)
89
+ self.assertEqual(self.inst.operands[0].value, val)
90
+
91
+ def check_disp(self, n, val, dispSize, derefSize):
92
+ self.assertEqual(self.inst.operands[n].type, distorm3.OPERAND_MEMORY)
93
+ self.assertEqual(self.inst.operands[n].dispSize, dispSize)
94
+ self.assertEqual(self.inst.operands[n].size, derefSize)
95
+ self.assertEqual(self.inst.operands[n].disp, val)
96
+
97
+ def check_abs_disp(self, n, val, dispSize, derefSize):
98
+ self.assertEqual(self.inst.operands[n].type, distorm3.OPERAND_ABSOLUTE_ADDRESS)
99
+ self.assertEqual(self.inst.operands[n].dispSize, dispSize)
100
+ self.assertEqual(self.inst.operands[n].size, derefSize)
101
+ self.assertEqual(self.inst.operands[n].disp, val)
102
+
103
+ def check_simple_deref(self, n, idx, derefSize):
104
+ """ Checks whether a (simple) memory dereference type is used, size of deref is in ops.size.
105
+ Displacement is ignored in this check. """
106
+ self.assertEqual(self.inst.operands[n].type, distorm3.OPERAND_MEMORY)
107
+ self.assertEqual(self.inst.operands[n].size, derefSize)
108
+ self.assertEqual(self.inst.operands[n].index, idx)
109
+
110
+ def check_deref(self, n, idx, base, derefSize):
111
+ """ Checks whether a memory dereference type is used, size of deref is in ops.size.
112
+ Base registers is in inst.base.
113
+ Displacement is ignored in this check. """
114
+ self.assertEqual(self.inst.operands[n].type, distorm3.OPERAND_MEMORY)
115
+ self.assertEqual(self.inst.operands[n].size, derefSize)
116
+ self.assertEqual(self.inst.operands[n].index, idx)
117
+ self.assertEqual(self.inst.operands[n].base, base)
118
+
119
+ def check_type_size(self, n, t, sz):
120
+ self.assertEqual(self.inst.operands[n].type, t)
121
+ self.assertEqual(self.inst.operands[n].size, sz)
122
+
123
+ def check_addr_size(self, sz):
124
+ self.assertEqual({0: 16, 1: 32, 2: 64}[(self.inst.rawFlags >> 10) & 3], sz)
125
+
126
+ def I16(instText, instNo = 0, features = 0):
127
+ return Inst(instText, Decode16Bits, instNo, features)
128
+
129
+ def I32(instText, features = 0):
130
+ return Inst(instText, Decode32Bits, 0, features)
131
+
132
+ def IB32(bin):
133
+ return InstBin(bin, Decode32Bits)
134
+
135
+ def I64(instText, features = 0):
136
+ return Inst(instText, Decode64Bits, 0, features)
137
+
138
+ def IB64(bin):
139
+ return InstBin(bin, Decode64Bits)
140
+
141
+ def ABS64(x):
142
+ return x
143
+ #return struct.unpack("q", struct.pack("Q", x))[0]
144
+
145
+ class TestMode16(unittest.TestCase):
146
+ Derefs = ["BX + SI", "BX + DI", "BP + SI", "BP + DI", "SI", "DI", "BP", "BX"]
147
+ DerefsInfo = [(Regs.BX, Regs.SI), (Regs.BX, Regs.DI), (Regs.BP, Regs.SI), (Regs.BP, Regs.DI),
148
+ (Regs.SI,), (Regs.DI,), (Regs.BP,), (Regs.BX,)]
149
+ def test_none(self):
150
+ self.failIf(len(I16("cbw").inst.operands) > 0)
151
+ def test_imm8(self):
152
+ I16("int 0x55").check_imm(0, 0x55, 8)
153
+ def test_imm16(self):
154
+ I16("ret 0x1122").check_imm(0, 0x1122, 16)
155
+ def test_imm_full(self):
156
+ I16("push 0x1234").check_imm(0, 0x1234, 16)
157
+ def test_imm_aadm(self):
158
+ I16("aam").check_imm(0, 0xa, 8)
159
+ I16("aam 0x15").check_imm(0, 0x15, 8)
160
+ I16("aad").check_imm(0, 0xa, 8)
161
+ I16("aad 0x51").check_imm(0, 0x51, 8)
162
+ def test_seimm(self):
163
+ I16("push 5").check_imm(0, 0x5, 8)
164
+ a = I16("push -6")
165
+ self.assertEqual(a.inst.size, 2)
166
+ a.check_type_size(0, distorm3.OPERAND_IMMEDIATE, 8)
167
+ self.failIf(ABS64(a.inst.operands[0].value) != -6)
168
+ a = I16("db 0x66\n push -5")
169
+ self.assertEqual(a.inst.size, 3)
170
+ a.check_type_size(0, distorm3.OPERAND_IMMEDIATE, 32)
171
+ self.failIf(ABS64(a.inst.operands[0].value) != -5)
172
+ def test_imm16_1_imm8_2(self):
173
+ a = I16("enter 0x1234, 0x40")
174
+ a.check_imm(0, 0x1234, 16)
175
+ a.check_imm(1, 0x40, 8)
176
+ def test_imm8_1_imm8_2(self):
177
+ a = I16("extrq xmm0, 0x55, 0xff")
178
+ a.check_imm(1, 0x55, 8)
179
+ a.check_imm(2, 0xff, 8)
180
+ def test_reg8(self):
181
+ I16("inc dh").check_reg(0, Regs.DH, 8)
182
+ def test_reg16(self):
183
+ I16("arpl ax, bp").check_reg(1, Regs.BP, 16)
184
+ def test_reg_full(self):
185
+ I16("dec di").check_reg(0, Regs.DI, 16)
186
+ def test_reg32(self):
187
+ I16("movmskps ebx, xmm6").check_reg(0, Regs.EBX, 32)
188
+ def test_reg32_64(self):
189
+ I16("cvttsd2si esp, xmm3").check_reg(0, Regs.ESP, 32)
190
+ def test_freg32_64_rm(self):
191
+ I16("mov cr0, eax").check_reg(1, Regs.EAX, 32)
192
+ def test_rm8(self):
193
+ I16("seto dh").check_reg(0, Regs.DH, 8)
194
+ def test_rm16(self):
195
+ I16("str di").check_reg(0, Regs.DI, 16)
196
+ def test_rm_full(self):
197
+ I16("push bp").check_reg(0, Regs.BP, 16)
198
+ def test_rm32_64(self):
199
+ I16("movd xmm0, ebx").check_reg(1, Regs.EBX, 32)
200
+ def test_fpum16(self):
201
+ I16("fiadd word [bx]").check_simple_deref(0, Regs.BX, 16)
202
+ def test_fpum32(self):
203
+ I16("fisttp dword [si]").check_simple_deref(0, Regs.SI, 32)
204
+ def test_fpum64(self):
205
+ I16("fadd qword [esp]").check_simple_deref(0, Regs.ESP, 64)
206
+ def test_fpum80(self):
207
+ I16("fbld [eax]").check_simple_deref(0, Regs.EAX, 80)
208
+ def test_r32_m8(self):
209
+ I16("pinsrb xmm4, eax, 0x55").check_reg(1, Regs.EAX, 32)
210
+ I16("pinsrb xmm4, [bx], 0x55").check_simple_deref(1, Regs.BX, 8)
211
+ def test_r32_m16(self):
212
+ I16("pinsrw xmm4, edi, 0x55").check_reg(1, Regs.EDI, 32)
213
+ I16("pinsrw xmm1, word [si], 0x55").check_simple_deref(1, Regs.SI, 16)
214
+ def test_r32_64_m8(self):
215
+ I16("pextrb eax, xmm4, 0xaa").check_reg(0, Regs.EAX, 32)
216
+ I16("pextrb [bx], xmm2, 0xaa").check_simple_deref(0, Regs.BX, 8)
217
+ def test_r32_64_m16(self):
218
+ I16("pextrw esp, xmm7, 0x11").check_reg(0, Regs.ESP, 32)
219
+ I16("pextrw [bp], xmm0, 0xbb").check_simple_deref(0, Regs.BP, 16)
220
+ def test_rfull_m16(self):
221
+ I16("smsw ax").check_reg(0, Regs.AX, 16)
222
+ I16("smsw [bx]").check_simple_deref(0, Regs.BX, 16)
223
+ def test_creg(self):
224
+ I16("mov esp, cr3").check_reg(1, Regs.CR3, 32)
225
+ #I16("mov esp, cr8").check_reg(1, Regs.CR8, 32)
226
+ def test_dreg(self):
227
+ I16("mov edi, dr7").check_reg(1, Regs.DR7, 32)
228
+ def test_sreg(self):
229
+ I16("mov ax, ds").check_reg(1, Regs.DS, 16)
230
+ def test_seg(self):
231
+ I16("push fs").check_reg(0, Regs.FS, 16)
232
+ I16("db 0x66\n push es").check_reg(0, Regs.ES, 16)
233
+ def test_acc8(self):
234
+ I16("in al, 0x60").check_reg(0, Regs.AL, 8)
235
+ def test_acc_full(self):
236
+ I16("add ax, 0x100").check_reg(0, Regs.AX, 16)
237
+ def test_acc_full_not64(self):
238
+ I16("out 0x64, ax").check_reg(1, Regs.AX, 16)
239
+ def test_mem16_full(self):
240
+ I16("call far [bp]").check_simple_deref(0, Regs.BP, 16)
241
+ def test_ptr16_full(self):
242
+ a = I16("jmp 0xffff:0x1234").inst
243
+ self.assertEqual(a.size, 5)
244
+ self.assertEqual(a.operands[0].type, distorm3.OPERAND_FAR_MEMORY)
245
+ self.assertEqual(a.operands[0].size, 16)
246
+ self.assertEqual(a.operands[0].seg, 0xffff)
247
+ self.assertEqual(a.operands[0].off, 0x1234)
248
+ def test_mem16_3264(self):
249
+ I16("sgdt [bx]").check_simple_deref(0, Regs.BX, 32)
250
+ def test_relcb(self):
251
+ a = I16("db 0xe9\ndw 0x00")
252
+ a.check_pc(3, 16)
253
+ a = I16("db 0xe2\ndb 0x50")
254
+ a.check_pc(0x52, 8)
255
+ a = I16("db 0xe2\ndb 0xfd")
256
+ a.check_pc(-1, 8)
257
+ a = I16("db 0x67\ndb 0xe2\ndb 0xf0")
258
+ a.check_pc(-0xd, 8)
259
+ def test_relc_full(self):
260
+ a = I16("jmp 0x100")
261
+ self.assertEqual(a.inst.size, 3)
262
+ a.check_type_size(0, distorm3.OPERAND_IMMEDIATE, 16)
263
+ def test_mem(self):
264
+ I16("lea ax, [bx]").check_simple_deref(1, Regs.BX, 0)
265
+ def test_mem32(self):
266
+ I16("movntss [ebx], xmm5").check_simple_deref(0, Regs.EBX, 32)
267
+ def test_mem32_64(self):
268
+ I16("movnti [ebx], eax").check_simple_deref(0, Regs.EBX, 32)
269
+ def test_mem64(self):
270
+ I16("movlps [edi], xmm7").check_simple_deref(0, Regs.EDI, 64)
271
+ def test_mem128(self):
272
+ I16("movntps [eax], xmm3").check_simple_deref(0, Regs.EAX, 128)
273
+ def test_mem64_128(self):
274
+ I16("cmpxchg8b [edx]").check_simple_deref(0, Regs.EDX, 64)
275
+ def test_moffs8(self):
276
+ I16("mov al, [0x1234]").check_abs_disp(1, 0x1234, 16, 8)
277
+ I16("mov [dword 0x11112222], al").check_abs_disp(0, 0x11112222, 32, 8)
278
+ def test_moff_full(self):
279
+ I16("mov [0x8765], ax").check_abs_disp(0, 0x8765, 16, 16)
280
+ I16("mov ax, [dword 0x11112222]").check_abs_disp(1, 0x11112222, 32, 16)
281
+ def test_const1(self):
282
+ I16("shl si, 1").check_imm(1, 1, 8)
283
+ def test_regcl(self):
284
+ I16("rcl bp, cl").check_reg(1, Regs.CL, 8)
285
+ def test_ib_rb(self):
286
+ I16("mov dl, 0x88").check_reg(0, Regs.DL, 8)
287
+ def test_ib_r_dw_qw(self):
288
+ I16("bswap ecx").check_reg(0, Regs.ECX, 32)
289
+ def test_ib_r_full(self):
290
+ I16("inc si").check_reg(0, Regs.SI, 16)
291
+ def test_regi_esi(self):
292
+ I16("lodsb").check_simple_deref(1, Regs.SI, 8)
293
+ I16("cmpsw").check_simple_deref(0, Regs.SI, 16)
294
+ I16("lodsd").check_simple_deref(1, Regs.SI, 32)
295
+ def test_regi_edi(self):
296
+ I16("movsb").check_simple_deref(0, Regs.DI, 8)
297
+ I16("scasw").check_simple_deref(0, Regs.DI, 16)
298
+ I16("stosd").check_simple_deref(0, Regs.DI, 32)
299
+ def test_regi_ebxal(self):
300
+ a = I16("xlatb")
301
+ a.check_type_size(0, distorm3.OPERAND_MEMORY, 8)
302
+ self.failIf(a.inst.operands[0].index != Regs.AL)
303
+ self.failIf(a.inst.operands[0].base != Regs.BX)
304
+ def test_regi_eax(self):
305
+ I16("vmrun [ax]").check_simple_deref(0, Regs.AX, 16)
306
+ def test_regdx(self):
307
+ I16("in ax, dx").check_reg(1, Regs.DX, 16)
308
+ def test_regecx(self):
309
+ I16("invlpga [eax], ecx").check_reg(1, Regs.ECX, 32)
310
+ def test_fpu_si(self):
311
+ I16("fxch st4").check_reg(0, Regs.ST4, 32)
312
+ def test_fpu_ssi(self):
313
+ a = I16("fcmovnbe st0, st3")
314
+ a.check_reg(0, Regs.ST0, 32)
315
+ a.check_reg(1, Regs.ST3, 32)
316
+ def test_fpu_sis(self):
317
+ a = I16("fadd st3, st0")
318
+ a.check_reg(0, Regs.ST3, 32)
319
+ a.check_reg(1, Regs.ST0, 32)
320
+ def test_mm(self):
321
+ I16("pand mm0, mm7").check_reg(0, Regs.MM0, 64)
322
+ def test_mm_rm(self):
323
+ I16("psllw mm0, 0x55").check_reg(0, Regs.MM0, 64)
324
+ def test_mm32(self):
325
+ I16("punpcklbw mm1, [si]").check_simple_deref(1, Regs.SI, 32)
326
+ def test_mm64(self):
327
+ I16("packsswb mm3, [bx]").check_simple_deref(1, Regs.BX, 64)
328
+ def test_xmm(self):
329
+ I16("orps xmm5, xmm4").check_reg(0, Regs.XMM5, 128)
330
+ def test_xmm_rm(self):
331
+ I16("psrlw xmm6, 0x12").check_reg(0, Regs.XMM6, 128)
332
+ def test_xmm16(self):
333
+ I16("pmovsxbq xmm3, [bp]").check_simple_deref(1, Regs.BP, 16)
334
+ def test_xmm32(self):
335
+ I16("pmovsxwq xmm5, [di]").check_simple_deref(1, Regs.DI, 32)
336
+ def test_xmm64(self):
337
+ I16("roundsd xmm6, [si], 0x55").check_simple_deref(1, Regs.SI, 64)
338
+ def test_xmm128(self):
339
+ I16("roundpd xmm7, [bx], 0xaa").check_simple_deref(1, Regs.BX, 128)
340
+ def test_regxmm0(self):
341
+ I16("blendvpd xmm1, xmm3, xmm0").check_reg(2, Regs.XMM0, 128)
342
+ def test_disp_only(self):
343
+ a = I16("add [0x1234], bx")
344
+ a.check_type_size(0, distorm3.OPERAND_ABSOLUTE_ADDRESS, 16)
345
+ self.failIf(a.inst.operands[0].dispSize != 16)
346
+ self.failIf(a.inst.operands[0].disp != 0x1234)
347
+ def test_modrm(self):
348
+ texts = ["ADD [%s], AX" % i for i in self.Derefs]
349
+ for i in enumerate(texts):
350
+ a = I16(i[1])
351
+ if len(self.DerefsInfo[i[0]]) == 2:
352
+ a.check_deref(0, self.DerefsInfo[i[0]][1], self.DerefsInfo[i[0]][0], 16)
353
+ else:
354
+ a.check_simple_deref(0, self.DerefsInfo[i[0]][0], 16)
355
+ def test_modrm_disp8(self):
356
+ texts = ["ADD [%s + 0x55], AX" % i for i in self.Derefs]
357
+ for i in enumerate(texts):
358
+ a = I16(i[1])
359
+ if len(self.DerefsInfo[i[0]]) == 2:
360
+ a.check_deref(0, self.DerefsInfo[i[0]][1], self.DerefsInfo[i[0]][0], 16)
361
+ else:
362
+ a.check_simple_deref(0, self.DerefsInfo[i[0]][0], 16)
363
+ self.failIf(a.inst.operands[0].dispSize != 8)
364
+ self.failIf(a.inst.operands[0].disp != 0x55)
365
+ def test_modrm_disp16(self):
366
+ texts = ["ADD [%s + 0x3322], AX" % i for i in self.Derefs]
367
+ for i in enumerate(texts):
368
+ a = I16(i[1])
369
+ if len(self.DerefsInfo[i[0]]) == 2:
370
+ a.check_deref(0, self.DerefsInfo[i[0]][1], self.DerefsInfo[i[0]][0], 16)
371
+ else:
372
+ a.check_simple_deref(0, self.DerefsInfo[i[0]][0], 16)
373
+ self.failIf(a.inst.operands[0].dispSize != 16)
374
+ self.failIf(a.inst.operands[0].disp != 0x3322)
375
+
376
+ class TestMode32(unittest.TestCase):
377
+ Derefs = ["EAX", "ECX", "EDX", "EBX", "EBP", "ESI", "EDI"]
378
+ DerefsInfo = [Regs.EAX, Regs.ECX, Regs.EDX, Regs.EBX, Regs.EBP, Regs.ESI, Regs.EDI]
379
+ def test_none(self):
380
+ self.failIf(len(I32("cdq").inst.operands) > 0)
381
+ def test_imm8(self):
382
+ I32("int 0x55").check_imm(0, 0x55, 8)
383
+ def test_imm16(self):
384
+ I32("ret 0x1122").check_imm(0, 0x1122, 16)
385
+ def test_imm_full(self):
386
+ I32("push 0x12345678").check_imm(0, 0x12345678, 32)
387
+ def test_imm_aadm(self):
388
+ I32("aam").check_imm(0, 0xa, 8)
389
+ I32("aam 0x15").check_imm(0, 0x15, 8)
390
+ I32("aad").check_imm(0, 0xa, 8)
391
+ I32("aad 0x51").check_imm(0, 0x51, 8)
392
+ def test_seimm(self):
393
+ I32("push 6").check_imm(0, 0x6, 8)
394
+ a = I32("push -7")
395
+ self.assertEqual(a.inst.size, 2)
396
+ a.check_type_size(0, distorm3.OPERAND_IMMEDIATE, 8)
397
+ self.failIf(ABS64(a.inst.operands[0].value) != -7)
398
+ a = I32("db 0x66\n push -5")
399
+ self.assertEqual(a.inst.size, 3)
400
+ a.check_type_size(0, distorm3.OPERAND_IMMEDIATE, 16)
401
+ self.failIf(ABS64(a.inst.operands[0].value) != -5)
402
+ def test_imm16_1_imm8_2(self):
403
+ a = I32("enter 0x1234, 0x40")
404
+ a.check_imm(0, 0x1234, 16)
405
+ a.check_imm(1, 0x40, 8)
406
+ def test_imm8_1_imm8_2(self):
407
+ a = I32("extrq xmm0, 0x55, 0xff")
408
+ a.check_imm(1, 0x55, 8)
409
+ a.check_imm(2, 0xff, 8)
410
+ def test_reg8(self):
411
+ I32("inc dh").check_reg(0, Regs.DH, 8)
412
+ def test_reg16(self):
413
+ I32("arpl ax, bp").check_reg(1, Regs.BP, 16)
414
+ def test_reg_full(self):
415
+ I32("dec edi").check_reg(0, Regs.EDI, 32)
416
+ def test_reg32(self):
417
+ I32("movmskps ebx, xmm6").check_reg(0, Regs.EBX, 32)
418
+ def test_reg32_64(self):
419
+ I32("cvttsd2si esp, xmm3").check_reg(0, Regs.ESP, 32)
420
+ def test_freg32_64_rm(self):
421
+ I32("mov cr0, eax").check_reg(1, Regs.EAX, 32)
422
+ def test_rm8(self):
423
+ I32("seto dh").check_reg(0, Regs.DH, 8)
424
+ def test_rm16(self):
425
+ I32("verr di").check_reg(0, Regs.DI, 16)
426
+ def test_rm_full(self):
427
+ I32("push ebp").check_reg(0, Regs.EBP, 32)
428
+ def test_rm32_64(self):
429
+ I32("movd xmm0, ebx").check_reg(1, Regs.EBX, 32)
430
+ def test_fpum16(self):
431
+ I32("fiadd word [ebx]").check_simple_deref(0, Regs.EBX, 16)
432
+ def test_fpum32(self):
433
+ I32("fisttp dword [esi]").check_simple_deref(0, Regs.ESI, 32)
434
+ def test_fpum64(self):
435
+ I32("fadd qword [esp]").check_simple_deref(0, Regs.ESP, 64)
436
+ def test_fpum80(self):
437
+ I32("fbld [eax]").check_simple_deref(0, Regs.EAX, 80)
438
+ def test_r32_m8(self):
439
+ I32("pinsrb xmm4, eax, 0x55").check_reg(1, Regs.EAX, 32)
440
+ I32("pinsrb xmm4, [ebx], 0x55").check_simple_deref(1, Regs.EBX, 8)
441
+ def test_r32_m16(self):
442
+ I32("pinsrw xmm4, edi, 0x55").check_reg(1, Regs.EDI, 32)
443
+ I32("pinsrw xmm1, word [esi], 0x55").check_simple_deref(1, Regs.ESI, 16)
444
+ def test_r32_64_m8(self):
445
+ I32("pextrb eax, xmm4, 0xaa").check_reg(0, Regs.EAX, 32)
446
+ I32("pextrb [ebx], xmm2, 0xaa").check_simple_deref(0, Regs.EBX, 8)
447
+ def test_r32_64_m16(self):
448
+ I32("pextrw esp, xmm7, 0x11").check_reg(0, Regs.ESP, 32)
449
+ I32("pextrw [ebp], xmm0, 0xbb").check_simple_deref(0, Regs.EBP, 16)
450
+ def test_rfull_m16(self):
451
+ I32("smsw eax").check_reg(0, Regs.EAX, 32)
452
+ I32("smsw [ebx]").check_simple_deref(0, Regs.EBX, 16)
453
+ def test_creg(self):
454
+ I32("mov esp, cr3").check_reg(1, Regs.CR3, 32)
455
+ def test_dreg(self):
456
+ I32("mov edi, dr7").check_reg(1, Regs.DR7, 32)
457
+ def test_sreg(self):
458
+ I32("mov ax, ds").check_reg(1, Regs.DS, 16)
459
+ def test_seg(self):
460
+ I32("push ss").check_reg(0, Regs.SS, 16)
461
+ I32("db 0x66\n push ds").check_reg(0, Regs.DS, 16)
462
+ def test_acc8(self):
463
+ I32("in al, 0x60").check_reg(0, Regs.AL, 8)
464
+ def test_acc_full(self):
465
+ I32("add eax, 0x100").check_reg(0, Regs.EAX, 32)
466
+ def test_acc_full_not64(self):
467
+ I32("out 0x64, eax").check_reg(1, Regs.EAX, 32)
468
+ def test_mem16_full(self):
469
+ I32("call far [ebp]").check_simple_deref(0, Regs.EBP, 32)
470
+ def test_ptr16_full(self):
471
+ a = I32("jmp 0xffff:0x12345678").inst
472
+ self.assertEqual(a.size, 7)
473
+ self.assertEqual(a.operands[0].type, distorm3.OPERAND_FAR_MEMORY)
474
+ self.assertEqual(a.operands[0].size, 32)
475
+ self.assertEqual(a.operands[0].seg, 0xffff)
476
+ self.assertEqual(a.operands[0].off, 0x12345678)
477
+ def test_mem16_3264(self):
478
+ I32("sgdt [ebx]").check_simple_deref(0, Regs.EBX, 32)
479
+ def test_relcb(self):
480
+ a = I32("db 0xe9\ndd 0x00")
481
+ a.check_pc(5, 32)
482
+ a = I32("db 0xe2\ndb 0x50")
483
+ a.check_pc(0x52, 8)
484
+ a = I32("db 0xe2\ndb 0xfd")
485
+ a.check_pc(-1, 8)
486
+ a = I32("db 0x67\ndb 0xe2\ndb 0xf0")
487
+ a.check_pc(-0xd, 8)
488
+ def test_relc_full(self):
489
+ a = I32("jmp 0x100")
490
+ self.assertEqual(a.inst.size, 5)
491
+ a.check_type_size(0, distorm3.OPERAND_IMMEDIATE, 32)
492
+ def test_mem(self):
493
+ I32("lea ax, [ebx]").check_simple_deref(1, Regs.EBX, 0)
494
+ def test_mem32(self):
495
+ I32("movntss [ebx], xmm5").check_simple_deref(0, Regs.EBX, 32)
496
+ def test_mem32_64(self):
497
+ I32("movnti [edi], eax").check_simple_deref(0, Regs.EDI, 32)
498
+ def test_mem64(self):
499
+ I32("movlps [edi], xmm7").check_simple_deref(0, Regs.EDI, 64)
500
+ def test_mem128(self):
501
+ I32("movntps [eax], xmm3").check_simple_deref(0, Regs.EAX, 128)
502
+ def test_mem64_128(self):
503
+ I32("cmpxchg8b [edx]").check_simple_deref(0, Regs.EDX, 64)
504
+ def test_moffs8(self):
505
+ I32("mov al, [word 0x5678]").check_abs_disp(1, 0x5678, 16, 8)
506
+ I32("mov [0x11112222], al").check_abs_disp(0, 0x11112222, 32, 8)
507
+ def test_moff_full(self):
508
+ I32("mov [word 0x4321], eax").check_abs_disp(0, 0x4321, 16, 32)
509
+ I32("mov eax, [0x11112222]").check_abs_disp(1, 0x11112222, 32, 32)
510
+ def test_const1(self):
511
+ I32("shl esi, 1").check_imm(1, 1, 8)
512
+ def test_regcl(self):
513
+ I32("rcl ebp, cl").check_reg(1, Regs.CL, 8)
514
+ def test_ib_rb(self):
515
+ I32("mov dl, 0x88").check_reg(0, Regs.DL, 8)
516
+ def test_ib_r_dw_qw(self):
517
+ I32("bswap ecx").check_reg(0, Regs.ECX, 32)
518
+ def test_ib_r_full(self):
519
+ I32("inc esi").check_reg(0, Regs.ESI, 32)
520
+ def test_regi_esi(self):
521
+ I32("lodsb").check_simple_deref(1, Regs.ESI, 8)
522
+ I32("cmpsw").check_simple_deref(0, Regs.ESI, 16)
523
+ I32("lodsd").check_simple_deref(1, Regs.ESI, 32)
524
+ def test_regi_edi(self):
525
+ I32("movsb").check_simple_deref(0, Regs.EDI, 8)
526
+ I32("scasw").check_simple_deref(0, Regs.EDI, 16)
527
+ I32("stosd").check_simple_deref(0, Regs.EDI, 32)
528
+ def test_regi_ebxal(self):
529
+ a = I32("xlatb")
530
+ a.check_type_size(0, distorm3.OPERAND_MEMORY, 8)
531
+ self.failIf(a.inst.operands[0].index != Regs.AL)
532
+ self.failIf(a.inst.operands[0].base != Regs.EBX)
533
+ def test_regi_eax(self):
534
+ I32("vmrun [eax]").check_simple_deref(0, Regs.EAX, 32)
535
+ def test_regdx(self):
536
+ I32("in eax, dx").check_reg(1, Regs.DX, 16)
537
+ def test_regecx(self):
538
+ I32("invlpga [eax], ecx").check_reg(1, Regs.ECX, 32)
539
+ def test_fpu_si(self):
540
+ I32("fxch st4").check_reg(0, Regs.ST4, 32)
541
+ def test_fpu_ssi(self):
542
+ a = I32("fcmovnbe st0, st3")
543
+ a.check_reg(0, Regs.ST0, 32)
544
+ a.check_reg(1, Regs.ST3, 32)
545
+ def test_fpu_sis(self):
546
+ a = I32("fadd st3, st0")
547
+ a.check_reg(0, Regs.ST3, 32)
548
+ a.check_reg(1, Regs.ST0, 32)
549
+ def test_mm(self):
550
+ I32("pand mm0, mm7").check_reg(0, Regs.MM0, 64)
551
+ def test_mm_rm(self):
552
+ I32("psllw mm0, 0x55").check_reg(0, Regs.MM0, 64)
553
+ def test_mm32(self):
554
+ I32("punpcklbw mm1, [esi]").check_simple_deref(1, Regs.ESI, 32)
555
+ def test_mm64(self):
556
+ I32("packsswb mm3, [ebx]").check_simple_deref(1, Regs.EBX, 64)
557
+ def test_xmm(self):
558
+ I32("orps xmm5, xmm4").check_reg(0, Regs.XMM5, 128)
559
+ def test_xmm_rm(self):
560
+ I32("psrlw xmm6, 0x12").check_reg(0, Regs.XMM6, 128)
561
+ def test_xmm16(self):
562
+ I32("pmovsxbq xmm3, [ebp]").check_simple_deref(1, Regs.EBP, 16)
563
+ def test_xmm32(self):
564
+ I32("pmovsxwq xmm5, [edi]").check_simple_deref(1, Regs.EDI, 32)
565
+ def test_xmm64(self):
566
+ I32("roundsd xmm6, [esi], 0x55").check_simple_deref(1, Regs.ESI, 64)
567
+ def test_xmm128(self):
568
+ I32("roundpd xmm7, [ebx], 0xaa").check_simple_deref(1, Regs.EBX, 128)
569
+ def test_regxmm0(self):
570
+ I32("blendvpd xmm1, xmm3, xmm0").check_reg(2, Regs.XMM0, 128)
571
+ def test_cr8(self):
572
+ I32("db 0xf0\n mov cr0, eax").check_reg(0, Regs.CR8, 32)
573
+ def test_disp_only(self):
574
+ a = I32("add [0x12345678], ebx")
575
+ a.check_type_size(0, distorm3.OPERAND_ABSOLUTE_ADDRESS, 32)
576
+ self.failIf(a.inst.operands[0].dispSize != 32)
577
+ self.failIf(a.inst.operands[0].disp != 0x12345678)
578
+ def test_modrm(self):
579
+ texts = ["ADD [%s], EDI" % i for i in self.Derefs]
580
+ for i in enumerate(texts):
581
+ a = I32(i[1])
582
+ a.check_simple_deref(0, self.DerefsInfo[i[0]], 32)
583
+ def test_modrm_disp8(self):
584
+ texts = ["ADD [%s + 0x55], ESI" % i for i in self.Derefs]
585
+ for i in enumerate(texts):
586
+ a = I32(i[1])
587
+ a.check_simple_deref(0, self.DerefsInfo[i[0]], 32)
588
+ self.failIf(a.inst.operands[0].dispSize != 8)
589
+ self.failIf(a.inst.operands[0].disp != 0x55)
590
+ def test_modrm_disp32(self):
591
+ texts = ["ADD [%s + 0x33221144], EDX" % i for i in self.Derefs]
592
+ for i in enumerate(texts):
593
+ a = I32(i[1])
594
+ a.check_simple_deref(0, self.DerefsInfo[i[0]], 32)
595
+ self.failIf(a.inst.operands[0].dispSize != 32)
596
+ self.failIf(a.inst.operands[0].disp != 0x33221144)
597
+ def test_base_ebp(self):
598
+ a = I32("mov [ebp+0x55], eax")
599
+ a.check_simple_deref(0, Regs.EBP, 32)
600
+ self.failIf(a.inst.operands[0].dispSize != 8)
601
+ self.failIf(a.inst.operands[0].disp != 0x55)
602
+ a = I32("mov [ebp+0x55+eax], eax")
603
+ a.check_deref(0, Regs.EAX, Regs.EBP, 32)
604
+ self.failIf(a.inst.operands[0].dispSize != 8)
605
+ self.failIf(a.inst.operands[0].disp != 0x55)
606
+ a = I32("mov [ebp+0x55443322], eax")
607
+ a.check_simple_deref(0, Regs.EBP, 32)
608
+ self.failIf(a.inst.operands[0].dispSize != 32)
609
+ self.failIf(a.inst.operands[0].disp != 0x55443322)
610
+ Bases = ["EAX", "ECX", "EDX", "EBX", "ESP", "ESI", "EDI"]
611
+ BasesInfo = [Regs.EAX, Regs.ECX, Regs.EDX, Regs.EBX, Regs.ESP, Regs.ESI, Regs.EDI]
612
+ Indices = ["EAX", "ECX", "EDX", "EBX", "EBP", "ESI", "EDI"]
613
+ IndicesInfo = [Regs.EAX, Regs.ECX, Regs.EDX, Regs.EBX, Regs.EBP, Regs.ESI, Regs.EDI]
614
+ def test_bases(self):
615
+ for i in enumerate(self.Bases):
616
+ a = I32("cmp ebp, [%s]" % (i[1]))
617
+ a.check_simple_deref(1, self.BasesInfo[i[0]], 32)
618
+ def test_bases_disp32(self):
619
+ for i in enumerate(self.Bases):
620
+ a = I32("cmp ebp, [%s+0x12345678]" % (i[1]))
621
+ a.check_simple_deref(1, self.BasesInfo[i[0]], 32)
622
+ self.failIf(a.inst.operands[1].dispSize != 32)
623
+ self.failIf(a.inst.operands[1].disp != 0x12345678)
624
+ def test_scales(self):
625
+ for i in enumerate(self.Indices):
626
+ # A scale of 2 causes the scale to be omitted and changed from reg*2 to reg+reg.
627
+ for s in [4, 8]:
628
+ a = I32("and bp, [%s*%d]" % (i[1], s))
629
+ a.check_deref(1, self.IndicesInfo[i[0]], None, 16)
630
+ self.failIf(a.inst.operands[1].scale != s)
631
+ def test_sib(self):
632
+ for i in enumerate(self.Indices):
633
+ for j in enumerate(self.Bases):
634
+ for s in [1, 2, 4, 8]:
635
+ a = I32("or bp, [%s*%d + %s]" % (i[1], s, j[1]))
636
+ a.check_deref(1, self.IndicesInfo[i[0]], self.BasesInfo[j[0]], 16)
637
+ if s != 1:
638
+ self.failIf(a.inst.operands[1].scale != s)
639
+ def test_sib_disp8(self):
640
+ for i in enumerate(self.Indices):
641
+ for j in enumerate(self.Bases):
642
+ for s in [1, 2, 4, 8]:
643
+ a = I32("xor al, [%s*%d + %s + 0x55]" % (i[1], s, j[1]))
644
+ a.check_deref(1, self.IndicesInfo[i[0]], self.BasesInfo[j[0]], 8)
645
+ self.failIf(a.inst.operands[1].dispSize != 8)
646
+ self.failIf(a.inst.operands[1].disp != 0x55)
647
+ if s != 1:
648
+ self.failIf(a.inst.operands[1].scale != s)
649
+ def test_sib_disp32(self):
650
+ for i in enumerate(self.Indices):
651
+ for j in enumerate(self.Bases):
652
+ for s in [1, 2, 4, 8]:
653
+ a = I32("sub ebp, [%s*%d + %s + 0x55aabbcc]" % (i[1], s, j[1]))
654
+ a.check_deref(1, self.IndicesInfo[i[0]], self.BasesInfo[j[0]], 32)
655
+ self.failIf(a.inst.operands[1].dispSize != 32)
656
+ self.failIf(a.inst.operands[1].disp != 0x55aabbcc)
657
+ if s != 1:
658
+ self.failIf(a.inst.operands[1].scale != s)
659
+
660
+ class TestMode64(unittest.TestCase):
661
+ Derefs = ["RAX", "RCX", "RDX", "RBX", "RBP", "RSI", "RDI"]
662
+ DerefsInfo = [Regs.RAX, Regs.RCX, Regs.RDX, Regs.RBX, Regs.RBP, Regs.RSI, Regs.RDI]
663
+ def test_none(self):
664
+ self.failIf(len(I64("cdq").inst.operands) > 0)
665
+ def test_imm8(self):
666
+ I64("int 0x55").check_imm(0, 0x55, 8)
667
+ def test_imm16(self):
668
+ I64("ret 0x1122").check_imm(0, 0x1122, 16)
669
+ def test_imm_full(self):
670
+ I64("push 0x12345678").check_imm(0, 0x12345678, 32)
671
+ I64("mov rax, 0x1234567812345678").check_imm(1, 0x1234567812345678, 64)
672
+ def test_imm_aadm(self):
673
+ #I64("aam").check_imm(0, 0xa, 8)
674
+ #I64("aam 0x15").check_imm(0, 0x15, 8)
675
+ #I64("aad").check_imm(0, 0xa, 8)
676
+ #I64("aad 0x51").check_imm(0, 0x51, 8)
677
+ pass
678
+ def test_seimm(self):
679
+ I64("push 6").check_imm(0, 0x6, 8)
680
+ a = I64("push -7")
681
+ self.assertEqual(a.inst.size, 2)
682
+ a.check_type_size(0, distorm3.OPERAND_IMMEDIATE, 8)
683
+ self.failIf(ABS64(a.inst.operands[0].value) != -7)
684
+ def test_imm16_1_imm8_2(self):
685
+ a = I64("enter 0x1234, 0x40")
686
+ a.check_imm(0, 0x1234, 16)
687
+ a.check_imm(1, 0x40, 8)
688
+ def test_imm8_1_imm8_2(self):
689
+ a = I64("extrq xmm0, 0x55, 0xff")
690
+ a.check_imm(1, 0x55, 8)
691
+ a.check_imm(2, 0xff, 8)
692
+ def test_reg8(self):
693
+ I64("inc dh").check_reg(0, Regs.DH, 8)
694
+ def test_reg_full(self):
695
+ I64("dec rdi").check_reg(0, Regs.RDI, 64)
696
+ I64("cmp r15, r14").check_reg(0, Regs.R15, 64)
697
+ I64("cmp r8d, r9d").check_reg(0, Regs.R8D, 32)
698
+ I64("cmp r9w, r8w").check_reg(0, Regs.R9W, 16)
699
+ def test_reg32(self):
700
+ I64("movmskps ebx, xmm6").check_reg(0, Regs.EBX, 32)
701
+ I64("movmskps r11d, xmm6").check_reg(0, Regs.R11D, 32)
702
+ def test_reg32_64(self):
703
+ I64("cvttsd2si rsp, xmm3").check_reg(0, Regs.RSP, 64)
704
+ I64("cvttsd2si r14, xmm3").check_reg(0, Regs.R14, 64)
705
+ def test_freg32_64_rm(self):
706
+ I64("mov cr0, rax").check_reg(1, Regs.RAX, 64)
707
+ I64("mov cr0, r14").check_reg(1, Regs.R14, 64)
708
+ def test_rm8(self):
709
+ I64("seto dh").check_reg(0, Regs.DH, 8)
710
+ def test_rm16(self):
711
+ I64("verr di").check_reg(0, Regs.DI, 16)
712
+ I64("verr r8w").check_reg(0, Regs.R8W, 16)
713
+ def test_rm_full(self):
714
+ I64("push rbp").check_reg(0, Regs.RBP, 64)
715
+ def test_rm32_64(self):
716
+ I64("movq xmm0, rdx").check_reg(1, Regs.RDX, 64)
717
+ I64("movq xmm0, r10").check_reg(1, Regs.R10, 64)
718
+ I64("cvtsi2sd xmm0, rdx").check_reg(1, Regs.RDX, 64)
719
+ I64("vmread rax, rax").check_reg(1, Regs.RAX, 64)
720
+ def test_rm16_32(self):
721
+ I64("movsxd rax, eax").check_reg(1, Regs.EAX, 32)
722
+ I64("movzx rax, ax").check_reg(1, Regs.AX, 16)
723
+ def test_fpum16(self):
724
+ I64("fiadd word [rbx]").check_simple_deref(0, Regs.RBX, 16)
725
+ def test_fpum32(self):
726
+ I64("fisttp dword [rsi]").check_simple_deref(0, Regs.RSI, 32)
727
+ def test_fpum64(self):
728
+ I64("fadd qword [rsp]").check_simple_deref(0, Regs.RSP, 64)
729
+ def test_fpum80(self):
730
+ I64("fbld [rax]").check_simple_deref(0, Regs.RAX, 80)
731
+ def test_r32_m8(self):
732
+ I64("pinsrb xmm4, eax, 0x55").check_reg(1, Regs.EAX, 32)
733
+ I64("pinsrb xmm4, [rbx], 0x55").check_simple_deref(1, Regs.RBX, 8)
734
+ def test_r32_m16(self):
735
+ I64("pinsrw xmm4, edi, 0x55").check_reg(1, Regs.EDI, 32)
736
+ I64("pinsrw xmm1, word [rsi], 0x55").check_simple_deref(1, Regs.RSI, 16)
737
+ I64("pinsrw xmm1, r8d, 0x55").check_reg(1, Regs.R8D, 32)
738
+ def test_r32_64_m8(self):
739
+ I64("pextrb eax, xmm4, 0xaa").check_reg(0, Regs.EAX, 32)
740
+ I64("pextrb [rbx], xmm2, 0xaa").check_simple_deref(0, Regs.RBX, 8)
741
+ def test_r32_64_m16(self):
742
+ I64("pextrw esp, xmm7, 0x11").check_reg(0, Regs.ESP, 32)
743
+ I64("pextrw [rbp], xmm0, 0xbb").check_simple_deref(0, Regs.RBP, 16)
744
+ def test_rfull_m16(self):
745
+ I64("smsw eax").check_reg(0, Regs.EAX, 32)
746
+ I64("smsw [rbx]").check_simple_deref(0, Regs.RBX, 16)
747
+ def test_creg(self):
748
+ I64("mov rsp, cr3").check_reg(1, Regs.CR3, 64)
749
+ I64("mov cr8, rdx").check_reg(0, Regs.CR8, 64)
750
+ def test_dreg(self):
751
+ I64("mov rdi, dr7").check_reg(1, Regs.DR7, 64)
752
+ def test_sreg(self):
753
+ I64("mov ax, fs").check_reg(1, Regs.FS, 16)
754
+ def test_seg(self):
755
+ I64("push gs").check_reg(0, Regs.GS, 16)
756
+ def test_acc8(self):
757
+ I64("in al, 0x60").check_reg(0, Regs.AL, 8)
758
+ def test_acc_full(self):
759
+ I64("add rax, 0x100").check_reg(0, Regs.RAX, 64)
760
+ def test_acc_full_not64(self):
761
+ I64("out 0x64, eax").check_reg(1, Regs.EAX, 32)
762
+ def test_mem16_full(self):
763
+ I64("call far [rbp]").check_simple_deref(0, Regs.RBP, 32)
764
+ I64("db 0x48\n call far [rbp]").check_simple_deref(0, Regs.RBP, 64)
765
+ def test_mem16_3264(self):
766
+ I64("sgdt [rbx]").check_simple_deref(0, Regs.RBX, 64)
767
+ def test_relcb(self):
768
+ a = I64("db 0xe9\ndd 0x00")
769
+ a.check_pc(5, 32)
770
+ a = I64("db 0xe2\ndb 0x50")
771
+ a.check_pc(0x52, 8)
772
+ a = I64("db 0xe2\ndb 0xfd")
773
+ a.check_pc(-1, 8)
774
+ a = I64("db 0x67\ndb 0xe2\ndb 0xf0")
775
+ a.check_pc(-0xd, 8)
776
+ def test_relc_full(self):
777
+ a = I64("jmp 0x100")
778
+ self.assertEqual(a.inst.size, 5)
779
+ a.check_type_size(0, distorm3.OPERAND_IMMEDIATE, 32)
780
+ def test_mem(self):
781
+ I64("lea ax, [rbx]").check_simple_deref(1, Regs.RBX, 0)
782
+ def test_mem32(self):
783
+ I64("movntss [rbx], xmm5").check_simple_deref(0, Regs.RBX, 32)
784
+ def test_mem32_64(self):
785
+ I64("movnti [rdi], eax").check_simple_deref(0, Regs.RDI, 32)
786
+ I64("movnti [rbp], rax").check_simple_deref(0, Regs.RBP, 64)
787
+ def test_mem64(self):
788
+ I64("movlps [rdi], xmm7").check_simple_deref(0, Regs.RDI, 64)
789
+ def test_mem128(self):
790
+ I64("movntps [rax], xmm3").check_simple_deref(0, Regs.RAX, 128)
791
+ def test_mem64_128(self):
792
+ I64("cmpxchg8b [rdx]").check_simple_deref(0, Regs.RDX, 64)
793
+ I64("cmpxchg16b [rbx]").check_simple_deref(0, Regs.RBX, 128)
794
+ def test_moffs8(self):
795
+ I64("mov al, [dword 0x12345678]").check_abs_disp(1, 0x12345678, 32, 8)
796
+ I64("mov [qword 0xaaaabbbbccccdddd], al").check_abs_disp(0, 0xaaaabbbbccccdddd, 64, 8)
797
+ def test_moff_full(self):
798
+ I64("mov [dword 0xaaaabbbb], rax").check_abs_disp(0, 0xffffffffaaaabbbb, 32, 64)
799
+ I64("mov rax, [qword 0xaaaabbbbccccdddd]").check_abs_disp(1, 0xaaaabbbbccccdddd, 64, 64)
800
+ def test_const1(self):
801
+ I64("shl rsi, 1").check_imm(1, 1, 8)
802
+ def test_regcl(self):
803
+ I64("rcl rbp, cl").check_reg(1, Regs.CL, 8)
804
+ def test_ib_rb(self):
805
+ I64("mov dl, 0x88").check_reg(0, Regs.DL, 8)
806
+ I64("mov spl, 0x88").check_reg(0, Regs.SPL, 8)
807
+ I64("mov r10b, 0x88").check_reg(0, Regs.R10B, 8)
808
+ def test_ib_r_dw_qw(self):
809
+ I64("bswap rcx").check_reg(0, Regs.RCX, 64)
810
+ I64("bswap r10").check_reg(0, Regs.R10, 64)
811
+ I64("push r10").check_reg(0, Regs.R10, 64)
812
+ def test_ib_r_full(self):
813
+ I64("inc rsi").check_reg(0, Regs.RSI, 64)
814
+ I64("inc r9").check_reg(0, Regs.R9, 64)
815
+ I64("push r10w").check_reg(0, Regs.R10W, 16)
816
+ I64("xchg r10d, eax").check_reg(0, Regs.R10D, 32)
817
+ def test_regi_esi(self):
818
+ I64("lodsb").check_simple_deref(1, Regs.RSI, 8)
819
+ I64("cmpsw").check_simple_deref(0, Regs.RSI, 16)
820
+ I64("lodsd").check_simple_deref(1, Regs.RSI, 32)
821
+ I64("lodsq").check_simple_deref(1, Regs.RSI, 64)
822
+ def test_regi_edi(self):
823
+ I64("movsb").check_simple_deref(0, Regs.RDI, 8)
824
+ I64("scasw").check_simple_deref(0, Regs.RDI, 16)
825
+ I64("stosd").check_simple_deref(0, Regs.RDI, 32)
826
+ I64("stosq").check_simple_deref(0, Regs.RDI, 64)
827
+ def test_regi_ebxal(self):
828
+ a = I64("xlatb")
829
+ a.check_type_size(0, distorm3.OPERAND_MEMORY, 8)
830
+ self.failIf(a.inst.operands[0].index != Regs.AL)
831
+ self.failIf(a.inst.operands[0].base != Regs.RBX)
832
+ def test_regi_eax(self):
833
+ I64("vmrun [rax]").check_simple_deref(0, Regs.RAX, 64)
834
+ def test_regdx(self):
835
+ #I64("in eax, dx").check_reg(1, Regs.DX, 16)
836
+ pass
837
+ def test_regecx(self):
838
+ I64("invlpga [rax], ecx").check_reg(1, Regs.ECX, 32)
839
+ def test_fpu_si(self):
840
+ I64("fxch st4").check_reg(0, Regs.ST4, 32)
841
+ def test_fpu_ssi(self):
842
+ a = I64("fcmovnbe st0, st3")
843
+ a.check_reg(0, Regs.ST0, 32)
844
+ a.check_reg(1, Regs.ST3, 32)
845
+ def test_fpu_sis(self):
846
+ a = I64("fadd st3, st0")
847
+ a.check_reg(0, Regs.ST3, 32)
848
+ a.check_reg(1, Regs.ST0, 32)
849
+ def test_mm(self):
850
+ I64("pand mm0, mm7").check_reg(0, Regs.MM0, 64)
851
+ def test_mm_rm(self):
852
+ I64("psllw mm0, 0x55").check_reg(0, Regs.MM0, 64)
853
+ def test_mm32(self):
854
+ I64("punpcklbw mm1, [rsi]").check_simple_deref(1, Regs.RSI, 32)
855
+ def test_mm64(self):
856
+ I64("packsswb mm3, [rbx]").check_simple_deref(1, Regs.RBX, 64)
857
+ def test_xmm(self):
858
+ I64("orps xmm5, xmm4").check_reg(0, Regs.XMM5, 128)
859
+ I64("orps xmm15, xmm4").check_reg(0, Regs.XMM15, 128)
860
+ def test_xmm_rm(self):
861
+ I64("psrlw xmm6, 0x12").check_reg(0, Regs.XMM6, 128)
862
+ I64("psrlw xmm13, 0x12").check_reg(0, Regs.XMM13, 128)
863
+ def test_xmm16(self):
864
+ I64("pmovsxbq xmm3, [rbp]").check_simple_deref(1, Regs.RBP, 16)
865
+ def test_xmm32(self):
866
+ I64("pmovsxwq xmm5, [rdi]").check_simple_deref(1, Regs.RDI, 32)
867
+ def test_xmm64(self):
868
+ I64("roundsd xmm6, [rsi], 0x55").check_simple_deref(1, Regs.RSI, 64)
869
+ def test_xmm128(self):
870
+ I64("roundpd xmm7, [rbx], 0xaa").check_simple_deref(1, Regs.RBX, 128)
871
+ I64("roundpd xmm7, xmm15, 0xaa").check_reg(1, Regs.XMM15, 128)
872
+ def test_regxmm0(self):
873
+ I64("blendvpd xmm1, xmm3, xmm0").check_reg(2, Regs.XMM0, 128)
874
+ def test_disp_only(self):
875
+ a = I64("add [0x12345678], rbx")
876
+ a.check_type_size(0, distorm3.OPERAND_ABSOLUTE_ADDRESS, 64)
877
+ self.failIf(a.inst.operands[0].dispSize != 32)
878
+ self.failIf(a.inst.operands[0].disp != 0x12345678)
879
+ def test_modrm(self):
880
+ texts = ["ADD [%s], RDI" % i for i in self.Derefs]
881
+ for i in enumerate(texts):
882
+ a = I64(i[1])
883
+ a.check_simple_deref(0, self.DerefsInfo[i[0]], 64)
884
+ def test_modrm_disp8(self):
885
+ texts = ["ADD [%s + 0x55], RSI" % i for i in self.Derefs]
886
+ for i in enumerate(texts):
887
+ a = I64(i[1])
888
+ a.check_simple_deref(0, self.DerefsInfo[i[0]], 64)
889
+ self.failIf(a.inst.operands[0].dispSize != 8)
890
+ self.failIf(a.inst.operands[0].disp != 0x55)
891
+ def test_modrm_disp32(self):
892
+ texts = ["ADD [%s + 0x33221144], RDX" % i for i in self.Derefs]
893
+ for i in enumerate(texts):
894
+ a = I64(i[1])
895
+ a.check_simple_deref(0, self.DerefsInfo[i[0]], 64)
896
+ self.failIf(a.inst.operands[0].dispSize != 32)
897
+ self.failIf(a.inst.operands[0].disp != 0x33221144)
898
+ def test_base_rbp(self):
899
+ a = I64("mov [rbp+0x55], eax")
900
+ a.check_simple_deref(0, Regs.RBP, 32)
901
+ self.failIf(a.inst.operands[0].dispSize != 8)
902
+ self.failIf(a.inst.operands[0].disp != 0x55)
903
+ a = I64("mov [rbp+0x55443322], eax")
904
+ a.check_simple_deref(0, Regs.RBP, 32)
905
+ self.failIf(a.inst.operands[0].dispSize != 32)
906
+ self.failIf(a.inst.operands[0].disp != 0x55443322)
907
+ def test_base_rip(self):
908
+ a = I64("mov [rip+0x12345678], rdx")
909
+ a.check_simple_deref(0, Regs.RIP, 64)
910
+ self.failIf(a.inst.operands[0].dispSize != 32)
911
+ self.failIf(a.inst.operands[0].disp != 0x12345678)
912
+ def test_reg8_rex(self):
913
+ I64("mov sil, al").check_reg(0, Regs.SIL, 8)
914
+ I64("inc bpl").check_reg(0, Regs.BPL, 8)
915
+ def test_imm64(self):
916
+ I64("mov rax, 0x1234567890abcdef").check_imm(1, 0x1234567890abcdef, 64)
917
+ def test_reg64(self):
918
+ I64("movsxd r10, eax").check_reg(0, Regs.R10, 64)
919
+ def test_rm16_32(self):
920
+ #MOVZXD RAX, [RAX]
921
+ I64("db 0x63\n db 0x00").check_simple_deref(1, Regs.RAX, 32)
922
+ #MOVZXDW RAX, [RAX]
923
+ #I64("db 0x66\n db 0x63\n db 0x00").check_simple_deref(1, Regs.RAX, 16)
924
+ #MOVZXD RAX, EAX
925
+ I64("db 0x63\n db 0xc0").check_reg(1, Regs.EAX, 32)
926
+ #MOVZXDW RAX, AX
927
+ #I64("db 0x66\n db 0x63\n db 0xc0").check_reg(1, Regs.AX, 16)
928
+ #MOVZXDW RAX, R8W
929
+ #I64("db 0x66\n db 0x41\n db 0x63\n db 0xc0").check_reg(1, Regs.R8W, 16)
930
+ Bases = ["RAX", "RCX", "RDX", "RBX", "RSP", "RSI", "RDI", "R8", "R9", "R10", "R11", "R12", "R13", "R14", "R15"]
931
+ BasesInfo = [Regs.RAX, Regs.RCX, Regs.RDX, Regs.RBX, Regs.RSP, Regs.RSI, Regs.RDI, Regs.R8, Regs.R9, Regs.R10, Regs.R11, Regs.R12, Regs.R13, Regs.R14, Regs.R15]
932
+ Indices = ["RAX", "RCX", "RDX", "RBX", "RBP", "RSI", "RDI", "R8", "R9", "R10", "R11", "R12", "R13", "R14", "R15"]
933
+ IndicesInfo = [Regs.RAX, Regs.RCX, Regs.RDX, Regs.RBX, Regs.RBP, Regs.RSI, Regs.RDI, Regs.R8, Regs.R9, Regs.R10, Regs.R11, Regs.R12, Regs.R13, Regs.R14, Regs.R15]
934
+ def test_bases(self):
935
+ for i in enumerate(self.Bases):
936
+ a = I64("cmp rbp, [%s]" % (i[1]))
937
+ a.check_simple_deref(1, self.BasesInfo[i[0]], 64)
938
+ def test_bases_disp32(self):
939
+ for i in enumerate(self.Bases):
940
+ a = I64("cmp rbp, [%s+0x12345678]" % (i[1]))
941
+ a.check_simple_deref(1, self.BasesInfo[i[0]], 64)
942
+ self.failIf(a.inst.operands[1].dispSize != 32)
943
+ self.failIf(a.inst.operands[1].disp != 0x12345678)
944
+ def test_scales(self):
945
+ for i in enumerate(self.Indices):
946
+ # A scale of 2 causes the scale to be omitted and changed from reg*2 to reg+reg.
947
+ for s in [4, 8]:
948
+ a = I64("and rbp, [%s*%d]" % (i[1], s))
949
+ a.check_deref(1, self.IndicesInfo[i[0]], None, 64)
950
+ self.failIf(a.inst.operands[1].scale != s)
951
+ def test_sib(self):
952
+ for i in enumerate(self.Indices):
953
+ for j in enumerate(self.Bases):
954
+ for s in [1, 2, 4, 8]:
955
+ a = I64("or rbp, [%s*%d + %s]" % (i[1], s, j[1]))
956
+ a.check_deref(1, self.IndicesInfo[i[0]], self.BasesInfo[j[0]], 64)
957
+ if s != 1:
958
+ self.failIf(a.inst.operands[1].scale != s)
959
+ def test_sib_disp8(self):
960
+ for i in enumerate(self.Indices):
961
+ for j in enumerate(self.Bases):
962
+ for s in [1, 2, 4, 8]:
963
+ a = I64("xor al, [%s*%d + %s + 0x55]" % (i[1], s, j[1]))
964
+ a.check_deref(1, self.IndicesInfo[i[0]], self.BasesInfo[j[0]], 8)
965
+ self.failIf(a.inst.operands[1].dispSize != 8)
966
+ self.failIf(a.inst.operands[1].disp != 0x55)
967
+ if s != 1:
968
+ self.failIf(a.inst.operands[1].scale != s)
969
+ def test_sib_disp32(self):
970
+ for i in enumerate(self.Indices):
971
+ for j in enumerate(self.Bases):
972
+ for s in [1, 2, 4, 8]:
973
+ a = I64("sub rdx, [%s*%d + %s + 0x55aabbcc]" % (i[1], s, j[1]))
974
+ a.check_deref(1, self.IndicesInfo[i[0]], self.BasesInfo[j[0]], 64)
975
+ self.failIf(a.inst.operands[1].dispSize != 32)
976
+ self.failIf(a.inst.operands[1].disp != 0x55aabbcc)
977
+ if s != 1:
978
+ self.failIf(a.inst.operands[1].scale != s)
979
+ def test_base32(self):
980
+ I64("mov eax, [ebx]").check_simple_deref(1, Regs.EBX, 32)
981
+
982
+ class TestInstTable(unittest.TestCase):
983
+ """ Check that locate_inst algorithm covers all opcode-length (ol)
984
+ for the varying sizes of opcodes.
985
+ The bad tests should not find an instruction, so they should fail on purpose,
986
+ to see we don't crash the diassembler.
987
+ Also test for some end-cases with nop and wait. """
988
+ def test_c7_opcode(self):
989
+ IB32("c7f8aaaaaaaa").check_mnemonic("XBEGIN")
990
+ IB64("c7f8aaaaaaaa").check_mnemonic("XBEGIN")
991
+ IB32("C7C108000000").check_mnemonic("MOV")
992
+ IB64("C7C108000000").check_mnemonic("MOV")
993
+ IB64("48C7C000000000").check_mnemonic("MOV")
994
+ def test_tx(self):
995
+ IB64("0f01d5").check_mnemonic("XEND")
996
+ IB64("c6f8bb").check_mnemonic("XABORT")
997
+ IB64("c7f800000000").check_mnemonic("XBEGIN")
998
+ def test_fuzz_9b_and_c7(self):
999
+ for i in xrange(10000):
1000
+ s = "%02x%02x" % (i & 0xff, random.randint(0, 255))
1001
+ IB32("9b%sffffffff" % s)
1002
+ IB32("c7%sffffffff" % s)
1003
+ def test_ol1(self):
1004
+ IB32("00c0").check_mnemonic("ADD")
1005
+ def test_ol13(self):
1006
+ IB32("80c055").check_mnemonic("ADD")
1007
+ def test_ol1d(self):
1008
+ IB32("d900").check_mnemonic("FLD")
1009
+ IB32("d9c8").check_mnemonic("FXCH")
1010
+ IB32("d9e1").check_mnemonic("FABS")
1011
+ def test_ol2(self):
1012
+ IB32("0f06").check_mnemonic("CLTS")
1013
+ def test_ol23(self):
1014
+ IB32("0fbae055").check_mnemonic("BT")
1015
+ def test_ol2d(self):
1016
+ IB32("0f01e0").check_mnemonic("SMSW")
1017
+ IB32("0f0130").check_mnemonic("LMSW")
1018
+ IB32("0f01c9").check_mnemonic("MWAIT")
1019
+ def test_ol3(self):
1020
+ IB32("0f380000").check_mnemonic("PSHUFB")
1021
+ def test_ol1_bad(self):
1022
+ # There is no undefined instruction in the root, except a prefix, oh well.
1023
+ pass
1024
+ def test_ol13_bad(self):
1025
+ IB32("f780").check_invalid()
1026
+ def test_ol1d_bad(self):
1027
+ IB32("d908").check_invalid()
1028
+ IB32("d9d1").check_invalid()
1029
+ IB32("d9ef").check_invalid()
1030
+ def test_ol2_bad(self):
1031
+ IB32("0fff").check_invalid()
1032
+ def test_ol23_bad(self):
1033
+ IB32("0f0dff").check_invalid()
1034
+ def test_ol2d_bad(self):
1035
+ IB32("0f0128").check_invalid()
1036
+ IB32("0f01ca").check_invalid()
1037
+ def test_ol3_bad(self):
1038
+ IB32("0f0fff").check_invalid()
1039
+ def test_index63(self):
1040
+ # Test arpl, since it has a special treatment for 32/64 bits.
1041
+ a = IB32("63c0")
1042
+ a.check_mnemonic("ARPL")
1043
+ a = IB64("63c0")
1044
+ a.check_mnemonic("MOVSXD")
1045
+ def test_index90(self):
1046
+ # If nop is prefixed with f3, it is pause then. If it is prefixed with rex, it might be xchg.
1047
+ IB32("90").check_mnemonic("NOP")
1048
+ IB64("90").check_mnemonic("NOP")
1049
+ IB64("4890").check_mnemonic("NOP")
1050
+ IB64("4190").check_mnemonic("XCHG")
1051
+ IB64("f390").check_mnemonic("PAUSE")
1052
+ def test_wait(self):
1053
+ # Wait instruction is very tricky. It might be coalesced with the next bytes.
1054
+ # If the next bytes are 'waitable', otherwise it is a standalone instruction.
1055
+ IB32("9b90").check_mnemonic("WAIT", 0) # nop isn't waitable.
1056
+ IB32("9bdfe0").check_mnemonic("FSTSW") # waitable stsw
1057
+ IB32("dfe0").check_mnemonic("FNSTSW") # non-waitable stsw
1058
+ IB32("9b00c0").check_mnemonic("WAIT") # add isn't waitable
1059
+ IB32("9bd930").check_mnemonic("FSTENV") # waitable fstenv
1060
+ IB32("9b66dbe3").check_mnemonic("WAIT") # prefix breaks waiting
1061
+ def test_3dnow(self):
1062
+ IB32("0f0fc00d").check_mnemonic("PI2FD")
1063
+ IB32("0f0d00").check_mnemonic("PREFETCH")
1064
+ def test_mandatory(self):
1065
+ IB32("f30f10c0").check_mnemonic("MOVSS")
1066
+ IB32("660f10c0").check_mnemonic("MOVUPD")
1067
+ IB32("660f71d055").check_mnemonic("PSRLW")
1068
+ IB32("660ffec0").check_mnemonic("PADDD")
1069
+ IB32("f20f10c0").check_mnemonic("MOVSD")
1070
+ IB32("f20f11c0").check_mnemonic("MOVSD")
1071
+ IB32("660f3800c0").check_mnemonic("PSHUFB")
1072
+ IB32("f20f38f0c0").check_mnemonic("CRC32")
1073
+ IB32("660fc730").check_mnemonic("VMCLEAR")
1074
+ IB32("f30fc730").check_mnemonic("VMXON")
1075
+ def test_vex(self):
1076
+ I32("vaddpd ymm1, ymm2, ymm2").check_mnemonic("VADDPD") # pre encoding: 66, 0f, 58
1077
+ I32("vaddps ymm1, ymm2, ymm2").check_mnemonic("VADDPS") # pre encoding: 0f, 58
1078
+ I32("vaddsd xmm1, xmm2, qword [eax]").check_mnemonic("VADDSD") # pre encoding: f2, 0f, 58
1079
+ I32("vaddss xmm1, xmm2, dword [eax]").check_mnemonic("VADDSS") # pre encoding: f3, 0f, 58
1080
+ I32("vmovsd xmm1, xmm2, xmm3").check_mnemonic("VMOVSD") # pre encoding: f2, 0f, 10
1081
+ I32("vmovsd xmm1, qword [eax]").check_mnemonic("VMOVSD") # pre encoding: f2 0f 10 - but VEX.vvvv is not encoded!
1082
+ # Since in a VEX prefix you can encode the virtual prefix, we got three ways to get to 0xf 0x38
1083
+ # So see that both work well.
1084
+ IB32("c4e279dbc2").check_mnemonic("VAESIMC") # pre encoding: 66, 0f, 38, db, virtual prefix is 0f 38
1085
+ IB32("c4e17938dbc2").check_mnemonic("VAESIMC") # the virtual prefix is only 0f
1086
+ IB32("c5f938dbc2").check_mnemonic("VAESIMC") # the virtual prefix is only 0f, but short VEX
1087
+ # Same test as earlier, but for 0xf 0x3a, though this instruction doesn't have a short form.
1088
+ IB32("c4e3710dc255").check_mnemonic("VBLENDPD") # pre encoding: 66, 0f, 3a, 0d, virtual prefix is 0f 3a
1089
+ IB32("c4e1713a0dc255").check_mnemonic("VBLENDPD") # pre encoding: 66, 0f, 3a, 0d, virtual prefix is 0f
1090
+ I32("vldmxcsr dword [eax]").check_mnemonic("VLDMXCSR")
1091
+ I32("vzeroupper").check_mnemonic("VZEROUPPER")
1092
+ I32("vzeroall").check_mnemonic("VZEROALL")
1093
+ I32("vpslld xmm1, xmm2, xmm3").check_mnemonic("VPSLLD")
1094
+ def test_vex_special(self):
1095
+ # VVVV encoded, where there is not such an encoding for the VAESIMC instruction.
1096
+ IB32("c4e271dbca").check_invalid()
1097
+ IB32("c4e2791800").check_mnemonic("VBROADCASTSS") # just to make sure this instruction is fine.
1098
+ IB32("c4e279ff00").check_invalid() # pre encoding: 66, 0f, 38, ff
1099
+ IB32("c4e179ff00").check_invalid() # pre encoding: 66, 0f, 38, ff, mmmmm = 1
1100
+ IB32("c4e379ff00").check_invalid() # pre encoding: 66, 0f, 38, ff, mmmmm = 3
1101
+ IB32("c4e4791800").check_invalid() # pre encoding: 66, 0f, 38, 18, mmmmm = 4
1102
+ IB32("c5f8ae10").check_mnemonic("VLDMXCSR") # pre encoding: 0f, ae /02
1103
+ IB32("c4c178ae10").check_mnemonic("VLDMXCSR") # longer form of 0f, ae /02
1104
+ IB32("c4c179ae10").check_invalid() # longer form of 0f, ae /02, invalid pp=1
1105
+ IB32("c4c17aae10").check_invalid() # longer form of 0f, ae /02, invalid pp=2
1106
+ IB32("c4c17bae10").check_invalid() # longer form of 0f, ae /02, invalid pp=3
1107
+ IB32("c4c17877").check_mnemonic("VZEROUPPER") # longer form of 0f, 77
1108
+ IB32("c4c17c77").check_mnemonic("VZEROALL") # longer form of 0f, 77
1109
+ IB32("c4c97c77").check_invalid() # longer form of 0f, 77, invalid mmmmm
1110
+ def test_crc32(self):
1111
+ I32("crc32 eax, al").check_reg(0, Regs.EAX, 32)
1112
+ def test_lzcnt(self):
1113
+ # This is the only instruction that has a mandatory prefix and can have ALSO a valid operand size prefix!
1114
+ I32("lzcnt ax, bx").check_reg(0, Regs.AX, 16)
1115
+ I32("lzcnt eax, ebx").check_reg(0, Regs.EAX, 32)
1116
+ I64("lzcnt rax, rbx").check_reg(0, Regs.RAX, 64)
1117
+
1118
+ class TestAVXOperands(unittest.TestCase):
1119
+ def test_rm32(self):
1120
+ #I16("vextractps eax, xmm2, 3").check_reg(0, Regs.EAX, 32)
1121
+ I32("vextractps eax, xmm2, 3").check_reg(0, Regs.EAX, 32)
1122
+ I64("vextractps eax, xmm2, 3").check_reg(0, Regs.EAX, 32)
1123
+ def test_reg32_64_m8(self):
1124
+ #I16("vpextrb eax, xmm2, 3").check_reg(0, Regs.EAX, 32)
1125
+ I32("vpextrb eax, xmm2, 3").check_reg(0, Regs.EAX, 32)
1126
+ I64("vpextrb eax, xmm2, 3").check_reg(0, Regs.EAX, 32)
1127
+ I64("vpextrb rax, xmm2, 3").check_reg(0, Regs.RAX, 64)
1128
+ I32("vpextrb [ebx], xmm2, 3").check_simple_deref(0, Regs.EBX, 8)
1129
+ I64("vpextrb [rbx], xmm2, 3").check_simple_deref(0, Regs.RBX, 8)
1130
+ def test_reg32_64_m16(self):
1131
+ I32("vpextrw eax, xmm2, 3").check_reg(0, Regs.EAX, 32)
1132
+ I64("vpextrw rax, xmm2, 3").check_reg(0, Regs.RAX, 64)
1133
+ I64("vpextrw rax, xmm2, 3").check_reg(0, Regs.RAX, 64)
1134
+ I32("vpextrw [ebx], xmm2, 3").check_simple_deref(0, Regs.EBX, 16)
1135
+ I64("vpextrw [rbx], xmm2, 3").check_simple_deref(0, Regs.RBX, 16)
1136
+ def test_wreg32_64_WITH_wxmm32_64(self):
1137
+ a = I32("vcvtss2si eax, xmm1")
1138
+ a.check_reg(0, Regs.EAX, 32)
1139
+ a.check_reg(1, Regs.XMM1, 128)
1140
+ a = I64("vcvtss2si rax, [rbx]")
1141
+ a.check_reg(0, Regs.RAX, 64)
1142
+ a.check_simple_deref(1, Regs.RBX, 64)
1143
+ a = I64("vcvtss2si eax, [rbx]")
1144
+ a.check_reg(0, Regs.EAX, 32)
1145
+ a.check_simple_deref(1, Regs.RBX, 32)
1146
+ def test_vxmm(self):
1147
+ I32("vaddsd xmm1, xmm2, xmm3").check_reg(1, Regs.XMM2, 128)
1148
+ I64("vaddsd xmm2, xmm3, xmm4").check_reg(1, Regs.XMM3, 128)
1149
+ def test_xmm_imm(self):
1150
+ I32("vpblendvb xmm1, xmm2, xmm3, xmm4").check_reg(3, Regs.XMM4, 128)
1151
+ # Force XMM15, but high bit is ignored in 32bits.
1152
+ self.failIf(IB32("c4e3694ccbf0").inst.operands[3].index != Regs.XMM7)
1153
+ I64("vpblendvb xmm1, xmm2, xmm3, xmm15").check_reg(3, Regs.XMM15, 128)
1154
+ def test_yxmm(self):
1155
+ I32("vaddsubpd ymm2, ymm4, ymm6").check_reg(0, Regs.YMM2, 256)
1156
+ I32("vaddsubpd xmm7, xmm4, xmm6").check_reg(0, Regs.XMM7, 128)
1157
+ I64("vaddsubpd ymm12, ymm4, ymm6").check_reg(0, Regs.YMM12, 256)
1158
+ I64("vaddsubpd xmm14, xmm4, xmm6").check_reg(0, Regs.XMM14, 128)
1159
+ def test_yxmm_imm(self):
1160
+ I32("vblendvpd xmm1, xmm2, xmm3, xmm4").check_reg(3, Regs.XMM4, 128)
1161
+ I32("vblendvpd ymm1, ymm2, ymm3, ymm4").check_reg(3, Regs.YMM4, 256)
1162
+ # Force YMM15, but high bit is ignored in 32bits.
1163
+ self.failIf(IB32("c4e36d4bcbf0").inst.operands[3].index != Regs.YMM7)
1164
+ I64("vblendvpd xmm1, xmm2, xmm3, xmm14").check_reg(3, Regs.XMM14, 128)
1165
+ I64("vblendvpd ymm1, ymm2, ymm3, ymm9").check_reg(3, Regs.YMM9, 256)
1166
+ def test_ymm(self):
1167
+ I32("vbroadcastsd ymm5, [eax]").check_reg(0, Regs.YMM5, 256)
1168
+ I64("vbroadcastsd ymm13, [rax]").check_reg(0, Regs.YMM13, 256)
1169
+ def test_ymm256(self):
1170
+ I32("vperm2f128 ymm2, ymm4, [eax], 0x55").check_simple_deref(2, Regs.EAX, 256)
1171
+ I64("vperm2f128 ymm2, ymm14, [rax], 0x55").check_simple_deref(2, Regs.RAX, 256)
1172
+ def test_vymm(self):
1173
+ I32("vinsertf128 ymm1, ymm4, xmm4, 0xaa").check_reg(1, Regs.YMM4, 256)
1174
+ I64("vinsertf128 ymm1, ymm15, xmm4, 0xaa").check_reg(1, Regs.YMM15, 256)
1175
+ def test_vyxmm(self):
1176
+ I32("vmaxpd xmm1, xmm2, xmm3").check_reg(1, Regs.XMM2, 128)
1177
+ I32("vmaxpd ymm1, ymm2, ymm3").check_reg(1, Regs.YMM2, 256)
1178
+ I64("vmaxpd xmm1, xmm12, xmm3").check_reg(1, Regs.XMM12, 128)
1179
+ I64("vmaxpd ymm1, ymm12, ymm3").check_reg(1, Regs.YMM12, 256)
1180
+ def test_yxmm64_256(self):
1181
+ I32("vmovddup xmm1, xmm2").check_reg(1, Regs.XMM2, 128)
1182
+ I32("vmovddup ymm1, ymm2").check_reg(1, Regs.YMM2, 256)
1183
+ I32("vmovddup xmm1, [ecx]").check_simple_deref(1, Regs.ECX, 64)
1184
+ I32("vmovddup ymm1, [ebx]").check_simple_deref(1, Regs.EBX, 256)
1185
+ I64("vmovddup xmm1, xmm12").check_reg(1, Regs.XMM12, 128)
1186
+ I64("vmovddup ymm1, ymm12").check_reg(1, Regs.YMM12, 256)
1187
+ I64("vmovddup xmm1, [rcx]").check_simple_deref(1, Regs.RCX, 64)
1188
+ I64("vmovddup ymm1, [rbx]").check_simple_deref(1, Regs.RBX, 256)
1189
+ def test_yxmm128_256(self):
1190
+ I32("vandnpd xmm1, xmm2, xmm3").check_reg(2, Regs.XMM3, 128)
1191
+ I32("vandnpd ymm1, ymm2, ymm3").check_reg(2, Regs.YMM3, 256)
1192
+ I32("vandnpd xmm1, xmm2, [edi]").check_simple_deref(2, Regs.EDI, 128)
1193
+ I32("vandnpd ymm1, ymm2, [esi]").check_simple_deref(2, Regs.ESI, 256)
1194
+ I64("vandnpd xmm1, xmm2, xmm13").check_reg(2, Regs.XMM13, 128)
1195
+ I64("vandnpd ymm1, ymm2, ymm13").check_reg(2, Regs.YMM13, 256)
1196
+ I64("vandnpd xmm1, xmm2, [rdi]").check_simple_deref(2, Regs.RDI, 128)
1197
+ I64("vandnpd ymm1, ymm2, [rsi]").check_simple_deref(2, Regs.RSI, 256)
1198
+ def test_lxmm64_128(self):
1199
+ I32("vcvtdq2pd xmm1, xmm2").check_reg(1, Regs.XMM2, 128)
1200
+ I32("vcvtdq2pd xmm1, [eax]").check_simple_deref(1, Regs.EAX, 64)
1201
+ I32("vcvtdq2pd ymm1, [ebx]").check_simple_deref(1, Regs.EBX, 128)
1202
+ I64("vcvtdq2pd xmm1, xmm12").check_reg(1, Regs.XMM12, 128)
1203
+ I64("vcvtdq2pd xmm1, [rax]").check_simple_deref(1, Regs.RAX, 64)
1204
+ I64("vcvtdq2pd ymm1, [rbx]").check_simple_deref(1, Regs.RBX, 128)
1205
+ def test_lmem128_256(self):
1206
+ I32("vlddqu xmm1, [eax]").check_simple_deref(1, Regs.EAX, 128)
1207
+ I32("vlddqu ymm1, [eax]").check_simple_deref(1, Regs.EAX, 256)
1208
+ I64("vlddqu xmm1, [r14]").check_simple_deref(1, Regs.R14, 128)
1209
+ I64("vlddqu ymm1, [r13]").check_simple_deref(1, Regs.R13, 256)
1210
+
1211
+ class TestMisc(unittest.TestCase):
1212
+ def test_lods(self):
1213
+ a = I16("lodsb")
1214
+ a.check_reg(0, Regs.AL, 8)
1215
+ a.check_simple_deref(1, Regs.SI, 8)
1216
+ self.assertEqual(a.inst.isSegmentDefault, True)
1217
+ a = I32("lodsw")
1218
+ a.check_reg(0, Regs.AX, 16)
1219
+ a.check_simple_deref(1, Regs.ESI, 16)
1220
+ self.assertEqual(a.inst.isSegmentDefault, True)
1221
+ a = I32("lodsd")
1222
+ a.check_reg(0, Regs.EAX, 32)
1223
+ a.check_simple_deref(1, Regs.ESI, 32)
1224
+ self.assertEqual(a.inst.isSegmentDefault, True)
1225
+ a = I64("lodsq")
1226
+ a.check_reg(0, Regs.RAX, 64)
1227
+ a.check_simple_deref(1, Regs.RSI, 64)
1228
+ self.assertEqual(a.inst.isSegmentDefault, False)
1229
+ a = I16("db 0x2e\nlodsb")
1230
+ a.check_reg(0, Regs.AL, 8)
1231
+ a.check_simple_deref(1, Regs.SI, 8)
1232
+ self.assertEqual(a.inst.segment, Regs.CS)
1233
+ self.assertEqual(a.inst.isSegmentDefault, False)
1234
+ a = I32("db 0x2e\nlodsw")
1235
+ a.check_reg(0, Regs.AX, 16)
1236
+ a.check_simple_deref(1, Regs.ESI, 16)
1237
+ self.assertEqual(a.inst.segment, Regs.CS)
1238
+ self.assertEqual(a.inst.isSegmentDefault, False)
1239
+ a = I32("db 0x2e\nlodsd")
1240
+ a.check_reg(0, Regs.EAX, 32)
1241
+ a.check_simple_deref(1, Regs.ESI, 32)
1242
+ self.assertEqual(a.inst.segment, Regs.CS)
1243
+ self.assertEqual(a.inst.isSegmentDefault, False)
1244
+ a = I64("db 0x65\nlodsq")
1245
+ a.check_reg(0, Regs.RAX, 64)
1246
+ a.check_simple_deref(1, Regs.RSI, 64)
1247
+ self.assertEqual(a.inst.segment, Regs.GS)
1248
+ self.assertEqual(a.inst.isSegmentDefault, False)
1249
+ def test_stos(self):
1250
+ a = I16("stosb")
1251
+ a.check_simple_deref(0, Regs.DI, 8)
1252
+ a.check_reg(1, Regs.AL, 8)
1253
+ self.assertEqual(a.inst.isSegmentDefault, True)
1254
+ a = I32("stosw")
1255
+ a.check_simple_deref(0, Regs.EDI, 16)
1256
+ a.check_reg(1, Regs.AX, 16)
1257
+ self.assertEqual(a.inst.isSegmentDefault, True)
1258
+ a = I32("stosd")
1259
+ a.check_simple_deref(0, Regs.EDI, 32)
1260
+ a.check_reg(1, Regs.EAX, 32)
1261
+ self.assertEqual(a.inst.isSegmentDefault, True)
1262
+ a = I64("stosq")
1263
+ a.check_simple_deref(0, Regs.RDI, 64)
1264
+ a.check_reg(1, Regs.RAX, 64)
1265
+ self.assertEqual(a.inst.isSegmentDefault, False)
1266
+ a = I16("db 0x2e\nstosb")
1267
+ a.check_simple_deref(0, Regs.DI, 8)
1268
+ a.check_reg(1, Regs.AL, 8)
1269
+ self.assertEqual(a.inst.unusedPrefixesMask, 1)
1270
+ self.assertEqual(a.inst.segment, Regs.ES)
1271
+ self.assertEqual(a.inst.isSegmentDefault, True)
1272
+ a = I32("db 0x2e\nstosw")
1273
+ a.check_simple_deref(0, Regs.EDI, 16)
1274
+ a.check_reg(1, Regs.AX, 16)
1275
+ self.assertEqual(a.inst.unusedPrefixesMask, 1)
1276
+ self.assertEqual(a.inst.segment, Regs.ES)
1277
+ self.assertEqual(a.inst.isSegmentDefault, True)
1278
+ a = I32("db 0x2e\nstosd")
1279
+ a.check_simple_deref(0, Regs.EDI, 32)
1280
+ a.check_reg(1, Regs.EAX, 32)
1281
+ self.assertEqual(a.inst.unusedPrefixesMask, 1)
1282
+ self.assertEqual(a.inst.segment, Regs.ES)
1283
+ self.assertEqual(a.inst.isSegmentDefault, True)
1284
+ a = I64("db 0x65\nstosq")
1285
+ a.check_simple_deref(0, Regs.RDI, 64)
1286
+ a.check_reg(1, Regs.RAX, 64)
1287
+ self.assertEqual(a.inst.unusedPrefixesMask, 1)
1288
+ self.assertEqual(a.inst.segment, REG_NONE)
1289
+ def test_scas(self):
1290
+ a = I16("scasb")
1291
+ a.check_simple_deref(0, Regs.DI, 8)
1292
+ a.check_reg(1, Regs.AL, 8)
1293
+ self.assertEqual(a.inst.isSegmentDefault, True)
1294
+ a = I32("scasw")
1295
+ a.check_simple_deref(0, Regs.EDI, 16)
1296
+ a.check_reg(1, Regs.AX, 16)
1297
+ self.assertEqual(a.inst.isSegmentDefault, True)
1298
+ a = I32("scasd")
1299
+ a.check_simple_deref(0, Regs.EDI, 32)
1300
+ a.check_reg(1, Regs.EAX, 32)
1301
+ self.assertEqual(a.inst.isSegmentDefault, True)
1302
+ a = I64("scasq")
1303
+ a.check_simple_deref(0, Regs.RDI, 64)
1304
+ a.check_reg(1, Regs.RAX, 64)
1305
+ self.assertEqual(a.inst.isSegmentDefault, False)
1306
+ a = I16("db 0x2e\nscasb")
1307
+ a.check_simple_deref(0, Regs.DI, 8)
1308
+ a.check_reg(1, Regs.AL, 8)
1309
+ self.assertEqual(a.inst.unusedPrefixesMask, 1)
1310
+ self.assertEqual(a.inst.segment, Regs.ES)
1311
+ self.assertEqual(a.inst.isSegmentDefault, True)
1312
+ a = I32("db 0x2e\nscasw")
1313
+ a.check_simple_deref(0, Regs.EDI, 16)
1314
+ a.check_reg(1, Regs.AX, 16)
1315
+ self.assertEqual(a.inst.unusedPrefixesMask, 1)
1316
+ self.assertEqual(a.inst.segment, Regs.ES)
1317
+ self.assertEqual(a.inst.isSegmentDefault, True)
1318
+ a = I32("db 0x2e\nscasd")
1319
+ a.check_simple_deref(0, Regs.EDI, 32)
1320
+ a.check_reg(1, Regs.EAX, 32)
1321
+ self.assertEqual(a.inst.unusedPrefixesMask, 1)
1322
+ self.assertEqual(a.inst.segment, Regs.ES)
1323
+ self.assertEqual(a.inst.isSegmentDefault, True)
1324
+ a = I64("db 0x65\nscasq")
1325
+ a.check_simple_deref(0, Regs.RDI, 64)
1326
+ a.check_reg(1, Regs.RAX, 64)
1327
+ self.assertEqual(a.inst.unusedPrefixesMask, 1)
1328
+ self.assertEqual(a.inst.segment, REG_NONE)
1329
+ def test_cmps(self):
1330
+ a = I64("cmpsd")
1331
+ a.check_simple_deref(0, Regs.RSI, 32)
1332
+ a.check_simple_deref(1, Regs.RDI, 32)
1333
+ self.assertEqual(a.inst.unusedPrefixesMask, 0)
1334
+ self.assertEqual(a.inst.segment, REG_NONE)
1335
+ a = I16("db 0x2e\ncmpsb")
1336
+ a.check_simple_deref(0, Regs.SI, 8)
1337
+ a.check_simple_deref(1, Regs.DI, 8)
1338
+ self.assertEqual(a.inst.unusedPrefixesMask, 0)
1339
+ self.assertEqual(a.inst.segment, Regs.CS)
1340
+ self.assertEqual(a.inst.isSegmentDefault, False)
1341
+ def test_movs(self):
1342
+ a = I32("movsd")
1343
+ a.check_simple_deref(0, Regs.EDI, 32)
1344
+ a.check_simple_deref(1, Regs.ESI, 32)
1345
+ self.assertEqual(a.inst.unusedPrefixesMask, 0)
1346
+ self.assertEqual(a.inst.segment, Regs.DS)
1347
+ self.assertEqual(a.inst.isSegmentDefault, True)
1348
+ a = I32("db 0x2e\nmovsw")
1349
+ a.check_simple_deref(0, Regs.EDI, 16)
1350
+ a.check_simple_deref(1, Regs.ESI, 16)
1351
+ self.assertEqual(a.inst.unusedPrefixesMask, 0)
1352
+ self.assertEqual(a.inst.segment, Regs.CS)
1353
+ self.assertEqual(a.inst.isSegmentDefault, False)
1354
+ def test_ins(self):
1355
+ a = I32("db 0x65\ninsw")
1356
+ a.check_simple_deref(0, Regs.EDI, 16)
1357
+ a.check_reg(1, Regs.DX, 16)
1358
+ self.assertEqual(a.inst.unusedPrefixesMask, 1)
1359
+ self.assertEqual(a.inst.segment, Regs.ES)
1360
+ self.assertEqual(a.inst.isSegmentDefault, True)
1361
+ def test_outs(self):
1362
+ a = I64("db 0x65\noutsd")
1363
+ a.check_reg(0, Regs.DX, 16)
1364
+ a.check_simple_deref(1, Regs.RSI, 32)
1365
+ self.assertEqual(a.inst.segment, Regs.GS)
1366
+ self.assertEqual(a.inst.isSegmentDefault, False)
1367
+ def test_branch_hints(self):
1368
+ self.failIf("FLAG_HINT_TAKEN" not in I32("db 0x3e\n jnz 0x50").inst.flags)
1369
+ self.failIf("FLAG_HINT_NOT_TAKEN" not in I32("db 0x2e\n jp 0x55").inst.flags)
1370
+ self.failIf("FLAG_HINT_NOT_TAKEN" not in I32("db 0x2e\n jo 0x55000").inst.flags)
1371
+ self.failIf(I32("db 0x2e\n loop 0x55").inst.rawFlags & 0x1f, 0)
1372
+ def test_mnemonic_by_vexw(self):
1373
+ I32("vmovd xmm1, eax").check_mnemonic("VMOVD")
1374
+ I64("vmovd xmm1, eax").check_reg(1, Regs.EAX, 32)
1375
+ a = I64("vmovq xmm1, rax")
1376
+ a.check_mnemonic("VMOVQ")
1377
+ a.check_reg(1, Regs.RAX, 64)
1378
+ def test_vexl_ignored(self):
1379
+ I32("vaesdeclast xmm1, xmm2, xmm3").check_reg(0, Regs.XMM1, 128)
1380
+ IB32("c4e26ddfcb").check_mnemonic("VAESDECLAST")
1381
+ IB64("c4e26ddfcb").check_mnemonic("VAESDECLAST")
1382
+ def test_vexl_needed(self):
1383
+ I32("vinsertf128 ymm1, ymm2, xmm4, 0x42").check_mnemonic("VINSERTF128")
1384
+ IB32("c4e36918cc42").check_invalid() # Without VEX.L.
1385
+ IB64("c4e36918cc42").check_invalid() # Without VEX.L.
1386
+ def test_force_reg0(self):
1387
+ I32("extrq xmm1, 0x55, 0x66").check_mnemonic("EXTRQ")
1388
+ I64("extrq xmm14, 0x55, 0x66").check_reg(0, Regs.XMM14, 128)
1389
+ def test_pause(self):
1390
+ self.assertEqual(I16("pause").inst.size, 2)
1391
+ self.assertEqual(I32("pause").inst.size, 2)
1392
+ self.assertEqual(I64("pause").inst.size, 2)
1393
+ def test_nop(self):
1394
+ self.assertEqual(I16("db 0x90").inst.size, 1)
1395
+ self.assertEqual(I32("db 0x90").inst.size, 1)
1396
+ self.assertEqual(I64("db 0x90").inst.size, 1)
1397
+ self.assertEqual(I64("db 0x48, 0x90").inst.size, 2)
1398
+ # XCHG R8D, EAX
1399
+ a = I64("db 0x41, 0x90")
1400
+ a.check_reg(0, Regs.R8D, 32)
1401
+ a.check_reg(1, Regs.EAX, 32)
1402
+ # XCHG R8, RAX
1403
+ a = I64("db 0x49, 0x90")
1404
+ a.check_reg(0, Regs.R8, 64)
1405
+ a.check_reg(1, Regs.RAX, 64)
1406
+ a = I64("db 0x4f, 0x90")
1407
+ a.check_reg(0, Regs.R8, 64)
1408
+ a.check_reg(1, Regs.RAX, 64)
1409
+ def test_3dnow(self):
1410
+ I32("pfadd mm4, [eax]").check_reg(0, Regs.MM4, 64)
1411
+ I32("pfsub mm5, [eax]").check_reg(0, Regs.MM5, 64)
1412
+ I32("pfrcpit1 mm1, [ebx]").check_mnemonic("PFRCPIT1")
1413
+ I64("pavgusb mm1, mm2").check_mnemonic("PAVGUSB")
1414
+ def test_all_segs(self):
1415
+ I16("push fs").check_reg(0, Regs.FS, 16)
1416
+ I16("push gs").check_reg(0, Regs.GS, 16)
1417
+ I16("push ds").check_reg(0, Regs.DS, 16)
1418
+ I16("push cs").check_reg(0, Regs.CS, 16)
1419
+ I16("push ds").check_reg(0, Regs.DS, 16)
1420
+ I16("push es").check_reg(0, Regs.ES, 16)
1421
+ def test_op4(self):
1422
+ a = I32("insertq xmm2, xmm1, 0x55, 0xaa")
1423
+ a.check_reg(0, Regs.XMM2, 128)
1424
+ a.check_reg(1, Regs.XMM1, 128)
1425
+ a.check_type_size(2, distorm3.OPERAND_IMMEDIATE, 8)
1426
+ self.assertEqual(a.inst.operands[2].value, 0x55)
1427
+ a.check_type_size(3, distorm3.OPERAND_IMMEDIATE, 8)
1428
+ self.assertEqual(a.inst.operands[3].value, 0xaa)
1429
+ def test_pseudo_cmp(self):
1430
+ I32("cmpps xmm2, xmm3, 0x7")
1431
+ I64("cmpps xmm2, xmm4, 0x2")
1432
+ def test_jmp_counters(self):
1433
+ I16("jcxz 0x100")
1434
+ I32("jecxz 0x100")
1435
+ I64("jrcxz 0x100")
1436
+ def test_natives(self):
1437
+ self.assertEqual(I16("pusha").inst.size, 1)
1438
+ self.assertEqual(I16("pushad").inst.size, 2)
1439
+ self.assertEqual(I32("pusha").inst.size, 1)
1440
+ self.assertEqual(I32("pushaw").inst.size, 2)
1441
+ self.assertEqual(I16("CBW").inst.size, 1)
1442
+ self.assertEqual(I32("CWDE").inst.size, 1)
1443
+ self.assertEqual(I64("CDQE").inst.size, 2)
1444
+ def test_modrm_based(self):
1445
+ I32("movhlps xmm0, xmm1")
1446
+ I32("movhps xmm0, [eax]")
1447
+ I64("movhlps xmm0, xmm1")
1448
+ I64("movhps xmm0, [eax]")
1449
+ I64("movhlps xmm0, xmm1")
1450
+ I64("movlps xmm0, [eax]")
1451
+ def test_wait(self):
1452
+ self.assertEqual(I16("wait").inst.size, 1)
1453
+ def test_include_wait(self):
1454
+ self.assertEqual(I16("db 0x9b\n db 0xd9\n db 0x30").inst.size, 3)
1455
+ def test_loopxx_counters_size(self):
1456
+ a = I16("loopz 0x50")
1457
+ a.check_type_size(0,distorm3.OPERAND_IMMEDIATE, 8)
1458
+ a.check_addr_size(16)
1459
+ a = I32("loopz 0x50")
1460
+ a.check_type_size(0,distorm3.OPERAND_IMMEDIATE, 8)
1461
+ a.check_addr_size(32)
1462
+ a = I64("loopz 0x50")
1463
+ a.check_type_size(0,distorm3.OPERAND_IMMEDIATE, 8)
1464
+ a.check_addr_size(64)
1465
+ a = I16("db 0x67\n loopz 0x50")
1466
+ a.check_type_size(0,distorm3.OPERAND_IMMEDIATE, 8)
1467
+ a.check_addr_size(32)
1468
+ a = I32("db 0x67\n loopz 0x50")
1469
+ a.check_type_size(0,distorm3.OPERAND_IMMEDIATE, 8)
1470
+ a.check_addr_size(16)
1471
+ a = I64("db 0x67\n loopnz 0x50")
1472
+ a.check_type_size(0,distorm3.OPERAND_IMMEDIATE, 8)
1473
+ a.check_addr_size(32)
1474
+
1475
+ class TestPrefixes(unittest.TestCase):
1476
+ Derefs16 = ["BX + SI", "BX + DI", "BP + SI", "BP + DI", "SI", "DI", "BP", "BX"]
1477
+ Derefs32 = ["EAX", "ECX", "EDX", "EBX", "EBP", "ESI", "EDI"]
1478
+ Bases = ["EAX", "ECX", "EDX", "EBX", "ESP", "ESI", "EDI"]
1479
+ def test_without_seg(self):
1480
+ self.assertEqual(I64("and [rip+0X5247], ch").inst.segment, REG_NONE)
1481
+ self.assertEqual(I32("mov eax, [ebp*4]").inst.segment, Regs.DS)
1482
+ self.assertEqual(I32("mov eax, [eax*4+ebp]").inst.segment, Regs.SS)
1483
+ def test_default_seg16(self):
1484
+ a = I16("mov [ds:0x1234], ax")
1485
+ self.assertEqual(a.inst.segment, Regs.DS)
1486
+ self.assertEqual(a.inst.isSegmentDefault, 1)
1487
+ a = I16("mov [cs:0x1234], ax")
1488
+ self.assertEqual(a.inst.segment, Regs.CS)
1489
+ self.assertEqual(a.inst.isSegmentDefault, False)
1490
+ def test_default_seg16_all(self):
1491
+ for i in ["ADD [ds:%s], AX" % i for i in self.Derefs16]:
1492
+ a = I16(i)
1493
+ self.assertEqual(a.inst.segment, Regs.DS)
1494
+ if i[8:10] == "BP":
1495
+ self.assertEqual(a.inst.isSegmentDefault, False)
1496
+ else:
1497
+ self.assertEqual(a.inst.isSegmentDefault, True)
1498
+ # Test with disp8
1499
+ for i in ["ADD [ds:%s + 0x55], AX" % i for i in self.Derefs16]:
1500
+ a = I16(i)
1501
+ self.assertEqual(a.inst.segment, Regs.DS)
1502
+ if i[8:10] == "BP":
1503
+ self.assertEqual(a.inst.isSegmentDefault, False)
1504
+ else:
1505
+ self.assertEqual(a.inst.isSegmentDefault, True)
1506
+ def test_default_seg32(self):
1507
+ self.assertEqual(I32("mov [ds:0x12345678], eax").inst.segment, Regs.DS)
1508
+ self.assertEqual(I32("mov [cs:0x12345678], eax").inst.segment, Regs.CS)
1509
+ texts = ["ADD [ds:%s], EAX" % i for i in self.Derefs32]
1510
+ for i in enumerate(texts):
1511
+ a = I32(i[1])
1512
+ self.assertEqual(a.inst.segment, Regs.DS)
1513
+ if self.Derefs32[i[0]] == "EBP":
1514
+ self.assertEqual(a.inst.isSegmentDefault, False)
1515
+ else:
1516
+ self.assertEqual(a.inst.isSegmentDefault, True)
1517
+ # Test with disp8
1518
+ texts = ["ADD [ds:%s + 0x55], EAX" % i for i in self.Derefs32]
1519
+ for i in enumerate(texts):
1520
+ a = I32(i[1])
1521
+ self.assertEqual(a.inst.segment, Regs.DS)
1522
+ if self.Derefs32[i[0]] == "EBP":
1523
+ self.assertEqual(a.inst.isSegmentDefault, False)
1524
+ else:
1525
+ self.assertEqual(a.inst.isSegmentDefault, True)
1526
+ def test_sib(self):
1527
+ for i in enumerate(self.Derefs32):
1528
+ for j in enumerate(self.Bases):
1529
+ for s in [1, 2, 4, 8]:
1530
+ a = I32("cmp ebp, [ds:%s*%d + %s]" % (i[1], s, j[1]))
1531
+ a2 = I32("cmp ebp, [ds:%s*%d + %s + 0x55]" % (i[1], s, j[1]))
1532
+ self.assertEqual(a.inst.segment, Regs.DS)
1533
+ self.assertEqual(a2.inst.segment, Regs.DS)
1534
+ if (j[1] == "EBP" or j[1] == "ESP"):
1535
+ self.assertEqual(a.inst.isSegmentDefault, False)
1536
+ self.assertEqual(a2.inst.isSegmentDefault, False)
1537
+ else:
1538
+ self.assertEqual(a.inst.isSegmentDefault, True)
1539
+ self.assertEqual(a2.inst.isSegmentDefault, True)
1540
+
1541
+ def test_seg64(self):
1542
+ self.assertEqual(I64("mov [gs:rip+0x12345678], eax").inst.segment, Regs.GS)
1543
+ self.assertEqual(I64("mov [fs:0x12345678], eax").inst.segment, Regs.FS)
1544
+ def test_lock(self):
1545
+ self.failIf("FLAG_LOCK" not in I32("lock inc dword [eax]").inst.flags)
1546
+ def test_repnz(self):
1547
+ self.failIf("FLAG_REPNZ" not in I32("repnz scasb").inst.flags)
1548
+ def test_rep(self):
1549
+ self.failIf("FLAG_REP" not in I32("rep movsb").inst.flags)
1550
+ def test_segment_override(self):
1551
+ self.assertEqual(I32("mov eax, [cs:eax]").inst.segment, Regs.CS)
1552
+ self.assertEqual(I32("mov eax, [ds:eax]").inst.segment, Regs.DS)
1553
+ self.assertEqual(I32("mov eax, [es:eax]").inst.segment, Regs.ES)
1554
+ self.assertEqual(I32("mov eax, [ss:eax]").inst.segment, Regs.SS)
1555
+ self.assertEqual(I32("mov eax, [fs:eax]").inst.segment, Regs.FS)
1556
+ self.assertEqual(I32("mov eax, [gs:eax]").inst.segment, Regs.GS)
1557
+ def test_unused_normal(self):
1558
+ self.assertEqual(IB64("4090").inst.unusedPrefixesMask, 1)
1559
+ self.assertEqual(IB64("6790").inst.unusedPrefixesMask, 1)
1560
+ self.assertEqual(IB64("6690").inst.unusedPrefixesMask, 1)
1561
+ self.assertEqual(IB64("f290").inst.unusedPrefixesMask, 1)
1562
+ self.assertEqual(IB64("f090").inst.unusedPrefixesMask, 1)
1563
+ self.assertEqual(IB64("f3c3").inst.unusedPrefixesMask, 1)
1564
+ self.assertEqual(IB64("64c3").inst.unusedPrefixesMask, 1)
1565
+ def test_unused_doubles(self):
1566
+ self.assertEqual(IB64("404090").inst.unusedPrefixesMask, 3)
1567
+ self.assertEqual(IB64("676790").inst.unusedPrefixesMask, 3)
1568
+ self.assertEqual(IB64("666690").inst.unusedPrefixesMask, 3)
1569
+ self.assertEqual(IB64("f2f290").inst.unusedPrefixesMask, 3)
1570
+ self.assertEqual(IB64("f0f090").inst.unusedPrefixesMask, 3)
1571
+ self.assertEqual(IB64("f3f3c3").inst.unusedPrefixesMask, 3)
1572
+ self.assertEqual(IB64("642ec3").inst.unusedPrefixesMask, 3)
1573
+ def test_unused_sequences(self):
1574
+ self.assertEqual(len(IB64("66"*15).insts), 15)
1575
+ r = int(random.random() * 14)
1576
+ self.assertEqual(IB64("66"*r + "90").inst.unusedPrefixesMask, (1 << r) - 1)
1577
+ def test_rexw_66(self):
1578
+ self.assertEqual(IB64("6648ffc0").inst.unusedPrefixesMask, 1)
1579
+ self.assertEqual(IB64("6640ffc0").inst.unusedPrefixesMask, 2)
1580
+ self.assertEqual(IB64("48660f10c0").inst.unusedPrefixesMask, 1)
1581
+ self.assertEqual(IB64("664f0f10c0").inst.unusedPrefixesMask, 0)
1582
+
1583
+ class TestInvalid(unittest.TestCase):
1584
+ def align(self):
1585
+ for i in xrange(15):
1586
+ IB32("90")
1587
+ def test_filter_mem(self):
1588
+ #cmpxchg8b eax
1589
+ IB32("0fc7c8")
1590
+ self.align()
1591
+ def test_drop_prefixes(self):
1592
+ # Drop prefixes when we encountered an instruction that couldn't be decoded.
1593
+ IB32("666764ffff")
1594
+ self.align()
1595
+ def test_zzz_must_be_last_drop_prefixes(self):
1596
+ # Drop prefixes when the last byte in stream is a prefix.
1597
+ IB32("66")
1598
+
1599
+ class FlowControl:
1600
+ """ The flow control instruction will be flagged in the lo nibble of the 'meta' field in _InstInfo of diStorm.
1601
+ They are used to distinguish between flow control instructions (such as: ret, call, jmp, jz, etc) to normal ones. """
1602
+ (CALL,
1603
+ RET,
1604
+ SYS,
1605
+ BRANCH,
1606
+ COND_BRANCH,
1607
+ INT) = range(1, 7)
1608
+
1609
+ DF_MAXIMUM_ADDR16 = 1
1610
+ DF_MAXIMUM_ADDR32 = 2
1611
+ DF_RETURN_FC_ONLY = 4
1612
+ DF_STOP_ON_CALL = 8
1613
+ DF_STOP_ON_RET = 0x10
1614
+ DF_STOP_ON_SYS = 0x20
1615
+ DF_STOP_ON_BRANCH = 0x40
1616
+ DF_STOP_ON_COND_BRANCH = 0x80
1617
+ DF_STOP_ON_INT = 0x100
1618
+ DF_STOP_ON_FLOW_CONTROL = (DF_STOP_ON_CALL | DF_STOP_ON_RET | DF_STOP_ON_SYS | DF_STOP_ON_BRANCH | DF_STOP_ON_COND_BRANCH | DF_STOP_ON_INT)
1619
+
1620
+ class TestFeatures(unittest.TestCase):
1621
+ def test_addr16(self):
1622
+ #I16("mov [-4], bx", 0, DF_MAXIMUM_ADDR16).check_disp(0, 0xfffc, 16, 16)
1623
+ pass
1624
+ def test_add32(self):
1625
+ pass
1626
+ def test_fc(self):
1627
+ pairs = [
1628
+ (["INT 5", "db 0xf1", "INT 3", "INTO", "UD2"], FlowControl.INT),
1629
+ (["CALL 0x50", "CALL FAR [ebx]"], FlowControl.CALL),
1630
+ (["RET", "IRET", "RETF"], FlowControl.RET),
1631
+ (["SYSCALL", "SYSENTER", "SYSRET", "SYSEXIT"], FlowControl.SYS),
1632
+ (["JMP 0x50", "JMP FAR [ebx]"], FlowControl.BRANCH),
1633
+ (["JCXZ 0x50", "JO 0x50", "JNO 0x50", "JB 0x50", "JAE 0x50",
1634
+ "JZ 0x50", "JNZ 0x50", "JBE 0x50", "JA 0x50", "JS 0x50",
1635
+ "JNS 0x50", "JP 0x50", "JNP 0x50", "JL 0x50", "JGE 0x50",
1636
+ "JLE 0x50", "JG 0x50", "LOOP 0x50", "LOOPZ 0x50", "LOOPNZ 0x50"], FlowControl.COND_BRANCH)
1637
+ ]
1638
+ for i in pairs:
1639
+ for j in i[0]:
1640
+ a = I32(j + "\nnop", DF_STOP_ON_FLOW_CONTROL)
1641
+ self.assertEqual(len(a.insts), 1)
1642
+ self.assertEqual(a.inst["meta"] & 7, i[1])
1643
+ a = I32("push eax\nnop\n" + j, DF_RETURN_FC_ONLY)
1644
+ self.assertEqual(len(a.insts), 1)
1645
+ a = I32("nop\nxor eax, eax\n" + j + "\ninc eax", DF_RETURN_FC_ONLY | DF_STOP_ON_FLOW_CONTROL)
1646
+ self.assertEqual(len(a.insts), 1)
1647
+ def test_filter(self):
1648
+ pass
1649
+
1650
+ def GetNewSuite(className):
1651
+ suite = unittest.TestSuite()
1652
+ suite.addTest(unittest.makeSuite(className))
1653
+ return suite
1654
+
1655
+ def initfiles():
1656
+ for i in ["bin16", "bin32", "bin64"]:
1657
+ fbin.append(open("build\\linux\\"+i, "wb"))
1658
+
1659
+ if __name__ == "__main__":
1660
+ random.seed()
1661
+ #initfiles() # Used to emit the bytes of the tests - useful for code coverage input.
1662
+ suite = unittest.TestSuite()
1663
+ suite.addTest(GetNewSuite(TestMode16))
1664
+ suite.addTest(GetNewSuite(TestMode32))
1665
+ suite.addTest(GetNewSuite(TestMode64))
1666
+ suite.addTest(GetNewSuite(TestInstTable))
1667
+ suite.addTest(GetNewSuite(TestAVXOperands))
1668
+ suite.addTest(GetNewSuite(TestMisc))
1669
+ suite.addTest(GetNewSuite(TestPrefixes))
1670
+ #suite.addTest(GetNewSuite(TestInvalid))
1671
+ #suite.addTest(GetNewSuite(TestFeatures))
1672
+ unittest.TextTestRunner(verbosity=1).run(suite)