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
Binary file
Binary file
@@ -0,0 +1,440 @@
1
+ /* -*- indent-tabs-mode: nil -*-
2
+ *
3
+ * This file is part of Funchook.
4
+ * https://github.com/kubo/funchook
5
+ *
6
+ * Funchook is free software: you can redistribute it and/or modify it
7
+ * under the terms of the GNU General Public License as published by the
8
+ * Free Software Foundation, either version 2 of the License, or (at your
9
+ * option) any later version.
10
+ *
11
+ * As a special exception, the copyright holders of this library give you
12
+ * permission to link this library with independent modules to produce an
13
+ * executable, regardless of the license terms of these independent
14
+ * modules, and to copy and distribute the resulting executable under
15
+ * terms of your choice, provided that you also meet, for each linked
16
+ * independent module, the terms and conditions of the license of that
17
+ * module. An independent module is a module which is not derived from or
18
+ * based on this library. If you modify this library, you may extend this
19
+ * exception to your version of the library, but you are not obliged to
20
+ * do so. If you do not wish to do so, delete this exception statement
21
+ * from your version.
22
+ *
23
+ * Funchook is distributed in the hope that it will be useful, but WITHOUT
24
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
25
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
26
+ * for more details.
27
+ *
28
+ * You should have received a copy of the GNU General Public License
29
+ * along with Funchook. If not, see <http://www.gnu.org/licenses/>.
30
+ */
31
+ #include "config.h"
32
+ #include <stdio.h>
33
+ #include <stdarg.h>
34
+ #include <stddef.h>
35
+ #include <stdlib.h>
36
+ #include <stdint.h>
37
+ #include <string.h>
38
+ #include <limits.h>
39
+ #ifdef WIN32
40
+ #include <windows.h>
41
+ #ifndef PATH_MAX
42
+ #define PATH_MAX MAX_PATH
43
+ #endif
44
+ #endif
45
+ #include "funchook.h"
46
+ #include "funchook_io.h"
47
+ #include "funchook_internal.h"
48
+
49
+ #define FUNCHOOK_MAX_ERROR_MESSAGE_LEN 200
50
+
51
+ typedef struct funchook_entry {
52
+ void *target_func;
53
+ void *hook_func;
54
+ uint8_t trampoline[TRAMPOLINE_SIZE];
55
+ uint8_t old_code[JUMP32_SIZE];
56
+ uint8_t new_code[JUMP32_SIZE];
57
+ #ifdef CPU_X86_64
58
+ uint8_t transit[JUMP64_SIZE];
59
+ #endif
60
+ } funchook_entry_t;
61
+
62
+ struct funchook_page {
63
+ struct funchook_page *next;
64
+ uint16_t used;
65
+ funchook_entry_t entries[1];
66
+ };
67
+
68
+ struct funchook {
69
+ int installed;
70
+ funchook_page_t *page_list;
71
+ char error_message[FUNCHOOK_MAX_ERROR_MESSAGE_LEN];
72
+ funchook_io_t io;
73
+ };
74
+
75
+ char funchook_debug_file[PATH_MAX];
76
+
77
+ const size_t funchook_size = sizeof(funchook_t);
78
+
79
+ static size_t num_entries_in_page;
80
+
81
+ static void funchook_logv(funchook_t *funchook, int set_error, const char *fmt, va_list ap);
82
+ static void funchook_log_end(funchook_t *funchook, const char *fmt, ...);
83
+ static funchook_t *funchook_create_internal(void);
84
+ static int funchook_prepare_internal(funchook_t *funchook, void **target_func, void *hook_func);
85
+ static int funchook_install_internal(funchook_t *funchook, int flags);
86
+ static int funchook_uninstall_internal(funchook_t *funchook, int flags);
87
+ static int funchook_destroy_internal(funchook_t *funchook);
88
+ static int get_page(funchook_t *funchook, funchook_page_t **page_out, uint8_t *addr, rip_displacement_t *disp);
89
+
90
+ #ifdef CPU_X86_64
91
+
92
+ int funchook_page_avail(funchook_t *funchook, funchook_page_t *page, int idx, uint8_t *addr, rip_displacement_t *disp)
93
+ {
94
+ funchook_entry_t *entry = &page->entries[idx];
95
+ const uint8_t *src;
96
+ const uint8_t *dst;
97
+
98
+ if (!funchook_jump32_avail(addr, entry->trampoline)) {
99
+ funchook_log(funchook, " could not jump function %p to trampoline %p\n", addr, entry->trampoline);
100
+ return 0;
101
+ }
102
+ src = entry->trampoline + disp[0].src_addr_offset;
103
+ dst = disp[0].dst_addr;
104
+ if (!funchook_within_32bit_relative(src, dst)) {
105
+ funchook_log(funchook, " could not jump trampoline %p to function %p\n",
106
+ src, dst);
107
+ return 0;
108
+ }
109
+ src = entry->trampoline + disp[1].src_addr_offset;
110
+ dst = disp[1].dst_addr;
111
+ if (dst != 0 && !funchook_within_32bit_relative(src, dst)) {
112
+ funchook_log(funchook, " could not make 32-bit relative address from %p to %p\n",
113
+ src, dst);
114
+ return 0;
115
+ }
116
+ return 1;
117
+ }
118
+
119
+ #endif
120
+
121
+ funchook_t *funchook_create(void)
122
+ {
123
+ funchook_t *funchook = NULL;
124
+
125
+ funchook_log(funchook, "Enter funchook_create()\n");
126
+ funchook = funchook_create_internal();
127
+ funchook_log_end(funchook, "Leave funchook_create() => %p\n", funchook);
128
+ return funchook;
129
+ }
130
+
131
+ int funchook_prepare(funchook_t *funchook, void **target_func, void *hook_func)
132
+ {
133
+ int rv;
134
+ void *orig_func;
135
+
136
+ funchook_log(funchook, "Enter funchook_prepare(%p, %p, %p)\n", funchook, target_func, hook_func);
137
+ orig_func = *target_func;
138
+ rv = funchook_prepare_internal(funchook, target_func, hook_func);
139
+ funchook_log_end(funchook, "Leave funchook_prepare(..., [%p->%p],...) => %d\n", orig_func, *target_func, rv);
140
+ return rv;
141
+ }
142
+
143
+ int funchook_install(funchook_t *funchook, int flags)
144
+ {
145
+ int rv;
146
+
147
+ funchook_log(funchook, "Enter funchook_install(%p, 0x%x)\n", funchook, flags);
148
+ rv = funchook_install_internal(funchook, flags);
149
+ funchook_log_end(funchook, "Leave funchook_install() => %d\n", rv);
150
+ return rv;
151
+ }
152
+
153
+ int funchook_uninstall(funchook_t *funchook, int flags)
154
+ {
155
+ int rv;
156
+
157
+ funchook_log(funchook, "Enter funchook_uninstall(%p, 0x%x)\n", funchook, flags);
158
+ rv = funchook_uninstall_internal(funchook, flags);
159
+ funchook_log_end(NULL, "Leave funchook_uninstall() => %d\n", rv);
160
+ return rv;
161
+ }
162
+
163
+ int funchook_destroy(funchook_t *funchook)
164
+ {
165
+ int rv;
166
+
167
+ funchook_log(funchook, "Enter funchook_destroy(%p)\n", funchook);
168
+ rv = funchook_destroy_internal(funchook);
169
+ funchook_log_end(rv == 0 ? NULL : funchook, "Leave funchook_destroy() => %d\n", rv);
170
+ return rv;
171
+ }
172
+
173
+ const char *funchook_error_message(const funchook_t *funchook)
174
+ {
175
+ return funchook->error_message;
176
+ }
177
+
178
+ int funchook_set_debug_file(const char *name)
179
+ {
180
+ if (name != NULL) {
181
+ strlcpy(funchook_debug_file, name, sizeof(funchook_debug_file));
182
+ } else {
183
+ funchook_debug_file[0] = '\0';
184
+ }
185
+ return 0;
186
+ }
187
+
188
+ void funchook_log(funchook_t *funchook, const char *fmt, ...)
189
+ {
190
+ va_list ap;
191
+ va_start(ap, fmt);
192
+ funchook_logv(funchook, 0, fmt, ap);
193
+ va_end(ap);
194
+ }
195
+
196
+ void funchook_set_error_message(funchook_t *funchook, const char *fmt, ...)
197
+ {
198
+ va_list ap;
199
+
200
+ va_start(ap, fmt);
201
+ funchook_vsnprintf(funchook->error_message, FUNCHOOK_MAX_ERROR_MESSAGE_LEN, fmt, ap);
202
+ va_end(ap);
203
+ va_start(ap, fmt);
204
+ funchook_logv(funchook, 1, fmt, ap);
205
+ va_end(ap);
206
+ }
207
+
208
+ static void funchook_logv(funchook_t *funchook, int set_error, const char *fmt, va_list ap)
209
+ {
210
+ funchook_io_t iobuf;
211
+ funchook_io_t *io = &iobuf;
212
+
213
+ if (*funchook_debug_file == '\0') {
214
+ return;
215
+ }
216
+ if (funchook == NULL) {
217
+ funchook_io_open(&iobuf, funchook_debug_file, FUNCHOOK_IO_APPEND);
218
+ } else if (funchook->io.file == INVALID_FILE_HANDLE) {
219
+ funchook_io_open(&funchook->io, funchook_debug_file, FUNCHOOK_IO_APPEND);
220
+ io = &funchook->io;
221
+ } else {
222
+ io = &funchook->io;
223
+ }
224
+ if (io->file == INVALID_FILE_HANDLE) {
225
+ return;
226
+ }
227
+ if (set_error) {
228
+ funchook_io_puts(" ", io);
229
+ }
230
+ funchook_io_vprintf(io, fmt, ap);
231
+ if (set_error) {
232
+ funchook_io_putc('\n', io);
233
+ }
234
+ if (funchook == NULL) {
235
+ funchook_io_close(io);
236
+ } else {
237
+ funchook_io_flush(io);
238
+ }
239
+ }
240
+
241
+ static void funchook_log_end(funchook_t *funchook, const char *fmt, ...)
242
+ {
243
+ va_list ap;
244
+ va_start(ap, fmt);
245
+ funchook_logv(funchook, 0, fmt, ap);
246
+ va_end(ap);
247
+ if (funchook != NULL && funchook->io.file != INVALID_FILE_HANDLE) {
248
+ funchook_io_close(&funchook->io);
249
+ }
250
+ }
251
+
252
+ static funchook_t *funchook_create_internal(void)
253
+ {
254
+ funchook_t *funchook = funchook_alloc();
255
+ if (funchook == NULL) {
256
+ return NULL;
257
+ }
258
+ funchook->io.file = INVALID_FILE_HANDLE;
259
+ if (num_entries_in_page == 0) {
260
+ num_entries_in_page = (page_size - offsetof(funchook_page_t, entries)) / sizeof(funchook_entry_t);
261
+ funchook_log(funchook,
262
+ #ifdef WIN32
263
+ " allocation_unit=%"SIZE_T_FMT"u\n"
264
+ #endif
265
+ " page_size=%"SIZE_T_FMT"u\n"
266
+ " num_entries_in_page=%"SIZE_T_FMT"u\n",
267
+ #ifdef WIN32
268
+ allocation_unit,
269
+ #endif
270
+ page_size, num_entries_in_page);
271
+ }
272
+ return funchook;
273
+ }
274
+
275
+ static int funchook_prepare_internal(funchook_t *funchook, void **target_func, void *hook_func)
276
+ {
277
+ void *func = *target_func;
278
+ uint8_t trampoline[TRAMPOLINE_SIZE];
279
+ rip_displacement_t disp[2] = {{0,},{0,}};
280
+ funchook_page_t *page = NULL;
281
+ funchook_entry_t *entry;
282
+ uint8_t *src_addr;
283
+ uint32_t *offset_addr;
284
+ int rv;
285
+
286
+ if (funchook->installed) {
287
+ funchook_set_error_message(funchook, "Could not modify already-installed funchook handle.");
288
+ return FUNCHOOK_ERROR_ALREADY_INSTALLED;
289
+ }
290
+ func = funchook_resolve_func(funchook, func);
291
+ rv = funchook_make_trampoline(funchook, disp, func, trampoline);
292
+ if (rv != 0) {
293
+ funchook_log(funchook, " failed to make trampoline\n");
294
+ return rv;
295
+ }
296
+ rv = get_page(funchook, &page, func, disp);
297
+ if (rv != 0) {
298
+ funchook_log(funchook, " failed to get page\n");
299
+ return rv;
300
+ }
301
+ entry = &page->entries[page->used];
302
+ /* fill members */
303
+ entry->target_func = func;
304
+ entry->hook_func = hook_func;
305
+ memcpy(entry->trampoline, trampoline, TRAMPOLINE_SIZE);
306
+ memcpy(entry->old_code, func, JUMP32_SIZE);
307
+ #ifdef CPU_X86_64
308
+ if (funchook_jump32_avail(func, hook_func)) {
309
+ funchook_write_jump32(funchook, func, hook_func, entry->new_code);
310
+ entry->transit[0] = 0;
311
+ } else {
312
+ funchook_write_jump32(funchook, func, entry->transit, entry->new_code);
313
+ funchook_write_jump64(funchook, entry->transit, hook_func);
314
+ }
315
+ #else
316
+ funchook_write_jump32(funchook, func, hook_func, entry->new_code);
317
+ #endif
318
+ /* fix rip-relative offsets */
319
+ src_addr = entry->trampoline + disp[0].src_addr_offset;
320
+ offset_addr = (uint32_t*)(entry->trampoline + disp[0].pos_offset);
321
+ *offset_addr = (uint32_t)(disp[0].dst_addr - src_addr);
322
+ if (disp[1].dst_addr != 0) {
323
+ src_addr = entry->trampoline + disp[1].src_addr_offset;
324
+ offset_addr = (uint32_t*)(entry->trampoline + disp[1].pos_offset);
325
+ *offset_addr = (uint32_t)(disp[1].dst_addr - src_addr);
326
+ }
327
+ funchook_log_trampoline(funchook, entry->trampoline);
328
+
329
+ page->used++;
330
+ *target_func = (void*)entry->trampoline;
331
+ return 0;
332
+ }
333
+
334
+ static int funchook_install_internal(funchook_t *funchook, int flags)
335
+ {
336
+ funchook_page_t *page;
337
+
338
+ if (funchook->installed) {
339
+ return FUNCHOOK_ERROR_ALREADY_INSTALLED;
340
+ }
341
+
342
+ for (page = funchook->page_list; page != NULL; page = page->next) {
343
+ int rv = funchook_page_protect(funchook, page);
344
+ int i;
345
+
346
+ if (rv != 0) {
347
+ return rv;
348
+ }
349
+
350
+ for (i = 0; i < page->used; i++) {
351
+ funchook_entry_t *entry = &page->entries[i];
352
+ mem_state_t mstate;
353
+ int rv = funchook_unprotect_begin(funchook, &mstate, entry->target_func, JUMP32_SIZE);
354
+
355
+ if (rv != 0) {
356
+ return rv;
357
+ }
358
+ memcpy(entry->target_func, entry->new_code, JUMP32_SIZE);
359
+ rv = funchook_unprotect_end(funchook, &mstate);
360
+ if (rv != 0) {
361
+ return rv;
362
+ }
363
+ }
364
+ }
365
+ funchook->installed = 1;
366
+ return 0;
367
+ }
368
+
369
+ static int funchook_uninstall_internal(funchook_t *funchook, int flags)
370
+ {
371
+ funchook_page_t *page;
372
+
373
+ if (!funchook->installed) {
374
+ return FUNCHOOK_ERROR_NOT_INSTALLED;
375
+ }
376
+
377
+ for (page = funchook->page_list; page != NULL; page = page->next) {
378
+ int i;
379
+
380
+ for (i = 0; i < page->used; i++) {
381
+ funchook_entry_t *entry = &page->entries[i];
382
+ mem_state_t mstate;
383
+ int rv = funchook_unprotect_begin(funchook, &mstate, entry->target_func, JUMP32_SIZE);
384
+
385
+ if (rv != 0) {
386
+ return rv;
387
+ }
388
+ memcpy(entry->target_func, entry->old_code, JUMP32_SIZE);
389
+ rv = funchook_unprotect_end(funchook, &mstate);
390
+ if (rv != 0) {
391
+ return rv;
392
+ }
393
+ }
394
+ funchook_page_unprotect(funchook, page);
395
+ }
396
+ funchook->installed = 0;
397
+ return 0;
398
+ }
399
+
400
+ static int funchook_destroy_internal(funchook_t *funchook)
401
+ {
402
+ funchook_page_t *page, *page_next;
403
+
404
+ if (funchook == NULL) {
405
+ return -1;
406
+ }
407
+ if (funchook->installed) {
408
+ return FUNCHOOK_ERROR_ALREADY_INSTALLED;
409
+ }
410
+ for (page = funchook->page_list; page != NULL; page = page_next) {
411
+ page_next = page->next;
412
+ funchook_page_free(funchook, page);
413
+ }
414
+ funchook_io_close(&funchook->io);
415
+ funchook_free(funchook);
416
+ return 0;
417
+ }
418
+
419
+ static int get_page(funchook_t *funchook, funchook_page_t **page_out, uint8_t *addr, rip_displacement_t *disp)
420
+ {
421
+ funchook_page_t *page;
422
+ int rv;
423
+
424
+ for (page = funchook->page_list; page != NULL; page = page->next) {
425
+ if (page->used < num_entries_in_page && funchook_page_avail(funchook, page, page->used, addr, disp)) {
426
+ /* Reuse allocated page. */
427
+ *page_out = page;
428
+ return 0;
429
+ }
430
+ }
431
+ rv = funchook_page_alloc(funchook, &page, addr, disp);
432
+ if (rv != 0) {
433
+ return rv;
434
+ }
435
+ page->used = 0;
436
+ page->next = funchook->page_list;
437
+ funchook->page_list = page;
438
+ *page_out = page;
439
+ return 0;
440
+ }
Binary file
@@ -0,0 +1,155 @@
1
+ /* -*- indent-tabs-mode: nil -*-
2
+ *
3
+ * This file is part of Funchook.
4
+ * https://github.com/kubo/funchook
5
+ *
6
+ * Funchook is free software: you can redistribute it and/or modify it
7
+ * under the terms of the GNU General Public License as published by the
8
+ * Free Software Foundation, either version 2 of the License, or (at your
9
+ * option) any later version.
10
+ *
11
+ * As a special exception, the copyright holders of this library give you
12
+ * permission to link this library with independent modules to produce an
13
+ * executable, regardless of the license terms of these independent
14
+ * modules, and to copy and distribute the resulting executable under
15
+ * terms of your choice, provided that you also meet, for each linked
16
+ * independent module, the terms and conditions of the license of that
17
+ * module. An independent module is a module which is not derived from or
18
+ * based on this library. If you modify this library, you may extend this
19
+ * exception to your version of the library, but you are not obliged to
20
+ * do so. If you do not wish to do so, delete this exception statement
21
+ * from your version.
22
+ *
23
+ * Funchook is distributed in the hope that it will be useful, but WITHOUT
24
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
25
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
26
+ * for more details.
27
+ *
28
+ * You should have received a copy of the GNU General Public License
29
+ * along with Funchook. If not, see <http://www.gnu.org/licenses/>.
30
+ */
31
+ #ifndef FUNCHOOK_INTERNAL_H
32
+ #define FUNCHOOK_INTERNAL_H 1
33
+ #include "funchook.h"
34
+ #include "os_func.h"
35
+
36
+ #ifndef MIN
37
+ #define MIN(a, b) (((a) < (b)) ? (a) : (b))
38
+ #endif
39
+
40
+ #ifndef MAX
41
+ #define MAX(a, b) (((a) > (b)) ? (a) : (b))
42
+ #endif
43
+
44
+ #ifdef WIN32
45
+ #ifdef _WIN64
46
+ #define SIZE_T_FMT "I64"
47
+ #define SIZE_T_WIDTH "16"
48
+ #else
49
+ #define SIZE_T_FMT ""
50
+ #define SIZE_T_WIDTH "8"
51
+ #endif /* _WIN64 */
52
+ #else /* WIN32 */
53
+ #if defined(__LP64__) || defined(_LP64)
54
+ #define SIZE_T_FMT "l"
55
+ #define SIZE_T_WIDTH "16"
56
+ #else
57
+ #ifdef __APPLE__
58
+ #define SIZE_T_FMT "z"
59
+ #else
60
+ #define SIZE_T_FMT ""
61
+ #endif
62
+ #define SIZE_T_WIDTH "8"
63
+ #endif /* defined(__LP64__) || defined(_LP64) */
64
+ #endif /* WIN32 */
65
+
66
+ #ifndef __GNUC__
67
+ #define __attribute__(arg)
68
+ #endif
69
+
70
+ #define ROUND_DOWN(num, unit) ((num) & ~((unit) - 1))
71
+ #define ROUND_UP(num, unit) (((num) + (unit) - 1) & ~((unit) - 1))
72
+
73
+ #if defined _M_AMD64 || defined __x86_64__
74
+ #define CPU_X86_64
75
+ #endif
76
+
77
+ #define MAX_INSN_LEN 16
78
+ #define MAX_INSN_CHECK_SIZE 256
79
+
80
+ #define JUMP32_SIZE 5
81
+ #ifdef CPU_X86_64
82
+ #define JUMP64_SIZE 14
83
+ #endif
84
+
85
+ #define TRAMPOLINE_SIZE (JUMP32_SIZE + (MAX_INSN_LEN - 1) + JUMP32_SIZE)
86
+
87
+ /* This must be same with sysconf(_SC_PAGE_SIZE) on Unix
88
+ * or the dwPageSize member of the SYSTEM_INFO structure on Windows.
89
+ */
90
+ #undef PAGE_SIZE
91
+ #define PAGE_SIZE 0x1000 /* 4k */
92
+
93
+ /* This must be same with the dwAllocationGranularity
94
+ * member of the SYSTEM_INFO structure on Windows.
95
+ */
96
+ #define ALLOCATION_UNIT 0x10000 /* 64k */
97
+
98
+ typedef struct {
99
+ void *addr;
100
+ size_t size;
101
+ #ifdef WIN32
102
+ DWORD protect;
103
+ #endif
104
+ } mem_state_t;
105
+
106
+ typedef struct {
107
+ const uint8_t *dst_addr;
108
+ intptr_t src_addr_offset;
109
+ intptr_t pos_offset;
110
+ } rip_displacement_t;
111
+
112
+ typedef struct funchook_page funchook_page_t;
113
+
114
+ /* Functions in funchook.c */
115
+ extern const size_t funchook_size;
116
+ extern char funchook_debug_file[];
117
+ #ifdef CPU_X86_64
118
+ int funchook_page_avail(funchook_t *funchook, funchook_page_t *page, int idx, uint8_t *addr, rip_displacement_t *disp);
119
+ #else
120
+ #define funchook_page_avail(funchook, page, idx, addr, disp) (1)
121
+ #endif
122
+ void funchook_log(funchook_t *funchook, const char *fmt, ...) __attribute__((__format__ (__printf__, 2, 3)));
123
+ void funchook_set_error_message(funchook_t *funchook, const char *fmt, ...) __attribute__((__format__ (__printf__, 2, 3)));
124
+
125
+ /* Functions in funchook_linux.c & funchook_windows.c */
126
+ extern const size_t page_size;
127
+ extern const size_t allocation_unit; /* windows only */
128
+
129
+ funchook_t *funchook_alloc(void);
130
+ int funchook_free(funchook_t *funchook);
131
+
132
+ int funchook_page_alloc(funchook_t *funchook, funchook_page_t **page_out, uint8_t *func, rip_displacement_t *disp);
133
+ int funchook_page_free(funchook_t *funchook, funchook_page_t *page);
134
+ int funchook_page_protect(funchook_t *funchook, funchook_page_t *page);
135
+ int funchook_page_unprotect(funchook_t *funchook, funchook_page_t *page);
136
+
137
+ int funchook_unprotect_begin(funchook_t *funchook, mem_state_t *mstate, void *addr, size_t len);
138
+ int funchook_unprotect_end(funchook_t *funchook, const mem_state_t *mstate);
139
+
140
+ void *funchook_resolve_func(funchook_t *funchook, void *func);
141
+ const char *funchook_strerror(int errnum, char *buf, size_t buflen);
142
+
143
+ /* Functions in funchook_x86.c */
144
+
145
+ int funchook_write_jump32(funchook_t *funchook, const uint8_t *src, const uint8_t *dst, uint8_t *out);
146
+ #ifdef CPU_X86_64
147
+ int funchook_write_jump64(funchook_t *funchook, uint8_t *src, const uint8_t *dst);
148
+ int funchook_within_32bit_relative(const uint8_t *src, const uint8_t *dst);
149
+ int funchook_jump32_avail(const uint8_t *src, const uint8_t *dst);
150
+ #endif
151
+
152
+ int funchook_make_trampoline(funchook_t *funchook, rip_displacement_t *disp, const uint8_t *func, uint8_t *trampoline);
153
+ void funchook_log_trampoline(funchook_t *funchook, const uint8_t *trampoline);
154
+
155
+ #endif