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,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()