contrast-agent 3.8.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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,59 @@
1
+ AC_INIT([funchook], [0.1])
2
+
3
+ AC_PROG_CC
4
+ AC_GNU_SOURCE
5
+ AC_CANONICAL_HOST
6
+
7
+ if test "$GCC"; then
8
+ CFLAGS="$CFLAGS -Wall -fvisibility=hidden"
9
+ fi
10
+
11
+ AC_CHECK_SIZEOF(void*)
12
+ if test "$ac_cv_sizeof_voidp" = 4; then
13
+ FUNCHOOK_CPU=x86
14
+ else
15
+ FUNCHOOK_CPU=x86_64
16
+ fi
17
+ AC_SUBST(FUNCHOOK_CPU)
18
+
19
+ IF_WIN32='#'
20
+ IF_LINUX='#'
21
+ IF_OSX='#'
22
+
23
+ if test "$EXEEXT"; then
24
+ FUNCHOOK_OS=windows
25
+ LIBFUNCHOOK_SO=funchook.dll
26
+ CFLAGS="$CFLAGS -DFUNCHOOK_EXPORTS"
27
+ LINK_SHARED="\$(CC) -shared -Wl,--out-implib,funchook.lib"
28
+ IF_WIN32=
29
+ else
30
+ FUNCHOOK_OS=unix
31
+ PIC_CFLAGS="-fPIC"
32
+ LINK_SHARED="\$(CC) -shared"
33
+ case "$host_os" in
34
+ linux*)
35
+ LIBFUNCHOOK_SO=libfunchook.so
36
+ LIBS="-ldl"
37
+ IF_LINUX=
38
+ ;;
39
+ darwin*)
40
+ LIBFUNCHOOK_SO=libfunchook.dylib
41
+ IF_OSX=
42
+ ;;
43
+ esac
44
+ fi
45
+
46
+ AC_CHECK_DECLS([_sys_nerr, _sys_errlist, sys_nerr, sys_errlist])
47
+
48
+ AC_SUBST(FUNCHOOK_OS)
49
+ AC_SUBST(LIBFUNCHOOK_SO)
50
+ AC_SUBST(LINK_SHARED)
51
+ AC_SUBST(PIC_CFLAGS)
52
+ AC_SUBST(IF_WIN32)
53
+ AC_SUBST(IF_LINUX)
54
+ AC_SUBST(IF_OSX)
55
+
56
+ AC_CONFIG_HEADERS([src/config.h])
57
+
58
+ AC_CONFIG_FILES([Makefile src/Makefile test/Makefile])
59
+ AC_OUTPUT
@@ -0,0 +1,26 @@
1
+ :[diStorm3}:
2
+ The ultimate disassembler library.
3
+ Copyright (c) 2003-2016, Gil Dabah
4
+ All rights reserved.
5
+
6
+ Redistribution and use in source and binary forms, with or without
7
+ modification, are permitted provided that the following conditions are met:
8
+ * Redistributions of source code must retain the above copyright
9
+ notice, this list of conditions and the following disclaimer.
10
+ * Redistributions in binary form must reproduce the above copyright
11
+ notice, this list of conditions and the following disclaimer in the
12
+ documentation and/or other materials provided with the distribution.
13
+ * Neither the name of the Gil Dabah nor the
14
+ names of its contributors may be used to endorse or promote products
15
+ derived from this software without specific prior written permission.
16
+
17
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
18
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20
+ DISCLAIMED. IN NO EVENT SHALL GIL DABAH BE LIABLE FOR ANY
21
+ DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24
+ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,25 @@
1
+ COPYING
2
+ setup.cfg
3
+ setup.py
4
+ include\distorm.h
5
+ include\mnemonics.h
6
+ python\distorm3\__init__.py
7
+ python\distorm3\sample.py
8
+ src\config.h
9
+ src\decoder.c
10
+ src\decoder.h
11
+ src\distorm.c
12
+ src\instructions.c
13
+ src\instructions.h
14
+ src\insts.c
15
+ src\insts.h
16
+ src\mnemonics.c
17
+ src\operands.c
18
+ src\operands.h
19
+ src\prefix.c
20
+ src\prefix.h
21
+ src\textdefs.c
22
+ src\textdefs.h
23
+ src\wstring.c
24
+ src\wstring.h
25
+ src\x86defs.h
@@ -0,0 +1,4 @@
1
+ include COPYING setup.cfg setup.py
2
+ recursive-include src *.c *.h
3
+ recursive-include include *.c *.h
4
+ recursive-include . *.py
@@ -0,0 +1,12 @@
1
+ Powerful Disassembler Library For x86/AMD64
2
+ -----------
3
+
4
+ Welcome to the diStorm3 binary stream disassembler library project.
5
+
6
+ diStorm3 is really a decomposer, which means it takes an instruction and returns a binary structure which describes it rather than static text, which is great for advanced binary code analysis.
7
+
8
+ diStorm3 is super lightweight (~45KB), ultra fast and easy to use (a single API)!
9
+
10
+ "We benchmarked five popular open-source disassembly libraries and chose diStorm3, which had the best performance (and furthermore, has complete 64-bit support).", July 2014, Quoting David Williams-King in his Thesis about Binary Shuffling.
11
+
12
+ diStorm3.3.3 is now licensed under BSD!
@@ -0,0 +1,795 @@
1
+ #
2
+ # disOps.py v 1.0.0
3
+ #
4
+ # Copyright (C) 2003-2012 Gil Dabah, http://ragestorm.net/distorm/
5
+ #
6
+ # disOps is a part of the diStorm project, but can be used for anything.
7
+ # The generated output is tightly coupled with diStorm data structures which can be found at instructions.h.
8
+ # The code in diStorm that actually walks these structures is found at instructions.c.
9
+ #
10
+ # Since the DB was built purposely for diStorm, there are some
11
+ # Known issues:
12
+ # 1. ARPL/MOVSXD information in DB is stored as ARPL.
13
+ # Since ARPL and MOVSXD share the same opcode this DB doesn't support this mix.
14
+ # Therefore, if you use this DB for x64 instructions, you have to take care of this one.
15
+ #
16
+ # 2. SSE CMP pseudo instructions have the DEFAULT suffix letters of its type in the second mnemonic,
17
+ # the third operand, Imm8 which is responsible for determining the suffix,
18
+ # doesn't appear in the operands list but rather an InstFlag.PSEUDO_OPCODE implies this behavior.
19
+ #
20
+ # 3. The WAIT instruction is a bit problematic from a static DB point of view, read the comments in init_FPU in x86sets.py.
21
+ #
22
+ # 4. The OpLen.OL_33, [0x66, 0x0f, 0x78, 0x0], ["EXTRQ"] is very problematic as well.
23
+ # Since there's another 8 group table after the 0x78 byte in this case, but it's already a Prefixed table.
24
+ # Therefore, we will handle it as a normal 0x78 instruction with a mandatory prefix of 0x66.
25
+ # But the REG (=0) field of the ModRM byte will be checked in the decoder by a flag that states so.
26
+ # Otherwise, another normal table after Prefixed table really complicates matters,
27
+ # and doesn't worth the hassle for one exceptional instruction.
28
+ #
29
+ # 5. The NOP (0x90) instruction is really set in the DB as xchg rAX, rAX. Rather than true NOP, this is because of x64 behavior.
30
+ # Hence, it will be decided in runtime when decoding streams according to the mode.
31
+ #
32
+ # 6. The PAUSE (0xf3, 0x90) instruction isn't found in the DB, it will be returned directly by diStorm.
33
+ # This is because the 0xf3 in this case is not a mandatory prefix, and we don't want it to be built as part of a prefixed table.
34
+ #
35
+ # 7. The IO String instructions don't have explicit form and they don't support segments.
36
+ # It's up to diStorm to decide what to do with the operands and which segment is default and overrided.
37
+ #
38
+ # 8. Since opcodeId is an offset into the mnemonics table, the psuedo compare mnemonics needs a helper table to fix the offset.
39
+ # Psuedo compare instructions work in such a way that only the first instruction is defined in the DB.
40
+ # The rest are found using the third operand (that's why they are psuedo).
41
+ #
42
+ # To maximize the usage of this DB, one should learn the documentation of diStorm regarding the InstFlag and Operands Types.
43
+ #
44
+
45
+ import time
46
+
47
+ import x86sets
48
+ import x86db
49
+ from x86header import *
50
+
51
+ mnemonicsIds = {} # mnemonic : offset to mnemonics table of strings.
52
+ idsCounter = len("undefined") + 2 # Starts immediately after this one.
53
+
54
+ SSECmpTypes = ["EQ", "LT", "LE", "UNORD", "NEQ", "NLT", "NLE", "ORD"]
55
+ AVXCmpTypes = ["EQ", "LT", "LE", "UNORD", "NEQ", "NLT", "NLE", "ORD",
56
+ "EQ_UQ", "NGE", "NGT", "FALSE", "NEQ_OQ", "GE", "GT", "TRUE",
57
+ "EQ_OS", "LT_OQ", "LE_OQ", "UNORD_S", "NEQ_US", "NLT_UQ", "NLE_UQ", "ORD_S",
58
+ "EQ_US", "NGE_UQ", "NGT_UQ", "FALSE_OS", "NEQ_OS", "GE_OQ", "GT_OQ", "TRUE_US"]
59
+
60
+ # Support SSE pseudo compare instructions. We will have to add them manually.
61
+ def FixPseudo(mnems):
62
+ return [mnems[0] + i + mnems[1] for i in SSECmpTypes]
63
+
64
+ # Support AVX pseudo compare instructions. We will have to add them manually.
65
+ def FixPseudo2(mnems):
66
+ return [mnems[0] + i + mnems[1] for i in AVXCmpTypes]
67
+
68
+ def TranslateMnemonics(pseudoClassType, mnems):
69
+ global mnemonicsIds
70
+ global idsCounter
71
+ l = []
72
+ if pseudoClassType == ISetClass.SSE or pseudoClassType == ISetClass.SSE2:
73
+ mnems = FixPseudo(mnems)
74
+ elif pseudoClassType == ISetClass.AVX:
75
+ mnems = FixPseudo2(mnems)
76
+ for i in mnems:
77
+ if len(i) == 0:
78
+ # Some mnemonics are empty on purpose because they're not used.
79
+ # Set them to zero to keep the order of the list.
80
+ l.append(0) # Undefined instruction.
81
+ continue
82
+ if mnemonicsIds.has_key(i):
83
+ l.append(mnemonicsIds[i])
84
+ else:
85
+ mnemonicsIds[i] = idsCounter
86
+ l.append(idsCounter)
87
+ idsCounter += len(i) + 2 # For len/null chars.
88
+ if idsCounter >= 2**16:
89
+ raise "opcodeId is too big to fit into uint16_t"
90
+ return l
91
+
92
+ # All VIAL and diStorm3 code are based on the order of this list, do NOT edit!
93
+ REGISTERS = [
94
+ "RAX", "RCX", "RDX", "RBX", "RSP", "RBP", "RSI", "RDI", "R8", "R9", "R10", "R11", "R12", "R13", "R14", "R15", "XX",
95
+ "EAX", "ECX", "EDX", "EBX", "ESP", "EBP", "ESI", "EDI", "R8D", "R9D", "R10D", "R11D", "R12D", "R13D", "R14D", "R15D", "XX",
96
+ "AX", "CX", "DX", "BX", "SP", "BP", "SI", "DI", "R8W", "R9W", "R10W", "R11W", "R12W", "R13W", "R14W", "R15W", "XX",
97
+ "AL", "CL", "DL", "BL", "AH", "CH", "DH", "BH", "R8B", "R9B", "R10B", "R11B", "R12B", "R13B", "R14B", "R15B", "XX",
98
+ "SPL", "BPL", "SIL", "DIL", "XX",
99
+ "ES", "CS", "SS", "DS", "FS", "GS", "XX",
100
+ "RIP", "XX",
101
+ "ST0", "ST1", "ST2", "ST3", "ST4", "ST5", "ST6", "ST7", "XX",
102
+ "MM0", "MM1", "MM2", "MM3", "MM4", "MM5", "MM6", "MM7", "XX",
103
+ "XMM0", "XMM1", "XMM2", "XMM3", "XMM4", "XMM5", "XMM6", "XMM7", "XMM8", "XMM9", "XMM10", "XMM11", "XMM12", "XMM13", "XMM14", "XMM15", "XX",
104
+ "YMM0", "YMM1", "YMM2", "YMM3", "YMM4", "YMM5", "YMM6", "YMM7", "YMM8", "YMM9", "YMM10", "YMM11", "YMM12", "YMM13", "YMM14", "YMM15", "XX",
105
+ "CR0", "", "CR2", "CR3", "CR4", "", "", "", "CR8", "XX",
106
+ "DR0", "DR1", "DR2", "DR3", "", "", "DR6", "DR7"]
107
+
108
+ def CreatePythonDict(mnemonicsIds):
109
+ """ Create the opcodes dictionary for Python. """
110
+ s = "\n"
111
+ for i in mnemonicsIds:
112
+ s += "0x%x: \"%s\", " % (mnemonicsIds[i], i)
113
+ if len(s) - s.rfind("\n") >= 76:
114
+ s = s[:-1] + "\n"
115
+ open("python_output.txt", "w").write(s)
116
+
117
+ def CreateJavaDict(mnemonicsIds):
118
+ """ Create the opcodes dictionary/enum for Java. """
119
+ s = "\nmOpcodes.put(0, OpcodeEnum.UNDEFINED);\n"
120
+ for i in mnemonicsIds:
121
+ s += "mOpcodes.put(0x%x, OpcodeEnum.%s);\n" % (mnemonicsIds[i], i.replace(" ", "_").replace(",", ""))
122
+ open("java_enums.txt", "w").write(s)
123
+
124
+ s = "\nUNDEFINED, "
125
+ for i in mnemonicsIds:
126
+ s += "%s, " % (i.replace(" ", "_").replace(",", ""))
127
+ if len(s) - s.rfind("\n") >= 76:
128
+ s = s[:-1] + "\n"
129
+ open("java_mnemonics.txt", "w").write(s)
130
+
131
+ def DumpMnemonics():
132
+ global mnemonicsIds
133
+
134
+ f = open("defs.txt", "w")
135
+
136
+ f.write("typedef enum {\n\tI_UNDEFINED = 0, ")
137
+ pos = 0
138
+ l2 = sorted(mnemonicsIds.keys())
139
+ for i in l2:
140
+ s = "I_%s = %d" % (i.replace(" ", "_").replace(",", ""), mnemonicsIds[i])
141
+ if i != l2[-1]:
142
+ s += ","
143
+ pos += len(s)
144
+ if pos >= 70:
145
+ s += "\n\t"
146
+ pos = 0
147
+ elif i != l2[-1]:
148
+ s += " "
149
+ f.write(s)
150
+ f.write("\n} _InstructionType;\n\n")
151
+
152
+ regsText = "const _WRegister _REGISTERS[] = {\n\t"
153
+ regsEnum = "typedef enum {\n\t"
154
+ old = "*"
155
+ unused = 0
156
+ for i in REGISTERS:
157
+ if old != "*":
158
+ if old == "XX":
159
+ regsText += "\n\t"
160
+ regsEnum += "\n\t"
161
+ old = i
162
+ continue
163
+ else:
164
+ regsText += "{%d, \"%s\"}," % (len(old), old)
165
+ if len(old):
166
+ regsEnum += "R_%s," % old
167
+ else:
168
+ regsEnum += "R_UNUSED%d," % unused
169
+ unused += 1
170
+ if i != "XX":
171
+ regsText += " "
172
+ regsEnum += " "
173
+ old = i
174
+ regsText += "{%d, \"%s\"}\n};\n" % (len(old), old)
175
+ regsEnum += "R_" + old + "\n} _RegisterType;\n"
176
+
177
+ f.write(regsEnum + "\n")
178
+
179
+ # Mnemonics are sorted by insertion order. (Psuedo mnemonics depend on this!)
180
+ s = "const unsigned char _MNEMONICS[] =\n\"\\x09\" \"UNDEFINED\\0\" "
181
+ l = zip(mnemonicsIds.keys(), mnemonicsIds.values())
182
+ l.sort(lambda x, y: x[1] - y[1])
183
+ for i in l:
184
+ s += "\"\\x%02x\" \"%s\\0\" " % (len(i[0]), i[0])
185
+ if len(s) - s.rfind("\n") >= 76:
186
+ s += "\\\n"
187
+ s = s[:-1] + ";\n\n" # Ignore last space.
188
+ f.write(s)
189
+
190
+ f.write(regsText + "\n")
191
+ f.close()
192
+
193
+ # Used for Python/Java dictionary of opcodeIds-->mnemonics.
194
+ CreatePythonDict(mnemonicsIds)
195
+ CreateJavaDict(mnemonicsIds)
196
+
197
+ O_NONE = 0
198
+ # REG standalone
199
+ O_REG = 1
200
+ # IMM standalone
201
+ O_IMM = 2
202
+ # IMM_1 standalone
203
+ O_IMM_1 = 4
204
+ # IMM_2 standalone
205
+ O_IMM_2 = 5
206
+ # DISP standlone
207
+ O_DISP = 3
208
+ # MEM uses DISP
209
+ O_MEM = 3
210
+ # PC uses IMM
211
+ O_PC = 2
212
+ # PTR uses IMM
213
+ O_PTR = 2
214
+
215
+ _OPT2T = {OperandType.NONE : O_NONE,
216
+ OperandType.IMM8 : O_IMM,
217
+ OperandType.IMM16 : O_IMM,
218
+ OperandType.IMM_FULL : O_IMM,
219
+ OperandType.IMM32 : O_IMM,
220
+ OperandType.SEIMM8 : O_IMM,
221
+ OperandType.IMM16_1 : O_IMM_1,
222
+ OperandType.IMM8_1 : O_IMM_1,
223
+ OperandType.IMM8_2 : O_IMM_2,
224
+ OperandType.REG8 : O_REG,
225
+ OperandType.REG16 : O_REG,
226
+ OperandType.REG_FULL : O_REG,
227
+ OperandType.REG32 : O_REG,
228
+ OperandType.REG32_64 : O_REG,
229
+ OperandType.FREG32_64_RM : O_REG,
230
+ OperandType.RM8 : O_MEM,
231
+ OperandType.RM16 : O_MEM,
232
+ OperandType.RM_FULL : O_MEM,
233
+ OperandType.RM32_64 : O_MEM,
234
+ OperandType.RM16_32 : O_MEM,
235
+ OperandType.FPUM16 : O_MEM,
236
+ OperandType.FPUM32 : O_MEM,
237
+ OperandType.FPUM64 : O_MEM,
238
+ OperandType.FPUM80 : O_MEM,
239
+ OperandType.R32_M8 : O_MEM,
240
+ OperandType.R32_M16 : O_MEM,
241
+ OperandType.R32_64_M8 : O_MEM,
242
+ OperandType.R32_64_M16 : O_MEM,
243
+ OperandType.RFULL_M16 : O_MEM,
244
+ OperandType.CREG : O_REG,
245
+ OperandType.DREG : O_REG,
246
+ OperandType.SREG : O_REG,
247
+ OperandType.SEG : O_REG,
248
+ OperandType.ACC8 : O_REG,
249
+ OperandType.ACC16 : O_REG,
250
+ OperandType.ACC_FULL : O_REG,
251
+ OperandType.ACC_FULL_NOT64 : O_REG,
252
+ OperandType.MEM16_FULL : O_MEM,
253
+ OperandType.PTR16_FULL : O_PTR,
254
+ OperandType.MEM16_3264 : O_MEM,
255
+ OperandType.RELCB : O_PC,
256
+ OperandType.RELC_FULL : O_PC,
257
+ OperandType.MEM : O_MEM,
258
+ OperandType.MEM_OPT : O_MEM,
259
+ OperandType.MEM32 : O_MEM,
260
+ OperandType.MEM32_64 : O_MEM,
261
+ OperandType.MEM64 : O_MEM,
262
+ OperandType.MEM128 : O_MEM,
263
+ OperandType.MEM64_128 : O_MEM,
264
+ OperandType.MOFFS8 : O_MEM,
265
+ OperandType.MOFFS_FULL : O_MEM,
266
+ OperandType.CONST1 : O_IMM,
267
+ OperandType.REGCL : O_REG,
268
+ OperandType.IB_RB : O_REG,
269
+ OperandType.IB_R_FULL : O_REG,
270
+ OperandType.REGI_ESI : O_MEM,
271
+ OperandType.REGI_EDI : O_MEM,
272
+ OperandType.REGI_EBXAL : O_MEM,
273
+ OperandType.REGI_EAX : O_MEM,
274
+ OperandType.REGDX : O_REG,
275
+ OperandType.REGECX : O_REG,
276
+ OperandType.FPU_SI : O_REG,
277
+ OperandType.FPU_SSI : O_REG,
278
+ OperandType.FPU_SIS : O_REG,
279
+ OperandType.MM : O_REG,
280
+ OperandType.MM_RM : O_REG,
281
+ OperandType.MM32 : O_MEM,
282
+ OperandType.MM64 : O_MEM,
283
+ OperandType.XMM : O_REG,
284
+ OperandType.XMM_RM : O_REG,
285
+ OperandType.XMM16 : O_MEM,
286
+ OperandType.XMM32 : O_MEM,
287
+ OperandType.XMM64 : O_MEM,
288
+ OperandType.XMM128 : O_MEM,
289
+ OperandType.REGXMM0 : O_REG,
290
+ OperandType.RM32 : O_MEM,
291
+ OperandType.REG32_64_M8 : O_MEM,
292
+ OperandType.REG32_64_M16 : O_MEM,
293
+ OperandType.WREG32_64 : O_REG,
294
+ OperandType.WRM32_64 : O_REG,
295
+ OperandType.WXMM32_64 : O_MEM,
296
+ OperandType.VXMM : O_REG,
297
+ OperandType.XMM_IMM : O_IMM,
298
+ OperandType.YXMM : O_REG,
299
+ OperandType.YXMM_IMM : O_REG,
300
+ OperandType.YMM : O_REG,
301
+ OperandType.YMM256 : O_MEM,
302
+ OperandType.VYMM : O_REG,
303
+ OperandType.VYXMM : O_REG,
304
+ OperandType.YXMM64_256 : O_MEM,
305
+ OperandType.YXMM128_256 : O_MEM,
306
+ OperandType.LXMM64_128 : O_MEM,
307
+ OperandType.LMEM128_256 : O_MEM
308
+ }
309
+
310
+ def CheckOTCollisions(ii):
311
+ """ Checks whether an instruction has two or more operands that use the same fields in the diStorm3 structure.
312
+ E.G: ENTER 0x10, 0x1 --> This instruction uses two OT_IMM, which will cause a collision and use the same field twice which is bougs. """
313
+ types = map(lambda x: _OPT2T[x], ii.operands)
314
+ # Regs cannot cause a collision, since each register is stored inside the operand itself.
315
+ for i in types:
316
+ if i != O_REG and types.count(i) > 1:
317
+ print "**WARNING: Operand type collision for instruction: " + ii.mnemonics[0], ii.tag
318
+ break
319
+
320
+ # This fucntion for certain flow control related instructions will set their type.
321
+ def UpdateForFlowControl(ii):
322
+ if ii.mnemonics[0].find("CMOV") == 0:
323
+ ii.flowControl = FlowControl.CMOV
324
+ return
325
+
326
+ # Should I include SYSCALL ?
327
+ pairs = [
328
+ (["INT", "INT1", "INT 3", "INTO", "UD2"], FlowControl.INT),
329
+ (["CALL", "CALL FAR"], FlowControl.CALL),
330
+ (["RET", "IRET", "RETF"], FlowControl.RET),
331
+ (["SYSCALL", "SYSENTER", "SYSRET", "SYSEXIT"], FlowControl.SYS),
332
+ (["JMP", "JMP FAR"], FlowControl.UNC_BRANCH),
333
+ (["JCXZ", "JO", "JNO", "JB", "JAE", "JZ", "JNZ", "JBE", "JA", "JS", "JNS", "JP", "JNP", "JL", "JGE", "JLE", "JG", "LOOP", "LOOPZ", "LOOPNZ"], FlowControl.CND_BRANCH)
334
+ ]
335
+ ii.flowControl = 0
336
+ for p in pairs:
337
+ if ii.mnemonics[0] in p[0]:
338
+ ii.flowControl = p[1]
339
+ return
340
+
341
+ def UpdateWritableDestinationOperand(ii):
342
+ " Mark dst-wrt flag for all Integer instructions that write to GPR/mem. "
343
+ prefixes = ["MOV", "SET", "CMOV", "CMPXCHG"]
344
+ for i in prefixes:
345
+ if ii.mnemonics[0].find(i) == 0:
346
+ ii.flags |= InstFlag.DST_WR
347
+ return
348
+
349
+ mnemonics = [
350
+ "ADD", "OR", "ADC", "SBB", "AND", "SUB", "XOR", "INC", "DEC", "LEA", "XCHG",
351
+ "ROL", "ROR", "RCL", "RCR", "SHL", "SHR", "SAL", "SAR", "SHLD", "SHRD",
352
+ "NEG", "NOT", "MUL", "IMUL", "DIV", "IDIV",
353
+ "POP", "BTR", "BTS", "BTC", "XADD", "BSWAP",
354
+ "LZCNT", "MOVBE", "POPCNT", "CRC32", "SMSW"
355
+ ]
356
+ for i in mnemonics:
357
+ if ii.mnemonics[0] in i:
358
+ ii.flags |= InstFlag.DST_WR
359
+ return
360
+
361
+ # Make sure it's an FPU instruction before we continue.
362
+ if ii.classType != ISetClass.FPU:
363
+ return
364
+ fpu_mnemonics = [
365
+ "FSTENV", "FSTCW", "FSAVE", "FSTSW", "FST", "FSTP", "FNSTENV", "FNSTCW",
366
+ "FIST", "FISTP", "FNSAVE", "FBSTP", "FNSTSW"
367
+ ]
368
+ for i in fpu_mnemonics:
369
+ if ii.mnemonics[0] in i:
370
+ if len(ii.operands) > 0:
371
+ # Ignore operands of FPU STi.
372
+ if ii.operands[0] not in [OperandType.FPU_SI, OperandType.FPU_SSI, OperandType.FPU_SIS]:
373
+ ii.flags |= InstFlag.DST_WR
374
+ return
375
+
376
+ def UpdatePrivilegedInstruction(opcodeIds, ii):
377
+ """ Checks whether a given mnemonic from the given list is privileged,
378
+ and changes the relevant opcodeId to indicate so.
379
+ Most significant bit of the OpcodeId is the indicator. """
380
+
381
+ def IsPrivilegedMov(ii):
382
+ " Check for MOV instruction with Debug/Control registers which is privileged. "
383
+ return (ii.mnemonics[0] == "MOV") and ((OperandType.CREG in ii.operands) or (OperandType.DREG in ii.operands))
384
+
385
+ privileged = [
386
+ "LGDT", "LLDT", "LTR", "LIDT", "LMSW", "CLTS", "INVD",
387
+ "WBINVD", "INVLPG", "HLT", "RDMSR", "WRMSR", "RDPMC", "RDTSC",
388
+ # IO Sensitive Instructions, mostly allowed by ring0 only.
389
+ "IN", "INS", "OUT", "OUTS", "CLI", "STI", "IRET"
390
+ ]
391
+ for i in enumerate(ii.mnemonics):
392
+ if (i[1] in privileged) or IsPrivilegedMov(ii):
393
+ opcodeIds[i[0]] |= 0x8000
394
+
395
+ def SetInstructionAffectedFlags(ii, flagsTuple):
396
+ """ Helper routine to set the m/t/u flags for an instruction info. """
397
+ # Pad tuple for fast access.
398
+ if not isinstance(flagsTuple, type(())):
399
+ flagsTuple = (flagsTuple,)
400
+ flagsTuple += (0,) * (3 - len(flagsTuple))
401
+ ii.modifiedFlags = flagsTuple[0]
402
+ ii.testedFlags = flagsTuple[1]
403
+ ii.undefinedFlags = flagsTuple[2]
404
+
405
+ def GetTestedFlagsForCondition(cond):
406
+ OF, SF, ZF, AF, PF, CF, IF, DF = CPUFlags.OF, CPUFlags.SF, CPUFlags.ZF, CPUFlags.AF, CPUFlags.PF, CPUFlags.CF, CPUFlags.IF, CPUFlags.DF
407
+ Conditions = {
408
+ "O": OF,
409
+ "NO": OF,
410
+ "B": CF,
411
+ "AE": CF,
412
+ "Z": ZF,
413
+ "NZ": ZF,
414
+ "BE": CF | ZF,
415
+ "A": CF | ZF,
416
+ "S": SF,
417
+ "NS": SF,
418
+ "P": PF,
419
+ "NP": PF,
420
+ "L": SF | OF,
421
+ "GE": SF | OF,
422
+ "LE": SF | OF | ZF,
423
+ "G": SF | OF | ZF,
424
+ # Special for FCMOV
425
+ "U": PF,
426
+ "NU": PF,
427
+ "E": ZF,
428
+ "NE": ZF,
429
+ "NB": CF,
430
+ "NBE": CF | ZF
431
+ }
432
+ # Return tested flags only.
433
+ return (0, Conditions[cond], 0)
434
+
435
+ def UpdateInstructionAffectedFlags(ii):
436
+ """
437
+ Add flags for each instruction that is in the following table. We add modified/tested/undefined flags.
438
+ Note that some instruction reset specific flags, but we don't record that here, we only care about actually modified ones.
439
+ """
440
+ # MNEM: MODIFIED, TEST, UNDEFINED.
441
+ OF, SF, ZF, AF, PF, CF, IF, DF = CPUFlags.OF, CPUFlags.SF, CPUFlags.ZF, CPUFlags.AF, CPUFlags.PF, CPUFlags.CF, CPUFlags.IF, CPUFlags.DF
442
+ InstByMnem = {
443
+ "AAA": (AF | CF, AF, OF | SF | ZF | PF),
444
+ "AAS": (AF | CF, AF, OF | SF | ZF | PF),
445
+ "AAD": (SF | ZF | PF, 0, OF | AF | CF),
446
+ "AAM": (SF | ZF | PF, 0, OF | AF | CF),
447
+ "ADC": (OF | SF | ZF | AF | PF | CF, CF),
448
+ "ADD": (OF | SF | ZF | AF | PF | CF),
449
+ "AND": (OF | SF | ZF | PF | CF, 0, AF),
450
+ "ARPL": (ZF),
451
+ "BSF": (ZF, 0, OF | SF | ZF | AF | PF | CF),
452
+ "BSR": (ZF, 0, OF | SF | ZF | AF | PF | CF),
453
+ "BT": (CF, 0, OF | SF | ZF | AF | PF),
454
+ "BTS": (CF, 0, OF | SF | ZF | AF | PF),
455
+ "BTR": (CF, 0, OF | SF | ZF | AF | PF),
456
+ "BTC": (CF, 0, OF | SF | ZF | AF | PF),
457
+ "CLC": (CF),
458
+ "CLD": (DF),
459
+ "CLI": (IF),
460
+ "CMC": (CF),
461
+ "CMP": (OF | SF | ZF | AF | PF | CF),
462
+ "CMPXCHG": (OF | SF | ZF | AF | PF | CF),
463
+ "CMPXCHG8B": (ZF),
464
+ "CMPXCHG16B": (ZF), # Same inst as previous.
465
+ "COMSID": (ZF | PF | CF),
466
+ "COMISS": (ZF | PF | CF),
467
+ "DAA": (SF | ZF | AF | PF | CF, AF | CF, OF),
468
+ "DAS": (SF | ZF | AF | PF | CF, AF | CF, OF),
469
+ "DEC": (OF | SF | ZF | AF | PF),
470
+ "DIV": (0, 0, OF | SF | ZF | AF | PF | CF),
471
+ "FCOMI": (ZF | PF | CF),
472
+ "FCOMIP": (ZF | PF | CF),
473
+ "FUCOMI": (ZF | PF | CF),
474
+ "FUCOMIP": (ZF | PF | CF),
475
+ "IDIV": (0, 0, OF | SF | ZF | AF | PF | CF),
476
+ "IMUL": (OF | CF, 0, SF | ZF | AF | PF),
477
+ "INC": (OF | SF | ZF | AF | PF),
478
+ "UCOMSID": (ZF | PF | CF),
479
+ "UCOMISS": (ZF | PF | CF),
480
+ "IRET": (OF | SF | ZF | AF | PF | CF | IF | DF),
481
+ "LAR": (ZF),
482
+ "LOOPZ": (0, ZF),
483
+ "LOOPNZ": (0, ZF),
484
+ "LSL": (ZF),
485
+ "LZCNT": (ZF | CF, 0, OF | SF | AF | PF),
486
+ "MUL": (OF | CF, 0, SF | ZF | AF | PF),
487
+ "NEG": (OF | SF | ZF | AF | PF | CF),
488
+ "OR": (SF | ZF | PF, AF),
489
+ "POPCNT": (ZF),
490
+ "POPF": (OF | SF | ZF | AF | PF | CF | IF | DF),
491
+ "RSM": (OF | SF | ZF | AF | PF | CF | IF | DF),
492
+ "SAHF": (SF | ZF | AF | PF | CF),
493
+ "SBB": (OF | SF | ZF | AF | PF | CF, CF),
494
+ "STC": (CF),
495
+ "STD": (DF),
496
+ "STI": (IF),
497
+ "SUB": (OF | SF | ZF | AF | PF | CF),
498
+ "TEST": (SF | ZF | PF, 0, AF),
499
+ "VERR": (ZF),
500
+ "VERW": (ZF),
501
+ "XADD": (OF | SF | ZF | AF | PF | CF),
502
+ "XOR": (SF | ZF | PF, 0, AF),
503
+ # IO/String instructions:
504
+ "MOVS": (0, DF),
505
+ "LODS": (0, DF),
506
+ "STOS": (0, DF),
507
+ "CMPS": (OF | SF | ZF | AF | PF | CF, DF),
508
+ "SCAS": (OF | SF | ZF | AF | PF | CF, DF),
509
+ "INS": (0, DF),
510
+ "OUTS": (0, DF)
511
+ }
512
+ # Check for mnemonics in the above table.
513
+ for i in ii.mnemonics:
514
+ if InstByMnem.has_key(i) and (ii.flags & InstFlag.PSEUDO_OPCODE) == 0:
515
+ SetInstructionAffectedFlags(ii, InstByMnem[i])
516
+ return
517
+
518
+ # Look carefuly for SETcc or Jcc instructions.
519
+ for i in ["SET", "CMOV", "FCMOV"]:
520
+ if ii.mnemonics[0].find(i) == 0:
521
+ SetInstructionAffectedFlags(ii, GetTestedFlagsForCondition(ii.mnemonics[0][len(i):]))
522
+ return
523
+ # See if it's a Jcc instruction.
524
+ if ii.mnemonics[0][:1] == "J" and ii.mnemonics[0][:2] not in ["JM", "JC", "JE", "JR"]:
525
+ SetInstructionAffectedFlags(ii, GetTestedFlagsForCondition(ii.mnemonics[0][1:]))
526
+ return
527
+
528
+ # Still no match, try special shift/rotate instructions.
529
+ # Special shift/rotate instruction that with constant 1 have different flag affections:
530
+ # First tuple is with constant 1, second tuple is with any count (CL).
531
+ Shifts = [
532
+ (["RCL", "RCR"], (OF | CF, CF), (CF, CF, OF)),
533
+ (["ROL", "ROR"], (OF | CF), (CF, 0, OF)),
534
+ (["SAL", "SAR", "SHL", "SHR"], (OF | SF | ZF | PF | CF, 0, AF), (SF | ZF | PF | CF, 0, OF | AF)),
535
+ (["SHLD", "SHRD"], (OF | SF | ZF | PF | CF, 0, AF), (SF | ZF | PF | CF, 0, OF | AF))
536
+ ]
537
+ for i in Shifts:
538
+ for j in i[0]:
539
+ if ii.mnemonics[0] == j:
540
+ flags = i[1] if ii.operands[1] == OperandType.CONST1 else i[2]
541
+ SetInstructionAffectedFlags(ii, flags)
542
+ return
543
+
544
+ # The instruction doesn't affect any flags...
545
+ return
546
+
547
+ # Table to hold shared inst-info.
548
+ sharedInfoDict = {}
549
+ # Table to hold shared flags.
550
+ flagsDict = {}
551
+ def FormatInstruction(ii):
552
+ """ Formats a string with all information relevant for diStorm InstInfo structure
553
+ or the InstInfoEx. These are the internal structures diStorm uses for holding the instructions' information.
554
+ Using this structure diStorm knows how to format an opcode when it reads it from the stream.
555
+
556
+ An instruction information structure is found by its byte codes with a prefix of "II_".
557
+ So for example ADD EAX, Imm32 instruction is II_00.
558
+ Since there are several types of instructions information structures,
559
+ the tables which point to these non-default InstInfo structures, will have to cast the pointer. """
560
+
561
+ # There might be optional fields, if there's a 3rd operand or a second/third mnemonic.
562
+ optFields = ""
563
+ # Default type of structure is InstInfo.
564
+ type = "_InstInfo"
565
+
566
+ # Make sure the instruction can be fully represented using the diStorm3 _DecodeInst structure.
567
+ CheckOTCollisions(ii)
568
+
569
+ # Add flags for flow control instructions.
570
+ UpdateForFlowControl(ii)
571
+
572
+ # Add flags for writable destination operand.
573
+ UpdateWritableDestinationOperand(ii)
574
+
575
+ # Add affected modified/tested/undefined flags for instruction.
576
+ UpdateInstructionAffectedFlags(ii)
577
+
578
+ # Pad mnemonics to three, in case EXMNEMONIC/2 isn't used (so we don't get an exception).
579
+ mnems = TranslateMnemonics([None, ii.classType][(ii.flags & InstFlag.PSEUDO_OPCODE) == InstFlag.PSEUDO_OPCODE], ii.mnemonics) + [0, 0]
580
+
581
+ # Mark whether the instruction is privileged, by setting MSB of the OpcodeId field.
582
+ UpdatePrivilegedInstruction(mnems, ii)
583
+
584
+ # Pad operands to atleast three (so we don't get an exception too, since there might be instructions with no operands at all).
585
+ ops = ii.operands + [OperandType.NONE, OperandType.NONE, OperandType.NONE, OperandType.NONE]
586
+
587
+ # Is it an extended structure?
588
+ if ii.flags & InstFlag.EXTENDED:
589
+ # Since there's a second and/or a third mnemonic, use the the InstInfoEx structure.
590
+ type = "_InstInfoEx"
591
+ flagsEx = 0
592
+ # Fix flagsEx to have the VEX flags, except PRE_VEX.
593
+ if ii.flags & InstFlag.PRE_VEX:
594
+ flagsEx = ii.flags >> InstFlag.FLAGS_EX_START_INDEX
595
+ # If there's a third operand, use it, otherwise NONE.
596
+ op3 = [OperandType.NONE, ops[2]][(ii.flags & InstFlag.USE_OP3) == InstFlag.USE_OP3]
597
+ op4 = [OperandType.NONE, ops[3]][(ii.flags & InstFlag.USE_OP4) == InstFlag.USE_OP4]
598
+ if flagsEx >= 256: # Assert the size of flagsEx is enough to holds this value.
599
+ raise "FlagsEx exceeded its 8 bits. Change flagsEx of _InstInfoEx to be uint16!"
600
+ # Concat the mnemonics and the third operand.
601
+ optFields = ", 0x%x, %d, %d, %d, %d" % (flagsEx, op3, op4, mnems[1], mnems[2])
602
+
603
+ # Notice we filter out internal bits from flags.
604
+ flags = ii.flags & ((1 << InstFlag.FLAGS_EX_START_INDEX)-1)
605
+ # Allocate a slot for this flag if needed.
606
+ if not flagsDict.has_key(flags):
607
+ flagsDict[flags] = len(flagsDict)
608
+ # Get the flags-index.
609
+ flagsIndex = flagsDict[flags]
610
+ if flagsIndex >= 256:
611
+ raise "FlagsIndex exceeded its 8 bits. Change flags of _InstInfo to be uint16!"
612
+
613
+ # InstSharedInfo:
614
+ sharedInfo = (flagsIndex, ops[1], ops[0], (ii.classType << 3) | ii.flowControl, ii.modifiedFlags, ii.testedFlags, ii.undefinedFlags)
615
+ if not sharedInfoDict.has_key(sharedInfo):
616
+ sharedInfoDict[sharedInfo] = len(sharedInfoDict)
617
+ # Get the shared-info-index.
618
+ sharedInfoIndex = sharedInfoDict[sharedInfo]
619
+ if sharedInfoIndex >= 2**16:
620
+ raise "SharedInfoIndex exceeded its 16 bits. Change type of sharedInfoIndex in _InstInfo!"
621
+
622
+ fields = "0x%x, %d" % (sharedInfoIndex, mnems[0])
623
+ # "Structure-Name" = II_Bytes-Code {Fields + Optional-Fields}.
624
+ return ("\t/*II%s*/ {%s%s}" % (ii.tag, fields, optFields), (ii.flags & InstFlag.EXTENDED) != 0)
625
+
626
+ def FilterTable(table):
627
+ # All tables must go to output.
628
+ return True
629
+
630
+ def GeneratePseudoMnemonicOffsets():
631
+ """
632
+ Generate the static offset tables for psuedo compare instructions both for SSE and AVX.
633
+ The table is built in such a way that each cell holds the offset from the first pseudo mnemonic
634
+ to the indexed one.
635
+ """
636
+ # Lengths of pesudo mnemonics (SSE=CMPxxxYY + null + lengthByte)
637
+ lengths = map(lambda x: 3 + len(x) + 2 + 2, SSECmpTypes)
638
+ s = "uint16_t CmpMnemonicOffsets[8] = {\n" + ", ".join([str(sum(lengths[:i] or [0])) for i in xrange(len(lengths))]) + "\n};\n";
639
+
640
+ # (AVX=VCMPxxxYY + null + lengthByte).
641
+ lengths = map(lambda x: 4 + len(x) + 2 + 2, AVXCmpTypes)
642
+ s += "uint16_t VCmpMnemonicOffsets[32] = {\n" + ", ".join([str(sum(lengths[:i] or [0])) for i in xrange(len(lengths))]) + "\n};";
643
+ return s
644
+
645
+ def CreateTables(db):
646
+ """ This is the new tables generator code as for May 2011.
647
+ Its purpose is to return all tables and structures ready to use at once by diStorm.
648
+
649
+ The information is divided into 3 categories (arrays):
650
+ 1) The InstructionsTree root table, which holds all id's (InstNode) and refelects a tree, inside a flat array.
651
+ 2) The InstInfos table, which holds all Instruction-Information structures - the actual (basic) info per instruction.
652
+ 3) The InstInfosEx table, which holds all extended Instruction-Information structures.
653
+
654
+ Each array should be flat one defined only once. This means that we need to serialize all instruction-set tables into a single
655
+ table of pointers, kinda. This pointer is now a InstNode, which is really a 16 bits structure.
656
+ The low 13 bits are an index. The upper 3 bits are the type of what the index points to.
657
+ So basically, an index can be up to 8192 which is good enough as for now, cause we only have around ~5k entries in the tree.
658
+ However, it can be an index into the InstInfos or InstInfosEx tables, depends on the type.
659
+
660
+ A note from Feb 2007 - This new data layout in contrast with the old data layout saves more memory space (~12KB).
661
+ This new serialization should even save around 25kb! Because now we don't use real pointers anymore, only this tiny formatted InstNode.
662
+
663
+ The new method uses the last method, but instead of dividing the tree into many id's and pointer's tables,
664
+ it will now concatenate them all into the relevant tables. And instead of a real pointer to an Instruction-Information structure,
665
+ we will use an index into each table.
666
+
667
+ For example, say we have the following instructions table (byte code and mnemonic):
668
+ 0 - AND
669
+ 1 - XOR
670
+ 2 - OR
671
+ 3 - EMPTY (NO-INSTRUCTION-IS-ENCODED)
672
+ 4 - EMPTY
673
+ 5 - SHL
674
+ 6 - SHR
675
+ 7 - EMPTY
676
+
677
+ Old Documentation:
678
+ ------------------
679
+ So instead of generating the following old data layout:
680
+ {&II_00, &II_01, &II_02, NULL, NULL, &II_05, &II_06, NULL}
681
+ (Actually the old layout is a bit more complicated and consumes another byte for indicating the type of node.)
682
+
683
+ Anyways, we can generate the follow table:
684
+ {1, 2, 3, 0, 0, 4, 5, 0}
685
+ This time the table is in bytes, a byte is enough to index 256 instructions (which is a Full sized table).
686
+ However, an id's table is not enough, we need another table, the pointers table, which will look like this (following the above example):
687
+ {NULL, &II_00, &II_01, &II_02, &II_05, &II_06}
688
+
689
+ Note that if there are no EMPTY instructions in the table the first NULL entry will be omitted!
690
+
691
+ Assuming most of the space we managed to spare goes for telling diStorm "hey, this instruction is not encoded", we spared around 12KB.
692
+ So all empty instructions points to the same first entry inside its corresponding pointers table.
693
+ This way we pay another array of bytes for each table, but eliminate all NULL's.
694
+
695
+ So the actual node looks something like this:
696
+ {8, &table_00_ids, &table_00_pointers}
697
+ Which costs another dereference inside diStorm decoder.
698
+
699
+ New Documentation:
700
+ ------------------
701
+ As you can see, I did a pass back in 2007 to spare some empty entries in the tables.
702
+ But I kept using real pointers, which took lots of space. This time,
703
+ I am going to use a flat array which will represent the whole tree.
704
+ And combine all data into arrays, and spare even the old InstNode which was a small structure that says
705
+ what's the type of the table it points to. This type stuff will now be embedded inside the InstNode integer.
706
+
707
+ The new tables look like this (according to the above example):
708
+ InstInfo InstInfos[] = {
709
+ {AND info...},
710
+ {XOR info...},
711
+ {OR info...},
712
+ {SHL info...},
713
+ {SHR info...}
714
+ };
715
+
716
+ And another InstNodes table:
717
+ InstNode InstructionsTree[] = {
718
+ 0 | INSTINFO << 13,
719
+ 1 | INSTINFO << 13,
720
+ 2 | INSTINFO << 13,
721
+ -1,
722
+ -1,
723
+ 3 | INSTINFO << 13,
724
+ 4 | INSTINFO << 13,
725
+ -1,
726
+ };
727
+
728
+ The example happened to be a single table.
729
+ But suppose there's another index which points to another table in the tree, it would look like:
730
+ {TableIndexInInstructionsTree | TABLE << 13}
731
+ This way we know to read another byte and follow the next table...
732
+
733
+ :!:NOTE:!: You MUST iterate a table with GenBlock wrapper, otherwise you might NOT get all instructions from the DB!
734
+ Refer to x86db.py-class GenBlock for more information. """
735
+ indexShift = 13 # According to InstNode in instructions.h.
736
+ InstInfos = []
737
+ InstInfosEx = []
738
+ InstructionsTree = []
739
+ externTables = []
740
+ nextTableIndex = 256 # Root tree takes 256 nodes by default, so skip them.
741
+ # Scan all tables in the DB.
742
+ for x in db.GenerateTables(FilterTable):
743
+ # Don't make static definitions for specific exported tables.
744
+ if x.tag in ["_0F_0F", "_0F", "_0F_3A", "_0F_38"]:
745
+ # Store the index of these special tables, they are used directly in instructions.c.
746
+ externTables.append((x.tag, len(InstructionsTree)))
747
+ # Notice we use GenBlock for the special instructions, this is a must, otherwise we miss instructions from the DB.
748
+ for i in x86db.GenBlock(x):
749
+ if isinstance(i, x86db.InstructionInfo):
750
+ formattedII, isExtended = FormatInstruction(i)
751
+ if isExtended:
752
+ InstInfosEx.append(formattedII)
753
+ index = len(InstInfosEx) - 1
754
+ InstructionsTree.append((NodeType.INFOEX << indexShift | index, i.tag))
755
+ else:
756
+ InstInfos.append(formattedII)
757
+ index = len(InstInfos) - 1
758
+ InstructionsTree.append((NodeType.INFO << indexShift | index, i.tag))
759
+ elif isinstance(i, x86db.InstructionsTable):
760
+ InstructionsTree.append(((i.type << indexShift) | nextTableIndex, i.tag))
761
+ nextTableIndex += i.size # This assumes we walk on the instructions tables in BFS order!
762
+ else:
763
+ # False indicates this entry points nothing.
764
+ InstructionsTree.append((0, ""))
765
+ s = ["\n".join(["_InstInfo II_%s =%s;" % (i.mnemonics[0] if i.mnemonics[0][0] != '_' else i.mnemonics[0][1:], FormatInstruction(i)[0]) for i in db.getExportedInstructions()]),
766
+ "_iflags FlagsTable[%d] = {\n%s\n};" % (len(flagsDict), ",\n".join(["0x%x" % i[1] for i in sorted(zip(flagsDict.values(), flagsDict.keys()))])),
767
+ "\n".join(["_InstNode Table%s = %d;" % (i[0], i[1]) for i in externTables]),
768
+ "_InstInfo InstInfos[%d] = {\n%s\n};" % (len(InstInfos), ",\n".join(InstInfos)),
769
+ "_InstInfoEx InstInfosEx[%d] = {\n%s\n};" % (len(InstInfosEx), ",\n".join(InstInfosEx)),
770
+ "_InstNode InstructionsTree[%d] = {\n%s\n};" % (len(InstructionsTree), ",\n".join(["/* %x - %s */ %s" % (i[0], i[1][1], "0" if i[1][0] == 0 else "0x%x" % i[1][0]) for i in enumerate(InstructionsTree)])),
771
+ # sharedInfoDict must be evaluated last, since the exported instructions above add items to it!
772
+ "_InstSharedInfo InstSharedInfoTable[%d] = {\n%s\n};" % (len(sharedInfoDict), ",\n".join(["{%s}" % str(i[1])[1:-1] for i in sorted(zip(sharedInfoDict.values(), sharedInfoDict.keys()))])),
773
+ GeneratePseudoMnemonicOffsets()]
774
+ return "\n\n".join(s)
775
+
776
+ def main():
777
+ # Init the 80x86/x64 instructions sets DB.
778
+ db = x86db.InstructionsDB()
779
+ x86InstructionsSet = x86sets.Instructions(db.SetInstruction)
780
+
781
+ # Open file for output.
782
+ f = open("output.txt", "w")
783
+
784
+ f.write("/*\n * GENERATED BY disOps at %s\n */\n\n" % time.asctime())
785
+
786
+ # Generate all tables of id's and pointers with the instructions themselves.
787
+ lists = CreateTables(db)
788
+ # Write them to the file also.
789
+ f.write(lists)
790
+ f.close()
791
+
792
+ DumpMnemonics()
793
+
794
+ print "The file output.txt was written successfully"
795
+ main()