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.
- checksums.yaml +7 -0
- data/.clang-format +5 -0
- data/.dockerignore +10 -0
- data/.gitignore +58 -0
- data/.gitmodules +6 -0
- data/.rspec +6 -0
- data/.simplecov +4 -0
- data/Gemfile +7 -0
- data/LICENSE.txt +12 -0
- data/Rakefile +15 -0
- data/exe/contrast_service +29 -0
- data/ext/build_funchook.rb +48 -0
- data/ext/cs__assess_active_record_named/cs__active_record_named.c +47 -0
- data/ext/cs__assess_active_record_named/cs__active_record_named.h +10 -0
- data/ext/cs__assess_active_record_named/extconf.rb +2 -0
- data/ext/cs__assess_array/cs__assess_array.c +38 -0
- data/ext/cs__assess_array/cs__assess_array.h +9 -0
- data/ext/cs__assess_array/extconf.rb +2 -0
- data/ext/cs__assess_basic_object/cs__assess_basic_object.c +50 -0
- data/ext/cs__assess_basic_object/cs__assess_basic_object.h +17 -0
- data/ext/cs__assess_basic_object/extconf.rb +2 -0
- data/ext/cs__assess_fiber_track/cs__assess_fiber_track.c +86 -0
- data/ext/cs__assess_fiber_track/cs__assess_fiber_track.h +34 -0
- data/ext/cs__assess_fiber_track/extconf.rb +2 -0
- data/ext/cs__assess_hash/cs__assess_hash.c +64 -0
- data/ext/cs__assess_hash/cs__assess_hash.h +24 -0
- data/ext/cs__assess_hash/extconf.rb +2 -0
- data/ext/cs__assess_kernel/cs__assess_kernel.c +36 -0
- data/ext/cs__assess_kernel/cs__assess_kernel.h +10 -0
- data/ext/cs__assess_kernel/extconf.rb +2 -0
- data/ext/cs__assess_marshal_module/cs__assess_marshal_module.c +47 -0
- data/ext/cs__assess_marshal_module/cs__assess_marshal_module.h +18 -0
- data/ext/cs__assess_marshal_module/extconf.rb +2 -0
- data/ext/cs__assess_module/cs__assess_module.c +78 -0
- data/ext/cs__assess_module/cs__assess_module.h +25 -0
- data/ext/cs__assess_module/extconf.rb +2 -0
- data/ext/cs__assess_regexp/cs__assess_regexp.c +48 -0
- data/ext/cs__assess_regexp/cs__assess_regexp.h +22 -0
- data/ext/cs__assess_regexp/extconf.rb +2 -0
- data/ext/cs__assess_regexp_track/cs__assess_regexp_track.c +63 -0
- data/ext/cs__assess_regexp_track/cs__assess_regexp_track.h +29 -0
- data/ext/cs__assess_regexp_track/extconf.rb +2 -0
- data/ext/cs__assess_string/cs__assess_string.c +38 -0
- data/ext/cs__assess_string/cs__assess_string.h +19 -0
- data/ext/cs__assess_string/extconf.rb +2 -0
- data/ext/cs__assess_string_interpolation26/cs__assess_string_interpolation26.c +31 -0
- data/ext/cs__assess_string_interpolation26/cs__assess_string_interpolation26.h +13 -0
- data/ext/cs__assess_string_interpolation26/extconf.rb +2 -0
- data/ext/cs__common/cs__common.c +60 -0
- data/ext/cs__common/cs__common.h +28 -0
- data/ext/cs__common/extconf.rb +20 -0
- data/ext/cs__contrast_patch/cs__contrast_patch.c +445 -0
- data/ext/cs__contrast_patch/cs__contrast_patch.h +196 -0
- data/ext/cs__contrast_patch/extconf.rb +2 -0
- data/ext/cs__protect_kernel/cs__protect_kernel.c +37 -0
- data/ext/cs__protect_kernel/cs__protect_kernel.h +11 -0
- data/ext/cs__protect_kernel/extconf.rb +2 -0
- data/ext/cs__scope/cs__scope.c +96 -0
- data/ext/cs__scope/cs__scope.h +33 -0
- data/ext/cs__scope/extconf.rb +2 -0
- data/ext/extconf_common.rb +49 -0
- data/funchook/LICENSE +360 -0
- data/funchook/Makefile +29 -0
- data/funchook/Makefile.in +29 -0
- data/funchook/README.md +121 -0
- data/funchook/appveyor.yml +42 -0
- data/funchook/autogen.sh +3 -0
- data/funchook/autom4te.cache/output.0 +4976 -0
- data/funchook/autom4te.cache/requests +78 -0
- data/funchook/autom4te.cache/traces.0 +364 -0
- data/funchook/config.guess +1530 -0
- data/funchook/config.log +490 -0
- data/funchook/config.status +1016 -0
- data/funchook/config.sub +1773 -0
- data/funchook/configure +4976 -0
- data/funchook/configure.ac +59 -0
- data/funchook/distorm/COPYING +26 -0
- data/funchook/distorm/MANIFEST +25 -0
- data/funchook/distorm/MANIFEST.in +4 -0
- data/funchook/distorm/README.md +12 -0
- data/funchook/distorm/disOps/disOps.py +795 -0
- data/funchook/distorm/disOps/x86db.py +404 -0
- data/funchook/distorm/disOps/x86header.py +247 -0
- data/funchook/distorm/disOps/x86sets.py +1664 -0
- data/funchook/distorm/examples/cs/TestdiStorm/Program.cs +79 -0
- data/funchook/distorm/examples/cs/TestdiStorm/Properties/AssemblyInfo.cs +36 -0
- data/funchook/distorm/examples/cs/TestdiStorm/TestdiStorm.csproj +69 -0
- data/funchook/distorm/examples/cs/distorm-net.sln +26 -0
- data/funchook/distorm/examples/cs/distorm-net/CodeInfo.cs +23 -0
- data/funchook/distorm/examples/cs/distorm-net/DecodedInst.cs +15 -0
- data/funchook/distorm/examples/cs/distorm-net/DecodedResult.cs +14 -0
- data/funchook/distorm/examples/cs/distorm-net/DecomposedInst.cs +36 -0
- data/funchook/distorm/examples/cs/distorm-net/DecomposedResult.cs +14 -0
- data/funchook/distorm/examples/cs/distorm-net/Opcodes.cs +1268 -0
- data/funchook/distorm/examples/cs/distorm-net/Opcodes.tt +37 -0
- data/funchook/distorm/examples/cs/distorm-net/Operand.cs +25 -0
- data/funchook/distorm/examples/cs/distorm-net/Properties/AssemblyInfo.cs +36 -0
- data/funchook/distorm/examples/cs/distorm-net/diStorm3.cs +411 -0
- data/funchook/distorm/examples/cs/distorm-net/distorm-net.csproj +80 -0
- data/funchook/distorm/examples/cs/readme +3 -0
- data/funchook/distorm/examples/ddk/README +48 -0
- data/funchook/distorm/examples/ddk/distorm.ini +11 -0
- data/funchook/distorm/examples/ddk/dummy.c +15 -0
- data/funchook/distorm/examples/ddk/main.c +91 -0
- data/funchook/distorm/examples/ddk/makefile +1 -0
- data/funchook/distorm/examples/ddk/sources +10 -0
- data/funchook/distorm/examples/java/Makefile +23 -0
- data/funchook/distorm/examples/java/distorm/src/Main.java +43 -0
- data/funchook/distorm/examples/java/distorm/src/diStorm3/CodeInfo.java +27 -0
- data/funchook/distorm/examples/java/distorm/src/diStorm3/DecodedInst.java +32 -0
- data/funchook/distorm/examples/java/distorm/src/diStorm3/DecodedResult.java +11 -0
- data/funchook/distorm/examples/java/distorm/src/diStorm3/DecomposedInst.java +89 -0
- data/funchook/distorm/examples/java/distorm/src/diStorm3/DecomposedResult.java +11 -0
- data/funchook/distorm/examples/java/distorm/src/diStorm3/OpcodeEnum.java +131 -0
- data/funchook/distorm/examples/java/distorm/src/diStorm3/Opcodes.java +1123 -0
- data/funchook/distorm/examples/java/distorm/src/diStorm3/Operand.java +24 -0
- data/funchook/distorm/examples/java/distorm/src/diStorm3/distorm3.java +41 -0
- data/funchook/distorm/examples/java/jdistorm.c +405 -0
- data/funchook/distorm/examples/java/jdistorm.h +40 -0
- data/funchook/distorm/examples/java/jdistorm.sln +20 -0
- data/funchook/distorm/examples/java/jdistorm.vcproj +208 -0
- data/funchook/distorm/examples/linux/Makefile +15 -0
- data/funchook/distorm/examples/linux/main.c +181 -0
- data/funchook/distorm/examples/tests/Makefile +15 -0
- data/funchook/distorm/examples/tests/main.cpp +42 -0
- data/funchook/distorm/examples/tests/main.py +66 -0
- data/funchook/distorm/examples/tests/test_distorm3.py +1672 -0
- data/funchook/distorm/examples/tests/tests.sln +20 -0
- data/funchook/distorm/examples/tests/tests.vcxproj +82 -0
- data/funchook/distorm/examples/tests/tests.vcxproj.filters +22 -0
- data/funchook/distorm/examples/win32/disasm.sln +25 -0
- data/funchook/distorm/examples/win32/disasm.vcxproj +201 -0
- data/funchook/distorm/examples/win32/disasm.vcxproj.filters +14 -0
- data/funchook/distorm/examples/win32/main.cpp +163 -0
- data/funchook/distorm/include/distorm.h +482 -0
- data/funchook/distorm/include/mnemonics.h +301 -0
- data/funchook/distorm/make/linux/Makefile +28 -0
- data/funchook/distorm/make/mac/Makefile +24 -0
- data/funchook/distorm/make/win32/cdistorm.vcxproj +239 -0
- data/funchook/distorm/make/win32/cdistorm.vcxproj.filters +80 -0
- data/funchook/distorm/make/win32/distorm.sln +25 -0
- data/funchook/distorm/make/win32/resource.h +14 -0
- data/funchook/distorm/make/win32/resource.rc +99 -0
- data/funchook/distorm/python/distorm3/__init__.py +957 -0
- data/funchook/distorm/python/distorm3/sample.py +51 -0
- data/funchook/distorm/setup.cfg +10 -0
- data/funchook/distorm/setup.py +266 -0
- data/funchook/distorm/src/config.h +169 -0
- data/funchook/distorm/src/decoder.c +641 -0
- data/funchook/distorm/src/decoder.h +33 -0
- data/funchook/distorm/src/distorm.c +413 -0
- data/funchook/distorm/src/instructions.c +597 -0
- data/funchook/distorm/src/instructions.h +463 -0
- data/funchook/distorm/src/insts.c +7939 -0
- data/funchook/distorm/src/insts.h +64 -0
- data/funchook/distorm/src/mnemonics.c +284 -0
- data/funchook/distorm/src/operands.c +1290 -0
- data/funchook/distorm/src/operands.h +28 -0
- data/funchook/distorm/src/prefix.c +368 -0
- data/funchook/distorm/src/prefix.h +64 -0
- data/funchook/distorm/src/textdefs.c +172 -0
- data/funchook/distorm/src/textdefs.h +57 -0
- data/funchook/distorm/src/wstring.c +47 -0
- data/funchook/distorm/src/wstring.h +35 -0
- data/funchook/distorm/src/x86defs.h +82 -0
- data/funchook/include/funchook.h +123 -0
- data/funchook/install-sh +527 -0
- data/funchook/src/Makefile +70 -0
- data/funchook/src/Makefile.in +70 -0
- data/funchook/src/__strerror.h +109 -0
- data/funchook/src/config.h +101 -0
- data/funchook/src/config.h.in +100 -0
- data/funchook/src/decoder.o +0 -0
- data/funchook/src/distorm.o +0 -0
- data/funchook/src/funchook.c +440 -0
- data/funchook/src/funchook.o +0 -0
- data/funchook/src/funchook_internal.h +155 -0
- data/funchook/src/funchook_io.c +182 -0
- data/funchook/src/funchook_io.h +64 -0
- data/funchook/src/funchook_io.o +0 -0
- data/funchook/src/funchook_syscall.S +134 -0
- data/funchook/src/funchook_syscall.o +0 -0
- data/funchook/src/funchook_unix.c +480 -0
- data/funchook/src/funchook_unix.o +0 -0
- data/funchook/src/funchook_windows.c +397 -0
- data/funchook/src/funchook_x86.c +622 -0
- data/funchook/src/funchook_x86.o +0 -0
- data/funchook/src/instructions.o +0 -0
- data/funchook/src/insts.o +0 -0
- data/funchook/src/libfunchook.so +0 -0
- data/funchook/src/mnemonics.o +0 -0
- data/funchook/src/operands.o +0 -0
- data/funchook/src/os_func.c +115 -0
- data/funchook/src/os_func.h +75 -0
- data/funchook/src/os_func.o +0 -0
- data/funchook/src/os_func_unix.c +94 -0
- data/funchook/src/os_func_unix.o +0 -0
- data/funchook/src/os_func_windows.c +32 -0
- data/funchook/src/prefix.o +0 -0
- data/funchook/src/printf_base.c +1688 -0
- data/funchook/src/printf_base.h +46 -0
- data/funchook/src/printf_base.o +0 -0
- data/funchook/src/textdefs.o +0 -0
- data/funchook/src/wstring.o +0 -0
- data/funchook/test/Makefile +43 -0
- data/funchook/test/Makefile.in +43 -0
- data/funchook/test/funchook_test +0 -0
- data/funchook/test/libfunchook_test.c +25 -0
- data/funchook/test/libfunchook_test.so +0 -0
- data/funchook/test/libfunchook_test2.c +18 -0
- data/funchook/test/suffix.list +600 -0
- data/funchook/test/test_main.c +430 -0
- data/funchook/test/test_main.o +0 -0
- data/funchook/test/x86_64_test.S +10 -0
- data/funchook/test/x86_64_test.o +0 -0
- data/funchook/test/x86_test.S +339 -0
- data/funchook/win32/config.h +1 -0
- data/funchook/win32/funchook.sln +52 -0
- data/funchook/win32/funchook.vcxproj +188 -0
- data/funchook/win32/funchook.vcxproj.filters +84 -0
- data/funchook/win32/funchook_test.vcxproj +170 -0
- data/funchook/win32/funchook_test.vcxproj.filters +22 -0
- data/funchook/win32/funchook_test_dll.vcxproj +184 -0
- data/funchook/win32/funchook_test_dll.vcxproj.filters +30 -0
- data/funchook/win32/funchook_test_exe.def +3 -0
- data/lib/contrast-agent.rb +8 -0
- data/lib/contrast.rb +57 -0
- data/lib/contrast/agent.rb +80 -0
- data/lib/contrast/agent/assess.rb +45 -0
- data/lib/contrast/agent/assess/adjusted_span.rb +25 -0
- data/lib/contrast/agent/assess/class_reverter.rb +82 -0
- data/lib/contrast/agent/assess/contrast_event.rb +398 -0
- data/lib/contrast/agent/assess/frozen_properties.rb +41 -0
- data/lib/contrast/agent/assess/insulator.rb +53 -0
- data/lib/contrast/agent/assess/policy/dynamic_source_factory.rb +78 -0
- data/lib/contrast/agent/assess/policy/patcher.rb +85 -0
- data/lib/contrast/agent/assess/policy/policy.rb +116 -0
- data/lib/contrast/agent/assess/policy/policy_node.rb +289 -0
- data/lib/contrast/agent/assess/policy/policy_scanner.rb +44 -0
- data/lib/contrast/agent/assess/policy/preshift.rb +94 -0
- data/lib/contrast/agent/assess/policy/propagation_method.rb +260 -0
- data/lib/contrast/agent/assess/policy/propagation_node.rb +127 -0
- data/lib/contrast/agent/assess/policy/propagator.rb +35 -0
- data/lib/contrast/agent/assess/policy/propagator/append.rb +54 -0
- data/lib/contrast/agent/assess/policy/propagator/base.rb +37 -0
- data/lib/contrast/agent/assess/policy/propagator/center.rb +73 -0
- data/lib/contrast/agent/assess/policy/propagator/custom.rb +36 -0
- data/lib/contrast/agent/assess/policy/propagator/database_write.rb +62 -0
- data/lib/contrast/agent/assess/policy/propagator/insert.rb +55 -0
- data/lib/contrast/agent/assess/policy/propagator/keep.rb +26 -0
- data/lib/contrast/agent/assess/policy/propagator/next.rb +42 -0
- data/lib/contrast/agent/assess/policy/propagator/prepend.rb +50 -0
- data/lib/contrast/agent/assess/policy/propagator/remove.rb +76 -0
- data/lib/contrast/agent/assess/policy/propagator/replace.rb +27 -0
- data/lib/contrast/agent/assess/policy/propagator/reverse.rb +38 -0
- data/lib/contrast/agent/assess/policy/propagator/select.rb +86 -0
- data/lib/contrast/agent/assess/policy/propagator/splat.rb +60 -0
- data/lib/contrast/agent/assess/policy/propagator/split.rb +49 -0
- data/lib/contrast/agent/assess/policy/propagator/substitution.rb +169 -0
- data/lib/contrast/agent/assess/policy/propagator/trim.rb +81 -0
- data/lib/contrast/agent/assess/policy/rewriter_patch.rb +79 -0
- data/lib/contrast/agent/assess/policy/source_method.rb +209 -0
- data/lib/contrast/agent/assess/policy/source_node.rb +62 -0
- data/lib/contrast/agent/assess/policy/trigger_method.rb +209 -0
- data/lib/contrast/agent/assess/policy/trigger_node.rb +198 -0
- data/lib/contrast/agent/assess/policy/trigger_validation/ssrf_validator.rb +77 -0
- data/lib/contrast/agent/assess/policy/trigger_validation/trigger_validation.rb +31 -0
- data/lib/contrast/agent/assess/policy/trigger_validation/xss_validator.rb +40 -0
- data/lib/contrast/agent/assess/properties.rb +392 -0
- data/lib/contrast/agent/assess/rule.rb +18 -0
- data/lib/contrast/agent/assess/rule/base.rb +72 -0
- data/lib/contrast/agent/assess/rule/csrf.rb +66 -0
- data/lib/contrast/agent/assess/rule/csrf/csrf_action.rb +28 -0
- data/lib/contrast/agent/assess/rule/csrf/csrf_applicator.rb +69 -0
- data/lib/contrast/agent/assess/rule/csrf/csrf_watcher.rb +132 -0
- data/lib/contrast/agent/assess/rule/provider.rb +21 -0
- data/lib/contrast/agent/assess/rule/provider/hardcoded_key.rb +62 -0
- data/lib/contrast/agent/assess/rule/provider/hardcoded_password.rb +73 -0
- data/lib/contrast/agent/assess/rule/provider/hardcoded_value_rule.rb +121 -0
- data/lib/contrast/agent/assess/rule/redos.rb +68 -0
- data/lib/contrast/agent/assess/rule/response_scanning_rule.rb +47 -0
- data/lib/contrast/agent/assess/rule/response_watcher.rb +36 -0
- data/lib/contrast/agent/assess/rule/watcher.rb +36 -0
- data/lib/contrast/agent/assess/tag.rb +151 -0
- data/lib/contrast/agent/at_exit_hook.rb +33 -0
- data/lib/contrast/agent/class_reopener.rb +195 -0
- data/lib/contrast/agent/deadzone/policy/deadzone_node.rb +26 -0
- data/lib/contrast/agent/deadzone/policy/policy.rb +57 -0
- data/lib/contrast/agent/disable_reaction.rb +24 -0
- data/lib/contrast/agent/exclusion_matcher.rb +190 -0
- data/lib/contrast/agent/feature_state.rb +379 -0
- data/lib/contrast/agent/inventory/policy/policy.rb +32 -0
- data/lib/contrast/agent/inventory/policy/trigger_node.rb +22 -0
- data/lib/contrast/agent/logger_manager.rb +116 -0
- data/lib/contrast/agent/middleware.rb +352 -0
- data/lib/contrast/agent/module_data.rb +16 -0
- data/lib/contrast/agent/patching/policy/after_load_patch.rb +37 -0
- data/lib/contrast/agent/patching/policy/after_load_patcher.rb +58 -0
- data/lib/contrast/agent/patching/policy/method_policy.rb +94 -0
- data/lib/contrast/agent/patching/policy/module_policy.rb +116 -0
- data/lib/contrast/agent/patching/policy/patch.rb +312 -0
- data/lib/contrast/agent/patching/policy/patch_status.rb +192 -0
- data/lib/contrast/agent/patching/policy/patcher.rb +310 -0
- data/lib/contrast/agent/patching/policy/policy.rb +138 -0
- data/lib/contrast/agent/patching/policy/policy_node.rb +80 -0
- data/lib/contrast/agent/patching/policy/policy_unpatcher.rb +28 -0
- data/lib/contrast/agent/patching/policy/trigger_node.rb +81 -0
- data/lib/contrast/agent/protect/policy/policy.rb +37 -0
- data/lib/contrast/agent/protect/policy/trigger_node.rb +23 -0
- data/lib/contrast/agent/protect/rule.rb +58 -0
- data/lib/contrast/agent/protect/rule/base.rb +300 -0
- data/lib/contrast/agent/protect/rule/base_service.rb +88 -0
- data/lib/contrast/agent/protect/rule/cmd_injection.rb +156 -0
- data/lib/contrast/agent/protect/rule/csrf.rb +118 -0
- data/lib/contrast/agent/protect/rule/csrf/csrf_evaluator.rb +103 -0
- data/lib/contrast/agent/protect/rule/csrf/csrf_token_injector.rb +85 -0
- data/lib/contrast/agent/protect/rule/default_scanner.rb +300 -0
- data/lib/contrast/agent/protect/rule/deserialization.rb +193 -0
- data/lib/contrast/agent/protect/rule/http_method_tampering.rb +80 -0
- data/lib/contrast/agent/protect/rule/no_sqli.rb +101 -0
- data/lib/contrast/agent/protect/rule/no_sqli/mongo_no_sql_scanner.rb +40 -0
- data/lib/contrast/agent/protect/rule/path_traversal.rb +143 -0
- data/lib/contrast/agent/protect/rule/sqli.rb +101 -0
- data/lib/contrast/agent/protect/rule/sqli/default_sql_scanner.rb +16 -0
- data/lib/contrast/agent/protect/rule/sqli/mysql_sql_scanner.rb +38 -0
- data/lib/contrast/agent/protect/rule/sqli/postgres_sql_scanner.rb +22 -0
- data/lib/contrast/agent/protect/rule/sqli/sqlite_sql_scanner.rb +19 -0
- data/lib/contrast/agent/protect/rule/unsafe_file_upload.rb +20 -0
- data/lib/contrast/agent/protect/rule/xss.rb +24 -0
- data/lib/contrast/agent/protect/rule/xxe.rb +120 -0
- data/lib/contrast/agent/protect/rule/xxe/entity_wrapper.rb +82 -0
- data/lib/contrast/agent/railtie.rb +30 -0
- data/lib/contrast/agent/reaction_processor.rb +47 -0
- data/lib/contrast/agent/request.rb +493 -0
- data/lib/contrast/agent/request_context.rb +225 -0
- data/lib/contrast/agent/require_state.rb +61 -0
- data/lib/contrast/agent/response.rb +215 -0
- data/lib/contrast/agent/rewriter.rb +244 -0
- data/lib/contrast/agent/scope.rb +28 -0
- data/lib/contrast/agent/service_heartbeat.rb +37 -0
- data/lib/contrast/agent/settings_state.rb +148 -0
- data/lib/contrast/agent/socket_client.rb +125 -0
- data/lib/contrast/agent/thread.rb +26 -0
- data/lib/contrast/agent/tracepoint_hook.rb +51 -0
- data/lib/contrast/agent/version.rb +8 -0
- data/lib/contrast/api.rb +17 -0
- data/lib/contrast/api/.gitkeep +0 -0
- data/lib/contrast/api/connection_status.rb +49 -0
- data/lib/contrast/api/socket.rb +43 -0
- data/lib/contrast/api/speedracer.rb +206 -0
- data/lib/contrast/api/tcp_socket.rb +31 -0
- data/lib/contrast/api/unix_socket.rb +25 -0
- data/lib/contrast/common_agent_configuration.rb +86 -0
- data/lib/contrast/components/agent.rb +85 -0
- data/lib/contrast/components/app_context.rb +188 -0
- data/lib/contrast/components/assess.rb +67 -0
- data/lib/contrast/components/config.rb +135 -0
- data/lib/contrast/components/contrast_service.rb +113 -0
- data/lib/contrast/components/heap_dump.rb +34 -0
- data/lib/contrast/components/interface.rb +178 -0
- data/lib/contrast/components/inventory.rb +23 -0
- data/lib/contrast/components/logger.rb +92 -0
- data/lib/contrast/components/protect.rb +38 -0
- data/lib/contrast/components/sampling.rb +41 -0
- data/lib/contrast/components/scope.rb +106 -0
- data/lib/contrast/components/settings.rb +140 -0
- data/lib/contrast/config.rb +33 -0
- data/lib/contrast/config/agent_configuration.rb +24 -0
- data/lib/contrast/config/application_configuration.rb +27 -0
- data/lib/contrast/config/assess_configuration.rb +22 -0
- data/lib/contrast/config/assess_rules_configuration.rb +18 -0
- data/lib/contrast/config/base_configuration.rb +105 -0
- data/lib/contrast/config/default_value.rb +16 -0
- data/lib/contrast/config/exception_configuration.rb +21 -0
- data/lib/contrast/config/heap_dump_configuration.rb +23 -0
- data/lib/contrast/config/inventory_configuration.rb +20 -0
- data/lib/contrast/config/logger_configuration.rb +20 -0
- data/lib/contrast/config/protect_configuration.rb +20 -0
- data/lib/contrast/config/protect_rule_configuration.rb +37 -0
- data/lib/contrast/config/protect_rules_configuration.rb +30 -0
- data/lib/contrast/config/root_configuration.rb +26 -0
- data/lib/contrast/config/ruby_configuration.rb +39 -0
- data/lib/contrast/config/sampling_configuration.rb +22 -0
- data/lib/contrast/config/server_configuration.rb +23 -0
- data/lib/contrast/config/service_configuration.rb +22 -0
- data/lib/contrast/configuration.rb +214 -0
- data/lib/contrast/core_extensions/assess.rb +51 -0
- data/lib/contrast/core_extensions/assess/array.rb +58 -0
- data/lib/contrast/core_extensions/assess/assess_extension.rb +145 -0
- data/lib/contrast/core_extensions/assess/basic_object.rb +15 -0
- data/lib/contrast/core_extensions/assess/erb.rb +42 -0
- data/lib/contrast/core_extensions/assess/exec_trigger.rb +48 -0
- data/lib/contrast/core_extensions/assess/fiber.rb +125 -0
- data/lib/contrast/core_extensions/assess/hash.rb +22 -0
- data/lib/contrast/core_extensions/assess/kernel.rb +95 -0
- data/lib/contrast/core_extensions/assess/module.rb +14 -0
- data/lib/contrast/core_extensions/assess/regexp.rb +206 -0
- data/lib/contrast/core_extensions/assess/string.rb +75 -0
- data/lib/contrast/core_extensions/assess/tilt_template_trigger.rb +73 -0
- data/lib/contrast/core_extensions/delegator.rb +14 -0
- data/lib/contrast/core_extensions/eval_trigger.rb +52 -0
- data/lib/contrast/core_extensions/inventory.rb +22 -0
- data/lib/contrast/core_extensions/inventory/datastores.rb +37 -0
- data/lib/contrast/core_extensions/module.rb +42 -0
- data/lib/contrast/core_extensions/object.rb +27 -0
- data/lib/contrast/core_extensions/protect.rb +20 -0
- data/lib/contrast/core_extensions/protect/applies_command_injection_rule.rb +70 -0
- data/lib/contrast/core_extensions/protect/applies_deserialization_rule.rb +58 -0
- data/lib/contrast/core_extensions/protect/applies_no_sqli_rule.rb +81 -0
- data/lib/contrast/core_extensions/protect/applies_path_traversal_rule.rb +119 -0
- data/lib/contrast/core_extensions/protect/applies_sqli_rule.rb +63 -0
- data/lib/contrast/core_extensions/protect/applies_xxe_rule.rb +141 -0
- data/lib/contrast/core_extensions/protect/kernel.rb +30 -0
- data/lib/contrast/core_extensions/protect/psych.rb +7 -0
- data/lib/contrast/core_extensions/thread.rb +31 -0
- data/lib/contrast/internal_exception.rb +8 -0
- data/lib/contrast/rails_extensions/assess/action_controller_inheritance.rb +48 -0
- data/lib/contrast/rails_extensions/assess/active_record.rb +32 -0
- data/lib/contrast/rails_extensions/assess/active_record_named.rb +61 -0
- data/lib/contrast/rails_extensions/assess/configuration.rb +26 -0
- data/lib/contrast/rails_extensions/buffer.rb +30 -0
- data/lib/contrast/rails_extensions/rack.rb +45 -0
- data/lib/contrast/security_exception.rb +14 -0
- data/lib/contrast/sinatra_extensions/assess/cookie.rb +26 -0
- data/lib/contrast/sinatra_extensions/inventory/sinatra_base.rb +59 -0
- data/lib/contrast/tasks/service.rb +95 -0
- data/lib/contrast/utils/assess/sampling_util.rb +96 -0
- data/lib/contrast/utils/assess/tracking_util.rb +39 -0
- data/lib/contrast/utils/boolean_util.rb +33 -0
- data/lib/contrast/utils/cache.rb +69 -0
- data/lib/contrast/utils/class_util.rb +58 -0
- data/lib/contrast/utils/comment_range.rb +19 -0
- data/lib/contrast/utils/data_store_util.rb +23 -0
- data/lib/contrast/utils/duck_utils.rb +58 -0
- data/lib/contrast/utils/env_configuration_item.rb +52 -0
- data/lib/contrast/utils/environment_util.rb +152 -0
- data/lib/contrast/utils/freeze_util.rb +36 -0
- data/lib/contrast/utils/gemfile_reader.rb +191 -0
- data/lib/contrast/utils/hash_digest.rb +148 -0
- data/lib/contrast/utils/heap_dump_util.rb +113 -0
- data/lib/contrast/utils/invalid_configuration_util.rb +88 -0
- data/lib/contrast/utils/inventory_util.rb +126 -0
- data/lib/contrast/utils/io_util.rb +61 -0
- data/lib/contrast/utils/object_share.rb +117 -0
- data/lib/contrast/utils/operating_environment.rb +38 -0
- data/lib/contrast/utils/os.rb +49 -0
- data/lib/contrast/utils/path_util.rb +151 -0
- data/lib/contrast/utils/performs_logging.rb +152 -0
- data/lib/contrast/utils/preflight_util.rb +13 -0
- data/lib/contrast/utils/prevent_serialization.rb +52 -0
- data/lib/contrast/utils/rack_assess_session_cookie.rb +104 -0
- data/lib/contrast/utils/rails_assess_configuration.rb +95 -0
- data/lib/contrast/utils/random_util.rb +22 -0
- data/lib/contrast/utils/resource_loader.rb +23 -0
- data/lib/contrast/utils/ruby_ast_rewriter.rb +74 -0
- data/lib/contrast/utils/scope_util.rb +99 -0
- data/lib/contrast/utils/service_response_util.rb +116 -0
- data/lib/contrast/utils/service_sender_util.rb +98 -0
- data/lib/contrast/utils/sha256_builder.rb +69 -0
- data/lib/contrast/utils/sinatra_helper.rb +49 -0
- data/lib/contrast/utils/stack_trace_utils.rb +209 -0
- data/lib/contrast/utils/string_utils.rb +72 -0
- data/lib/contrast/utils/tag_util.rb +139 -0
- data/lib/contrast/utils/thread_tracker.rb +54 -0
- data/lib/contrast/utils/timer.rb +78 -0
- data/resources/assess/policy.json +1673 -0
- data/resources/csrf/inject.js +44 -0
- data/resources/deadzone/policy.json +55 -0
- data/resources/factory-bot-spec/spec_helper.rb +30 -0
- data/resources/inventory/policy.json +110 -0
- data/resources/protect/policy.json +417 -0
- data/resources/rubocops/kernel/catch_cop.rb +37 -0
- data/resources/rubocops/kernel/require_cop.rb +37 -0
- data/resources/rubocops/kernel/require_relative_cop.rb +33 -0
- data/resources/rubocops/module/autoload_cop.rb +37 -0
- data/resources/rubocops/module/const_defined_cop.rb +37 -0
- data/resources/rubocops/module/const_get_cop.rb +37 -0
- data/resources/rubocops/module/const_set_cop.rb +37 -0
- data/resources/rubocops/module/constants_cop.rb +37 -0
- data/resources/rubocops/module/name_cop.rb +37 -0
- data/resources/rubocops/object/class_cop.rb +37 -0
- data/resources/rubocops/object/freeze_cop.rb +37 -0
- data/resources/rubocops/object/frozen_cop.rb +37 -0
- data/resources/rubocops/object/is_a_cop.rb +37 -0
- data/resources/rubocops/object/method_cop.rb +37 -0
- data/resources/rubocops/object/respond_to_cop.rb +37 -0
- data/resources/rubocops/object/singleton_class_cop.rb +37 -0
- data/resources/rubocops/regexp/spelling_cop.rb +44 -0
- data/resources/rubocops/thread/new_cop.rb +39 -0
- data/resources/ruby-spec/ancestors_spec.rb +70 -0
- data/resources/ruby-spec/modulo_spec.rb +831 -0
- data/resources/ruby-spec/parameters_spec.rb +261 -0
- data/resources/ruby-spec/ruby_spec_spec_helper.rb +35 -0
- data/resources/test_marker.txt +1 -0
- data/ruby-agent.gemspec +129 -0
- data/service_executables/.gitkeep +0 -0
- data/service_executables/VERSION +1 -0
- data/service_executables/linux/contrast-service +0 -0
- data/service_executables/mac/contrast-service +0 -0
- metadata +945 -0
@@ -0,0 +1,182 @@
|
|
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
|
+
#if defined __linux
|
32
|
+
#define _GNU_SOURCE
|
33
|
+
#endif
|
34
|
+
#include <string.h>
|
35
|
+
#include <errno.h>
|
36
|
+
|
37
|
+
#ifdef WIN32
|
38
|
+
#include <windows.h>
|
39
|
+
#else
|
40
|
+
#include <fcntl.h>
|
41
|
+
#endif
|
42
|
+
|
43
|
+
#include "funchook_io.h"
|
44
|
+
#include "printf_base.h"
|
45
|
+
#include "os_func.h"
|
46
|
+
|
47
|
+
int funchook_io_open(funchook_io_t *io, const char *path, int mode)
|
48
|
+
{
|
49
|
+
#ifdef WIN32
|
50
|
+
DWORD access_mode = GENERIC_READ;
|
51
|
+
DWORD creation_disp = 0;
|
52
|
+
if (mode == FUNCHOOK_IO_WRITE) {
|
53
|
+
access_mode = GENERIC_WRITE;
|
54
|
+
creation_disp = CREATE_ALWAYS;
|
55
|
+
io->append = 0;
|
56
|
+
} else if (mode == FUNCHOOK_IO_APPEND) {
|
57
|
+
access_mode = GENERIC_WRITE;
|
58
|
+
creation_disp = OPEN_ALWAYS;
|
59
|
+
io->append = 1;
|
60
|
+
}
|
61
|
+
io->file = CreateFileA(path, access_mode, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, creation_disp, FILE_ATTRIBUTE_NORMAL, NULL);
|
62
|
+
#else
|
63
|
+
int flags = O_RDONLY;
|
64
|
+
if (mode == FUNCHOOK_IO_WRITE) {
|
65
|
+
flags = O_WRONLY | O_CREAT | O_TRUNC;
|
66
|
+
} else if (mode == FUNCHOOK_IO_APPEND) {
|
67
|
+
flags = O_WRONLY | O_CREAT | O_APPEND;
|
68
|
+
}
|
69
|
+
io->file = open(path, flags, 0666);
|
70
|
+
#endif
|
71
|
+
io->ptr = io->end = io->buf;
|
72
|
+
return io->file != INVALID_FILE_HANDLE ? 0 : -1;
|
73
|
+
}
|
74
|
+
|
75
|
+
int funchook_io_close(funchook_io_t *io)
|
76
|
+
{
|
77
|
+
if (io->file != INVALID_FILE_HANDLE) {
|
78
|
+
#ifdef WIN32
|
79
|
+
CloseHandle(io->file);
|
80
|
+
#else
|
81
|
+
close(io->file);
|
82
|
+
#endif
|
83
|
+
io->file = INVALID_FILE_HANDLE;
|
84
|
+
}
|
85
|
+
return 0;
|
86
|
+
}
|
87
|
+
|
88
|
+
char *funchook_io_gets(char *s, int size, funchook_io_t *io)
|
89
|
+
{
|
90
|
+
char *p = s;
|
91
|
+
char *e = s + size - 1;
|
92
|
+
while (p < e) {
|
93
|
+
if (io->ptr == io->end) {
|
94
|
+
#ifdef WIN32
|
95
|
+
DWORD len;
|
96
|
+
if (!ReadFile(io->file, io->buf, sizeof(io->buf), &len, NULL)) {
|
97
|
+
len = 0;
|
98
|
+
}
|
99
|
+
#else
|
100
|
+
int len = read(io->file, io->buf, sizeof(io->buf));
|
101
|
+
#endif
|
102
|
+
if (len <= 0) {
|
103
|
+
if (p != s) {
|
104
|
+
break;
|
105
|
+
}
|
106
|
+
return NULL;
|
107
|
+
}
|
108
|
+
io->ptr = io->buf;
|
109
|
+
io->end = io->buf + len;
|
110
|
+
}
|
111
|
+
if ((*(p++) = *(io->ptr++)) == '\n') {
|
112
|
+
break;
|
113
|
+
}
|
114
|
+
}
|
115
|
+
*p = '\0';
|
116
|
+
return s;
|
117
|
+
}
|
118
|
+
|
119
|
+
#define IO_PUTC(c, io) do { \
|
120
|
+
if (io->ptr == io->buf + sizeof(io->buf)) { \
|
121
|
+
if (funchook_io_flush(io) != 0) { \
|
122
|
+
return -1; \
|
123
|
+
} \
|
124
|
+
} \
|
125
|
+
*(io->ptr++) = (c); \
|
126
|
+
} while (0)
|
127
|
+
|
128
|
+
int funchook_io_putc(char c, funchook_io_t *io)
|
129
|
+
{
|
130
|
+
#ifdef WIN32
|
131
|
+
if (c == '\n') {
|
132
|
+
IO_PUTC('\r', io);
|
133
|
+
}
|
134
|
+
#endif
|
135
|
+
IO_PUTC(c, io);
|
136
|
+
return (unsigned char)c;
|
137
|
+
}
|
138
|
+
|
139
|
+
int funchook_io_puts(const char *s, funchook_io_t *io)
|
140
|
+
{
|
141
|
+
while (*s) {
|
142
|
+
#ifdef WIN32
|
143
|
+
if (*s == '\n') {
|
144
|
+
IO_PUTC('\r', io);
|
145
|
+
}
|
146
|
+
#endif
|
147
|
+
IO_PUTC(*(s++), io);
|
148
|
+
}
|
149
|
+
return 0;
|
150
|
+
}
|
151
|
+
|
152
|
+
int funchook_io_vprintf(funchook_io_t *io, const char *format, va_list ap)
|
153
|
+
{
|
154
|
+
return printf_base((pfb_putc_t)funchook_io_putc, io, format, ap);
|
155
|
+
}
|
156
|
+
|
157
|
+
int funchook_io_flush(funchook_io_t *io)
|
158
|
+
{
|
159
|
+
if (io->ptr != io->buf) {
|
160
|
+
#ifdef WIN32
|
161
|
+
DWORD len = (DWORD)(io->ptr - io->buf);
|
162
|
+
DWORD wlen;
|
163
|
+
if (io->append) {
|
164
|
+
LARGE_INTEGER ll;
|
165
|
+
ll.QuadPart = 0;
|
166
|
+
if (!SetFilePointerEx(io->file, ll, NULL, FILE_END)) {
|
167
|
+
return -1;
|
168
|
+
}
|
169
|
+
}
|
170
|
+
if (!WriteFile(io->file, io->buf, len, &wlen, NULL) || wlen != len) {
|
171
|
+
return -1;
|
172
|
+
}
|
173
|
+
#else
|
174
|
+
size_t len = io->ptr - io->buf;
|
175
|
+
if (write(io->file, io->buf, len) != len) {
|
176
|
+
return -1;
|
177
|
+
}
|
178
|
+
#endif
|
179
|
+
io->ptr = io->buf;
|
180
|
+
}
|
181
|
+
return 0;
|
182
|
+
}
|
@@ -0,0 +1,64 @@
|
|
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_IO_H
|
32
|
+
#define FUNCHOOK_IO_H 1
|
33
|
+
#include <stdarg.h>
|
34
|
+
|
35
|
+
typedef struct {
|
36
|
+
#ifdef WIN32
|
37
|
+
#define INVALID_FILE_HANDLE INVALID_HANDLE_VALUE
|
38
|
+
void *file;
|
39
|
+
int append;
|
40
|
+
#else
|
41
|
+
#define INVALID_FILE_HANDLE -1
|
42
|
+
int file;
|
43
|
+
#endif
|
44
|
+
char *ptr;
|
45
|
+
char *end;
|
46
|
+
char buf[128];
|
47
|
+
} funchook_io_t;
|
48
|
+
|
49
|
+
#define FUNCHOOK_IO_READ 0
|
50
|
+
#define FUNCHOOK_IO_WRITE 1
|
51
|
+
#define FUNCHOOK_IO_APPEND 2
|
52
|
+
|
53
|
+
/*
|
54
|
+
* stdio-like functions
|
55
|
+
*/
|
56
|
+
int funchook_io_open(funchook_io_t *io, const char *path, int mode);
|
57
|
+
int funchook_io_close(funchook_io_t *io);
|
58
|
+
char *funchook_io_gets(char *s, int size, funchook_io_t *io);
|
59
|
+
int funchook_io_putc(char c, funchook_io_t *io);
|
60
|
+
int funchook_io_puts(const char *s, funchook_io_t *io);
|
61
|
+
int funchook_io_vprintf(funchook_io_t *io, const char *format, va_list ap);
|
62
|
+
int funchook_io_flush(funchook_io_t *io);
|
63
|
+
|
64
|
+
#endif /* FUNCHOOK_IO_H */
|
Binary file
|
@@ -0,0 +1,134 @@
|
|
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
|
+
#ifdef __APPLE__
|
32
|
+
#define funchook_os_syscall _funchook_os_syscall
|
33
|
+
#define funchook_os_errno _funchook_os_errno
|
34
|
+
#define hidden private_extern
|
35
|
+
#endif
|
36
|
+
|
37
|
+
#ifdef __x86_64__
|
38
|
+
.text
|
39
|
+
.p2align 4,,15
|
40
|
+
.globl funchook_os_syscall
|
41
|
+
.hidden funchook_os_syscall
|
42
|
+
funchook_os_syscall:
|
43
|
+
movq %rdi, %rax /* syscall number */
|
44
|
+
#ifdef __APPLE__
|
45
|
+
addq $0x2000000, %rax
|
46
|
+
#endif
|
47
|
+
movq %rsi, %rdi /* 1st argument */
|
48
|
+
movq %rdx, %rsi /* 2nd argument */
|
49
|
+
movq %rcx, %rdx /* 3rd argument */
|
50
|
+
movq %r8, %r10 /* 4th argument */
|
51
|
+
movq %r9, %r8 /* 5th argument */
|
52
|
+
movq 8(%rsp), %r9 /* 6th argument */
|
53
|
+
syscall
|
54
|
+
#ifdef __APPLE__
|
55
|
+
jnc 1f
|
56
|
+
#else
|
57
|
+
cmpq $-4096, %rax
|
58
|
+
jbe 1f
|
59
|
+
negl %eax
|
60
|
+
#endif
|
61
|
+
movq funchook_os_errno@GOTPCREL(%rip), %rdi
|
62
|
+
movl %eax, (%rdi)
|
63
|
+
movq $-1, %rax
|
64
|
+
1:
|
65
|
+
ret
|
66
|
+
#endif
|
67
|
+
|
68
|
+
#if defined(__i386__) && defined(__linux__)
|
69
|
+
.text
|
70
|
+
.p2align 4,,15
|
71
|
+
.globl funchook_os_syscall
|
72
|
+
.hidden funchook_os_syscall
|
73
|
+
funchook_os_syscall:
|
74
|
+
pushl %ebx
|
75
|
+
pushl %esi
|
76
|
+
pushl %edi
|
77
|
+
pushl %ebp
|
78
|
+
movl 20(%esp), %eax /* syscall number */
|
79
|
+
movl 24(%esp), %ebx /* 1st argument */
|
80
|
+
movl 28(%esp), %ecx /* 2nd argument */
|
81
|
+
movl 32(%esp), %edx /* 3rd argument */
|
82
|
+
movl 36(%esp), %esi /* 4th argument */
|
83
|
+
movl 40(%esp), %edi /* 5th argument */
|
84
|
+
movl 44(%esp), %ebp /* 6th argument */
|
85
|
+
call *%gs:0x10 // or int $0x80
|
86
|
+
cmpl $-4096, %eax
|
87
|
+
jbe 1f
|
88
|
+
call funchook.get_pc_thunk.cx
|
89
|
+
addl $_GLOBAL_OFFSET_TABLE_, %ecx
|
90
|
+
movl funchook_os_errno@GOT(%ecx), %ecx
|
91
|
+
negl %eax
|
92
|
+
movl %eax, (%ecx)
|
93
|
+
movl $-1, %eax
|
94
|
+
1:
|
95
|
+
popl %ebp
|
96
|
+
popl %edi
|
97
|
+
popl %esi
|
98
|
+
popl %ebx
|
99
|
+
ret
|
100
|
+
|
101
|
+
funchook.get_pc_thunk.cx:
|
102
|
+
movl (%esp), %ecx
|
103
|
+
ret
|
104
|
+
#endif
|
105
|
+
|
106
|
+
#if defined(__i386__) && defined(__APPLE__)
|
107
|
+
.text
|
108
|
+
.p2align 4,,15
|
109
|
+
.globl funchook_os_syscall
|
110
|
+
.hidden funchook_os_syscall
|
111
|
+
funchook_os_syscall:
|
112
|
+
popl %ecx /* return address */
|
113
|
+
popl %eax /* syscall number */
|
114
|
+
pushl %ecx
|
115
|
+
int $0x80
|
116
|
+
pushl %ecx
|
117
|
+
jc L_1
|
118
|
+
/* success. return %eax */
|
119
|
+
ret
|
120
|
+
/* failure. set %eax to funchook_os_errno and return -1 */
|
121
|
+
L_1:
|
122
|
+
call L_2
|
123
|
+
L_2:
|
124
|
+
popl %ecx /* get current eip */
|
125
|
+
movl L_funchook_os_errno$non_lazy_ptr-L_2(%ecx), %edx
|
126
|
+
movl %eax, (%edx)
|
127
|
+
movl $-1, %eax
|
128
|
+
ret
|
129
|
+
|
130
|
+
.section __IMPORT,__pointers,non_lazy_symbol_pointers
|
131
|
+
L_funchook_os_errno$non_lazy_ptr:
|
132
|
+
.indirect_symbol funchook_os_errno
|
133
|
+
.long 0
|
134
|
+
#endif
|
Binary file
|
@@ -0,0 +1,480 @@
|
|
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 <stdint.h>
|
34
|
+
#include <limits.h>
|
35
|
+
#include <string.h>
|
36
|
+
#include <unistd.h>
|
37
|
+
#include <errno.h>
|
38
|
+
#include <sys/mman.h>
|
39
|
+
#include <dlfcn.h>
|
40
|
+
#ifdef __linux
|
41
|
+
#include <elf.h>
|
42
|
+
#include <link.h>
|
43
|
+
#endif
|
44
|
+
#ifdef __APPLE__
|
45
|
+
#include <stdlib.h>
|
46
|
+
#include <mach/mach.h>
|
47
|
+
#endif
|
48
|
+
#include "funchook_io.h"
|
49
|
+
#include "funchook_internal.h"
|
50
|
+
|
51
|
+
#if !defined(MAP_ANONYMOUS) && defined(MAP_ANON)
|
52
|
+
#define MAP_ANONYMOUS MAP_ANON
|
53
|
+
#endif
|
54
|
+
|
55
|
+
const size_t page_size = PAGE_SIZE;
|
56
|
+
|
57
|
+
funchook_t *funchook_alloc(void)
|
58
|
+
{
|
59
|
+
size_t size = ROUND_UP(funchook_size, page_size);
|
60
|
+
void *mem = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
61
|
+
if (mem == (void*)-1) {
|
62
|
+
return NULL;
|
63
|
+
}
|
64
|
+
return (funchook_t*)mem;
|
65
|
+
}
|
66
|
+
|
67
|
+
int funchook_free(funchook_t *funchook)
|
68
|
+
{
|
69
|
+
size_t size = ROUND_UP(funchook_size, page_size);
|
70
|
+
munmap(funchook, size);
|
71
|
+
return 0;
|
72
|
+
}
|
73
|
+
|
74
|
+
#ifdef CPU_X86_64
|
75
|
+
|
76
|
+
typedef struct memory_map memory_map_t;
|
77
|
+
static int memory_map_open(funchook_t *funchook, memory_map_t *mmap);
|
78
|
+
static int memory_map_next(memory_map_t *mmap, size_t *start, size_t *end);
|
79
|
+
static void memory_map_close(memory_map_t *mmap);
|
80
|
+
|
81
|
+
#if defined(__linux)
|
82
|
+
static char scan_address(const char **str, size_t *addr_p)
|
83
|
+
{
|
84
|
+
size_t addr = 0;
|
85
|
+
const char *s = *str;
|
86
|
+
|
87
|
+
while (1) {
|
88
|
+
char c = *(s++);
|
89
|
+
|
90
|
+
if ('0' <= c && c <= '9') {
|
91
|
+
addr = (addr * 16) + (c - '0');
|
92
|
+
} else if ('a' <= c && c <= 'f') {
|
93
|
+
addr = (addr * 16) + (c - 'a' + 10);
|
94
|
+
} else {
|
95
|
+
*str = s;
|
96
|
+
*addr_p = addr;
|
97
|
+
return c;
|
98
|
+
}
|
99
|
+
}
|
100
|
+
}
|
101
|
+
|
102
|
+
struct memory_map {
|
103
|
+
funchook_io_t io;
|
104
|
+
};
|
105
|
+
|
106
|
+
static int memory_map_open(funchook_t *funchook, memory_map_t *mm)
|
107
|
+
{
|
108
|
+
char buf[64];
|
109
|
+
if (funchook_io_open(&mm->io, "/proc/self/maps", FUNCHOOK_IO_READ) != 0) {
|
110
|
+
funchook_set_error_message(funchook, "Failed to open /proc/self/maps (%s)",
|
111
|
+
funchook_strerror(errno, buf, sizeof(buf)));
|
112
|
+
return FUNCHOOK_ERROR_INTERNAL_ERROR;
|
113
|
+
}
|
114
|
+
return 0;
|
115
|
+
}
|
116
|
+
|
117
|
+
static int memory_map_next(memory_map_t *mm, size_t *start, size_t *end)
|
118
|
+
{
|
119
|
+
char buf[PATH_MAX];
|
120
|
+
const char *str = buf;
|
121
|
+
|
122
|
+
if (funchook_io_gets(buf, sizeof(buf), &mm->io) == NULL) {
|
123
|
+
return -1;
|
124
|
+
}
|
125
|
+
if (scan_address(&str, start) != '-') {
|
126
|
+
return -1;
|
127
|
+
}
|
128
|
+
if (scan_address(&str, end) != ' ') {
|
129
|
+
return -1;
|
130
|
+
}
|
131
|
+
return 0;
|
132
|
+
}
|
133
|
+
|
134
|
+
static void memory_map_close(memory_map_t *mm)
|
135
|
+
{
|
136
|
+
funchook_io_close(&mm->io);
|
137
|
+
}
|
138
|
+
|
139
|
+
#elif defined(__APPLE__)
|
140
|
+
|
141
|
+
struct memory_map {
|
142
|
+
mach_port_t task;
|
143
|
+
vm_address_t addr;
|
144
|
+
};
|
145
|
+
|
146
|
+
static int memory_map_open(funchook_t *funchook, memory_map_t *mm)
|
147
|
+
{
|
148
|
+
mm->task = mach_task_self();
|
149
|
+
mm->addr = 0;
|
150
|
+
return 0;
|
151
|
+
}
|
152
|
+
|
153
|
+
static int memory_map_next(memory_map_t *mm, size_t *start, size_t *end)
|
154
|
+
{
|
155
|
+
vm_size_t size;
|
156
|
+
vm_region_basic_info_data_64_t info;
|
157
|
+
mach_msg_type_number_t info_count = VM_REGION_BASIC_INFO_COUNT_64;
|
158
|
+
memory_object_name_t object = 0;
|
159
|
+
|
160
|
+
if (vm_region_64(mm->task, &mm->addr, &size, VM_REGION_BASIC_INFO_64, (vm_region_info_t)&info, &info_count, &object) != KERN_SUCCESS) {
|
161
|
+
return -1;
|
162
|
+
}
|
163
|
+
*start = mm->addr;
|
164
|
+
*end = mm->addr + size;
|
165
|
+
mm->addr += size;
|
166
|
+
return 0;
|
167
|
+
}
|
168
|
+
|
169
|
+
static void memory_map_close(memory_map_t *mm)
|
170
|
+
{
|
171
|
+
return;
|
172
|
+
}
|
173
|
+
|
174
|
+
#else
|
175
|
+
#error unsupported OS
|
176
|
+
#endif
|
177
|
+
|
178
|
+
static int get_free_address(funchook_t *funchook, void *func_addr, void *addrs[2])
|
179
|
+
{
|
180
|
+
memory_map_t mm;
|
181
|
+
size_t prev_end = 0;
|
182
|
+
size_t start, end;
|
183
|
+
int rv;
|
184
|
+
|
185
|
+
if ((rv = memory_map_open(funchook, &mm)) != 0) {
|
186
|
+
return rv;
|
187
|
+
}
|
188
|
+
addrs[0] = addrs[1] = NULL;
|
189
|
+
|
190
|
+
while (memory_map_next(&mm, &start, &end) == 0) {
|
191
|
+
funchook_log(funchook, " process map: %0"SIZE_T_WIDTH SIZE_T_FMT"x-%0"SIZE_T_WIDTH SIZE_T_FMT"x\n",
|
192
|
+
start, end);
|
193
|
+
if (prev_end + page_size <= start) {
|
194
|
+
if (start < (size_t)func_addr) {
|
195
|
+
size_t addr = start - page_size;
|
196
|
+
if ((size_t)func_addr - addr < INT32_MAX) {
|
197
|
+
/* unused memory region before func_addr. */
|
198
|
+
addrs[0] = (void*)addr;
|
199
|
+
}
|
200
|
+
}
|
201
|
+
if ((size_t)func_addr < prev_end) {
|
202
|
+
if (prev_end - (size_t)func_addr < INT32_MAX) {
|
203
|
+
/* unused memory region after func_addr. */
|
204
|
+
addrs[1] = (void*)prev_end;
|
205
|
+
}
|
206
|
+
funchook_log(funchook, " -- Use address %p or %p for function %p\n",
|
207
|
+
addrs[0], addrs[1], func_addr);
|
208
|
+
memory_map_close(&mm);
|
209
|
+
return 0;
|
210
|
+
}
|
211
|
+
}
|
212
|
+
prev_end = end;
|
213
|
+
}
|
214
|
+
memory_map_close(&mm);
|
215
|
+
funchook_set_error_message(funchook, "Could not find a free region near %p",
|
216
|
+
func_addr);
|
217
|
+
return FUNCHOOK_ERROR_MEMORY_ALLOCATION;
|
218
|
+
}
|
219
|
+
|
220
|
+
#endif /* CPU_X86_64 */
|
221
|
+
|
222
|
+
int funchook_page_alloc(funchook_t *funchook, funchook_page_t **page_out, uint8_t *func, rip_displacement_t *disp)
|
223
|
+
{
|
224
|
+
#ifdef CPU_X86_64
|
225
|
+
int loop_cnt;
|
226
|
+
|
227
|
+
/* Loop three times just to avoid rare cases such as
|
228
|
+
* unused memory region is used between 'get_free_address()'
|
229
|
+
* and 'mmap()'.
|
230
|
+
*/
|
231
|
+
for (loop_cnt = 0; loop_cnt < 3; loop_cnt++) {
|
232
|
+
void *addrs[2];
|
233
|
+
int rv = get_free_address(funchook, func, addrs);
|
234
|
+
int i;
|
235
|
+
|
236
|
+
if (rv != 0) {
|
237
|
+
return rv;
|
238
|
+
}
|
239
|
+
for (i = 1; i >= 0; i--) {
|
240
|
+
/* Try to use addr[1] (unused memory region after `func`)
|
241
|
+
* and then addr[0] (before `func`)
|
242
|
+
*/
|
243
|
+
if (addrs[i] == NULL) {
|
244
|
+
continue;
|
245
|
+
}
|
246
|
+
*page_out = mmap(addrs[i], page_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
247
|
+
if (*page_out == addrs[i]) {
|
248
|
+
funchook_log(funchook, " allocate page %p (size=%"SIZE_T_FMT"u)\n", *page_out, page_size);
|
249
|
+
return 0;
|
250
|
+
}
|
251
|
+
if (*page_out == MAP_FAILED) {
|
252
|
+
char errbuf[128];
|
253
|
+
|
254
|
+
funchook_set_error_message(funchook, "mmap failed(addr=%p): %s", addrs[i],
|
255
|
+
funchook_strerror(errno, errbuf, sizeof(errbuf)));
|
256
|
+
return FUNCHOOK_ERROR_MEMORY_ALLOCATION;
|
257
|
+
}
|
258
|
+
funchook_log(funchook, " try to allocate %p but %p (size=%"SIZE_T_FMT"u)\n", addrs[i], *page_out, page_size);
|
259
|
+
munmap(*page_out, page_size);
|
260
|
+
}
|
261
|
+
}
|
262
|
+
funchook_set_error_message(funchook, "Failed to allocate memory in unused regions");
|
263
|
+
return FUNCHOOK_ERROR_MEMORY_ALLOCATION;
|
264
|
+
#else
|
265
|
+
char errbuf[128];
|
266
|
+
|
267
|
+
*page_out = mmap(NULL, page_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
268
|
+
if (*page_out != MAP_FAILED) {
|
269
|
+
funchook_log(funchook, " allocate page %p (size=%"SIZE_T_FMT"u)\n", *page_out, page_size);
|
270
|
+
return 0;
|
271
|
+
}
|
272
|
+
funchook_set_error_message(funchook, "mmap failed: %s", funchook_strerror(errno, errbuf, sizeof(errbuf)));
|
273
|
+
return FUNCHOOK_ERROR_MEMORY_ALLOCATION;
|
274
|
+
#endif
|
275
|
+
}
|
276
|
+
|
277
|
+
int funchook_page_free(funchook_t *funchook, funchook_page_t *page)
|
278
|
+
{
|
279
|
+
char errbuf[128];
|
280
|
+
int rv = munmap(page, page_size);
|
281
|
+
|
282
|
+
if (rv == 0) {
|
283
|
+
funchook_log(funchook, " deallocate page %p (size=%"SIZE_T_FMT"u)\n",
|
284
|
+
page, page_size);
|
285
|
+
return 0;
|
286
|
+
}
|
287
|
+
funchook_set_error_message(funchook, "Failed to deallocate page %p (size=%"SIZE_T_FMT"u, error=%s)",
|
288
|
+
page, page_size,
|
289
|
+
funchook_strerror(errno, errbuf, sizeof(errbuf)));
|
290
|
+
return FUNCHOOK_ERROR_MEMORY_FUNCTION;
|
291
|
+
}
|
292
|
+
|
293
|
+
int funchook_page_protect(funchook_t *funchook, funchook_page_t *page)
|
294
|
+
{
|
295
|
+
char errbuf[128];
|
296
|
+
int rv = mprotect(page, page_size, PROT_READ | PROT_EXEC);
|
297
|
+
|
298
|
+
if (rv == 0) {
|
299
|
+
funchook_log(funchook, " protect page %p (size=%"SIZE_T_FMT"u)\n",
|
300
|
+
page, page_size);
|
301
|
+
return 0;
|
302
|
+
}
|
303
|
+
funchook_set_error_message(funchook, "Failed to protect page %p (size=%"SIZE_T_FMT"u, error=%s)",
|
304
|
+
page, page_size,
|
305
|
+
funchook_strerror(errno, errbuf, sizeof(errbuf)));
|
306
|
+
return FUNCHOOK_ERROR_MEMORY_FUNCTION;
|
307
|
+
}
|
308
|
+
|
309
|
+
int funchook_page_unprotect(funchook_t *funchook, funchook_page_t *page)
|
310
|
+
{
|
311
|
+
char errbuf[128];
|
312
|
+
int rv = mprotect(page, page_size, PROT_READ | PROT_WRITE);
|
313
|
+
|
314
|
+
if (rv == 0) {
|
315
|
+
funchook_log(funchook, " unprotect page %p (size=%"SIZE_T_FMT"u)\n",
|
316
|
+
page, page_size);
|
317
|
+
return 0;
|
318
|
+
}
|
319
|
+
funchook_set_error_message(funchook, "Failed to unprotect page %p (size=%"SIZE_T_FMT"u, error=%s)",
|
320
|
+
page, page_size,
|
321
|
+
funchook_strerror(errno, errbuf, sizeof(errbuf)));
|
322
|
+
return FUNCHOOK_ERROR_MEMORY_FUNCTION;
|
323
|
+
}
|
324
|
+
|
325
|
+
int funchook_unprotect_begin(funchook_t *funchook, mem_state_t *mstate, void *start, size_t len)
|
326
|
+
{
|
327
|
+
static int prot = PROT_READ | PROT_WRITE | PROT_EXEC;
|
328
|
+
char errbuf[128];
|
329
|
+
size_t saddr = ROUND_DOWN((size_t)start, page_size);
|
330
|
+
int rv;
|
331
|
+
|
332
|
+
mstate->addr = (void*)saddr;
|
333
|
+
mstate->size = len + (size_t)start - saddr;
|
334
|
+
mstate->size = ROUND_UP(mstate->size, page_size);
|
335
|
+
rv = mprotect(mstate->addr, mstate->size, prot);
|
336
|
+
if (rv == 0) {
|
337
|
+
funchook_log(funchook, " unprotect memory %p (size=%"SIZE_T_FMT"u, prot=read,write%s) <- %p (size=%"SIZE_T_FMT"u)\n",
|
338
|
+
mstate->addr, mstate->size, (prot & PROT_EXEC) ? ",exec" : "", start, len);
|
339
|
+
return 0;
|
340
|
+
}
|
341
|
+
if (rv == -1 && errno == EACCES && (prot & PROT_EXEC)) {
|
342
|
+
rv = mprotect(mstate->addr, mstate->size, PROT_READ | PROT_WRITE);
|
343
|
+
if (rv == 0) {
|
344
|
+
prot = PROT_READ | PROT_WRITE;
|
345
|
+
funchook_log(funchook, " unprotect memory %p (size=%"SIZE_T_FMT"u, prot=read,write) <- %p (size=%"SIZE_T_FMT"u)\n",
|
346
|
+
mstate->addr, mstate->size, start, len);
|
347
|
+
return 0;
|
348
|
+
}
|
349
|
+
}
|
350
|
+
funchook_set_error_message(funchook, "Failed to unprotect memory %p (size=%"SIZE_T_FMT"u, prot=read,write%s) <- %p (size=%"SIZE_T_FMT"u, error=%s)",
|
351
|
+
mstate->addr, mstate->size, (prot & PROT_EXEC) ? ",exec" : "", start, len,
|
352
|
+
funchook_strerror(errno, errbuf, sizeof(errbuf)));
|
353
|
+
return FUNCHOOK_ERROR_MEMORY_FUNCTION;
|
354
|
+
}
|
355
|
+
|
356
|
+
int funchook_unprotect_end(funchook_t *funchook, const mem_state_t *mstate)
|
357
|
+
{
|
358
|
+
char errbuf[128];
|
359
|
+
int rv = mprotect(mstate->addr, mstate->size, PROT_READ | PROT_EXEC);
|
360
|
+
|
361
|
+
if (rv == 0) {
|
362
|
+
funchook_log(funchook, " protect memory %p (size=%"SIZE_T_FMT"u, prot=read,exec)\n",
|
363
|
+
mstate->addr, mstate->size);
|
364
|
+
return 0;
|
365
|
+
}
|
366
|
+
funchook_set_error_message(funchook, "Failed to protect memory %p (size=%"SIZE_T_FMT"u, prot=read,exec, error=%s)",
|
367
|
+
mstate->addr, mstate->size,
|
368
|
+
funchook_strerror(errno, errbuf, sizeof(errbuf)));
|
369
|
+
return FUNCHOOK_ERROR_MEMORY_FUNCTION;
|
370
|
+
}
|
371
|
+
|
372
|
+
void *funchook_resolve_func(funchook_t *funchook, void *func)
|
373
|
+
{
|
374
|
+
#ifdef __GLIBC__
|
375
|
+
struct link_map *lmap, *lm;
|
376
|
+
const ElfW(Ehdr) *ehdr;
|
377
|
+
const ElfW(Dyn) *dyn;
|
378
|
+
const ElfW(Sym) *symtab = NULL;
|
379
|
+
const ElfW(Sym) *symtab_end = NULL;
|
380
|
+
const char *strtab = NULL;
|
381
|
+
size_t strtab_size = 0;
|
382
|
+
int i;
|
383
|
+
|
384
|
+
lmap = NULL;
|
385
|
+
for (lm = _r_debug.r_map; lm != NULL; lm = lm->l_next) {
|
386
|
+
if ((void*)lm->l_addr <= func) {
|
387
|
+
if (lmap == NULL) {
|
388
|
+
lmap = lm;
|
389
|
+
} else if (lmap->l_addr > lm->l_addr) {
|
390
|
+
lmap = lm;
|
391
|
+
}
|
392
|
+
}
|
393
|
+
}
|
394
|
+
if (lmap == NULL) {
|
395
|
+
return func;
|
396
|
+
}
|
397
|
+
if (lmap->l_addr != 0) {
|
398
|
+
ehdr = (ElfW(Ehdr) *)lmap->l_addr;
|
399
|
+
if (memcmp(ehdr->e_ident, ELFMAG, SELFMAG) != 0) {
|
400
|
+
funchook_log(funchook, " not a valid ELF module %s.\n", lmap->l_name);
|
401
|
+
return func;
|
402
|
+
}
|
403
|
+
if (ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN) {
|
404
|
+
funchook_log(funchook, " ELF type is neither ET_EXEC nor ET_DYN.\n");
|
405
|
+
return func;
|
406
|
+
}
|
407
|
+
}
|
408
|
+
funchook_log(funchook, " link_map addr=%p, name=%s\n", (void*)lmap->l_addr, lmap->l_name);
|
409
|
+
dyn = lmap->l_ld;
|
410
|
+
|
411
|
+
for (i = 0; dyn[i].d_tag != DT_NULL; i++) {
|
412
|
+
switch (dyn[i].d_tag) {
|
413
|
+
case DT_SYMTAB:
|
414
|
+
symtab = (const ElfW(Sym) *)dyn[i].d_un.d_ptr;
|
415
|
+
break;
|
416
|
+
case DT_STRTAB:
|
417
|
+
strtab = (const char *)dyn[i].d_un.d_ptr;
|
418
|
+
break;
|
419
|
+
case DT_STRSZ:
|
420
|
+
strtab_size = dyn[i].d_un.d_val;
|
421
|
+
break;
|
422
|
+
}
|
423
|
+
}
|
424
|
+
symtab_end = (const ElfW(Sym) *)strtab;
|
425
|
+
while (symtab < symtab_end) {
|
426
|
+
if (symtab->st_name >= strtab_size) {
|
427
|
+
break;
|
428
|
+
}
|
429
|
+
if (ELF64_ST_TYPE(symtab->st_info) == STT_FUNC &&
|
430
|
+
symtab->st_size == 0 && (void*)symtab->st_value == func) {
|
431
|
+
void *fn = dlsym(RTLD_DEFAULT, strtab + symtab->st_name);
|
432
|
+
if (fn == func) {
|
433
|
+
fn = dlsym(RTLD_NEXT, strtab + symtab->st_name);
|
434
|
+
}
|
435
|
+
if (fn != NULL) {
|
436
|
+
funchook_log(funchook, " change %s address from %p to %p\n",
|
437
|
+
strtab + symtab->st_name, func, fn);
|
438
|
+
func = fn;
|
439
|
+
}
|
440
|
+
break;
|
441
|
+
}
|
442
|
+
symtab++;
|
443
|
+
}
|
444
|
+
#endif
|
445
|
+
return func;
|
446
|
+
}
|
447
|
+
|
448
|
+
#ifndef HAVE_DECL__SYS_NERR
|
449
|
+
#define HAVE_DECL__SYS_NERR 0
|
450
|
+
#endif
|
451
|
+
#ifndef HAVE_DECL__SYS_ERRLIST
|
452
|
+
#define HAVE_DECL__SYS_ERRLIST 0
|
453
|
+
#endif
|
454
|
+
#ifndef HAVE_DECL_SYS_NERR
|
455
|
+
#define HAVE_DECL_SYS_NERR 0
|
456
|
+
#endif
|
457
|
+
#ifndef HAVE_DECL_SYS_ERRLIST
|
458
|
+
#define HAVE_DECL_SYS_ERRLIST 0
|
459
|
+
#endif
|
460
|
+
|
461
|
+
const char *funchook_strerror(int errnum, char *buf, size_t buflen)
|
462
|
+
{
|
463
|
+
#if HAVE_DECL__SYS_NERR && HAVE_DECL__SYS_ERRLIST
|
464
|
+
if (0 <= errnum && errnum < _sys_nerr) {
|
465
|
+
return _sys_errlist[errnum];
|
466
|
+
}
|
467
|
+
#elif HAVE_DECL_SYS_NERR && HAVE_DECL_SYS_ERRLIST
|
468
|
+
if (0 <= errnum && errnum < sys_nerr) {
|
469
|
+
return sys_errlist[errnum];
|
470
|
+
}
|
471
|
+
#else
|
472
|
+
switch (errnum) {
|
473
|
+
#undef E
|
474
|
+
#define E(err, msg) case err: return msg;
|
475
|
+
#include "__strerror.h" /* header file copied from musl libc */
|
476
|
+
}
|
477
|
+
#endif
|
478
|
+
funchook_snprintf(buf, buflen, "Unknown error (%d)", errnum);
|
479
|
+
return buf;
|
480
|
+
}
|