src/internal/hook_backend_visit.hpp
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | #ifndef DETOURMODKIT_INTERNAL_HOOK_BACKEND_VISIT_HPP | ||
| 2 | #define DETOURMODKIT_INTERNAL_HOOK_BACKEND_VISIT_HPP | ||
| 3 | |||
| 4 | /** | ||
| 5 | * @file internal/hook_backend_visit.hpp | ||
| 6 | * @brief Nothrow visitation and toggle primitives over the inline/mid backend variant. | ||
| 7 | * @details The hook sibling TUs (src/hook.cpp and src/hook_toggle.cpp) share these helpers, so each visitation and | ||
| 8 | * exception-containment contract is stated exactly once. Every helper is noexcept and contains backend | ||
| 9 | * synchronization or allocation exceptions at this boundary. | ||
| 10 | */ | ||
| 11 | |||
| 12 | #include "internal/hook_patch_witness.hpp" | ||
| 13 | |||
| 14 | #include <safetyhook.hpp> | ||
| 15 | |||
| 16 | #include <atomic> | ||
| 17 | #include <cstddef> | ||
| 18 | #include <type_traits> | ||
| 19 | #include <utility> | ||
| 20 | #include <variant> | ||
| 21 | |||
| 22 | namespace DetourModKit::detail | ||
| 23 | { | ||
| 24 | #if defined(DMK_ENABLE_TEST_SEAMS) | ||
| 25 | // Overrides the byte witness Hook::enable() takes after the backend reports a successful patch. The suite can | ||
| 26 | // then drive the negative branch a real backend does not produce on demand. | ||
| 27 | extern bool (*g_hook_enable_witness_override)(bool) noexcept; | ||
| 28 | // Runs after a managed backend disable returns or throws and before DMK witnesses its target bytes. | ||
| 29 | extern void (*g_hook_backend_disable_probe)() noexcept; | ||
| 30 | // Counts managed backend toggle exceptions the containment boundaries below reached and contained. | ||
| 31 | extern std::atomic<std::size_t> g_backend_toggle_exception_catches; | ||
| 32 | #endif | ||
| 33 | |||
| 34 | /** | ||
| 35 | * @brief Returns the inline trampoline pointer for a hook backend, or nullptr for a mid hook / empty backend. | ||
| 36 | * @details The @ref hook::Hook::CallGate publishes this value while an inline hook is armed. | ||
| 37 | */ | ||
| 38 | [[nodiscard]] inline void * | ||
| 39 | 3940 | inline_trampoline(const std::variant<safetyhook::InlineHook, safetyhook::MidHook> &backend) noexcept | |
| 40 | { | ||
| 41 | 3940 | const auto *inline_backend = std::get_if<safetyhook::InlineHook>(&backend); | |
| 42 |
5/6✓ Branch 3 → 4 taken 3881 times.
✓ Branch 3 → 6 taken 59 times.
✗ Branch 5 → 6 not taken.
✓ Branch 5 → 7 taken 3881 times.
✓ Branch 8 → 9 taken 59 times.
✓ Branch 8 → 10 taken 3881 times.
|
3940 | if (inline_backend == nullptr || !*inline_backend) |
| 43 | { | ||
| 44 | 59 | return nullptr; | |
| 45 | } | ||
| 46 | 3881 | return inline_backend->original<void *>(); | |
| 47 | } | ||
| 48 | |||
| 49 | /// Applies a visitor that does not throw, or returns @p fallback when no managed backend is active. | ||
| 50 | template <typename ValueT, typename BackendVariant, typename Visitor> | ||
| 51 | 33001 | [[nodiscard]] ValueT backend_value_or(BackendVariant &backend, ValueT fallback, Visitor &&visitor) noexcept | |
| 52 | { | ||
| 53 | using InlineReference = decltype(*std::get_if<safetyhook::InlineHook>(&backend)); | ||
| 54 | using MidReference = decltype(*std::get_if<safetyhook::MidHook>(&backend)); | ||
| 55 | static_assert(std::is_nothrow_invocable_r_v<ValueT, Visitor, InlineReference>); | ||
| 56 | static_assert(std::is_nothrow_invocable_r_v<ValueT, Visitor, MidReference>); | ||
| 57 | |||
| 58 |
22/22DetourModKit::detail::PatchWitness DetourModKit::detail::backend_value_or<DetourModKit::detail::PatchWitness, std::variant<safetyhook::InlineHook, safetyhook::MidHook>, DetourModKit::detail::witness_of<std::variant<safetyhook::InlineHook, safetyhook::MidHook> >(std::variant<safetyhook::InlineHook, safetyhook::MidHook>&)::{lambda(auto:1&)#1}>(std::variant<safetyhook::InlineHook, safetyhook::MidHook>&, DetourModKit::detail::PatchWitness, DetourModKit::detail::witness_of<std::variant<safetyhook::InlineHook, safetyhook::MidHook> >(std::variant<safetyhook::InlineHook, safetyhook::MidHook>&)::{lambda(auto:1&)#1}&&):
✓ Branch 3 → 4 taken 11399 times.
✓ Branch 3 → 7 taken 538 times.
bool DetourModKit::detail::backend_value_or<bool, std::variant<safetyhook::InlineHook, safetyhook::MidHook>, DetourModKit::hook::Hook::is_enabled() const::{lambda(auto:1&)#1}>(std::variant<safetyhook::InlineHook, safetyhook::MidHook>&, bool, DetourModKit::hook::Hook::is_enabled() const::{lambda(auto:1&)#1}&&):
✓ Branch 3 → 4 taken 1071 times.
✓ Branch 3 → 7 taken 15 times.
bool DetourModKit::detail::backend_value_or<bool, std::variant<safetyhook::InlineHook, safetyhook::MidHook>, DetourModKit::(anonymous namespace)::run_teardown_restore<std::variant<safetyhook::InlineHook, safetyhook::MidHook> >(std::variant<safetyhook::InlineHook, safetyhook::MidHook>&)::{lambda(auto:1&)#1}>(std::variant<safetyhook::InlineHook, safetyhook::MidHook>&, bool, DetourModKit::(anonymous namespace)::run_teardown_restore<std::variant<safetyhook::InlineHook, safetyhook::MidHook> >(std::variant<safetyhook::InlineHook, safetyhook::MidHook>&)::{lambda(auto:1&)#1}&&):
✓ Branch 3 → 4 taken 260 times.
✓ Branch 3 → 7 taken 216 times.
bool DetourModKit::detail::backend_value_or<bool, std::variant<safetyhook::InlineHook, safetyhook::MidHook>, DetourModKit::hook::Hook::enable()::{lambda(auto:1&)#2}>(std::variant<safetyhook::InlineHook, safetyhook::MidHook>&, bool, DetourModKit::hook::Hook::enable()::{lambda(auto:1&)#2}&&):
✓ Branch 3 → 4 taken 3745 times.
✓ Branch 3 → 7 taken 61 times.
bool DetourModKit::detail::backend_value_or<bool, std::variant<safetyhook::InlineHook, safetyhook::MidHook>, DetourModKit::hook::Hook::enable()::{lambda(auto:1&)#3}>(std::variant<safetyhook::InlineHook, safetyhook::MidHook>&, bool, DetourModKit::hook::Hook::enable()::{lambda(auto:1&)#3}&&):
✓ Branch 3 → 4 taken 3745 times.
✓ Branch 3 → 7 taken 61 times.
bool DetourModKit::detail::backend_value_or<bool, std::variant<safetyhook::InlineHook, safetyhook::MidHook>, DetourModKit::hook::Hook::enable()::{lambda(auto:1&)#4}>(std::variant<safetyhook::InlineHook, safetyhook::MidHook>&, bool, DetourModKit::hook::Hook::enable()::{lambda(auto:1&)#4}&&):
✓ Branch 3 → 4 taken 9 times.
✓ Branch 3 → 7 taken 2 times.
bool DetourModKit::detail::backend_value_or<bool, std::variant<safetyhook::InlineHook, safetyhook::MidHook>, DetourModKit::hook::Hook::enable()::{lambda(auto:1&)#6}>(std::variant<safetyhook::InlineHook, safetyhook::MidHook>&, bool, DetourModKit::hook::Hook::enable()::{lambda(auto:1&)#6}&&):
✓ Branch 3 → 4 taken 4 times.
✓ Branch 3 → 7 taken 4 times.
bool DetourModKit::detail::backend_value_or<bool, std::variant<safetyhook::InlineHook, safetyhook::MidHook>, DetourModKit::hook::Hook::enable()::{lambda(auto:1&)#1}>(std::variant<safetyhook::InlineHook, safetyhook::MidHook>&, bool, DetourModKit::hook::Hook::enable()::{lambda(auto:1&)#1}&&):
✓ Branch 3 → 4 taken 3764 times.
✓ Branch 3 → 7 taken 62 times.
bool DetourModKit::detail::backend_value_or<bool, std::variant<safetyhook::InlineHook, safetyhook::MidHook>, DetourModKit::hook::Hook::disable()::{lambda(auto:1&)#2}>(std::variant<safetyhook::InlineHook, safetyhook::MidHook>&, bool, DetourModKit::hook::Hook::disable()::{lambda(auto:1&)#2}&&):
✓ Branch 3 → 4 taken 3538 times.
✓ Branch 3 → 7 taken 14 times.
bool DetourModKit::detail::backend_value_or<bool, std::variant<safetyhook::InlineHook, safetyhook::MidHook>, DetourModKit::hook::Hook::disable()::{lambda(auto:1&)#1}>(std::variant<safetyhook::InlineHook, safetyhook::MidHook>&, bool, DetourModKit::hook::Hook::disable()::{lambda(auto:1&)#1}&&):
✓ Branch 3 → 4 taken 3557 times.
✓ Branch 3 → 7 taken 14 times.
unsigned long long DetourModKit::detail::backend_value_or<unsigned long long, std::variant<safetyhook::InlineHook, safetyhook::MidHook>, DetourModKit::(anonymous namespace)::drain_backend_route<std::variant<safetyhook::InlineHook, safetyhook::MidHook> >(std::variant<safetyhook::InlineHook, safetyhook::MidHook>&)::{lambda()#1}::operator()() const::{lambda(auto:1 const&)#1}>(std::variant<safetyhook::InlineHook, safetyhook::MidHook>&, unsigned long long, DetourModKit::(anonymous namespace)::drain_backend_route<std::variant<safetyhook::InlineHook, safetyhook::MidHook> >(std::variant<safetyhook::InlineHook, safetyhook::MidHook>&)::{lambda()#1}::operator()() const::{lambda(auto:1 const&)#1}&&):
✓ Branch 3 → 4 taken 259 times.
✓ Branch 3 → 8 taken 663 times.
|
33001 | if (auto *inline_backend = std::get_if<safetyhook::InlineHook>(&backend)) |
| 59 | { | ||
| 60 | 31351 | return std::forward<Visitor>(visitor)(*inline_backend); | |
| 61 | } | ||
| 62 |
11/22DetourModKit::detail::PatchWitness DetourModKit::detail::backend_value_or<DetourModKit::detail::PatchWitness, std::variant<safetyhook::InlineHook, safetyhook::MidHook>, DetourModKit::detail::witness_of<std::variant<safetyhook::InlineHook, safetyhook::MidHook> >(std::variant<safetyhook::InlineHook, safetyhook::MidHook>&)::{lambda(auto:1&)#1}>(std::variant<safetyhook::InlineHook, safetyhook::MidHook>&, DetourModKit::detail::PatchWitness, DetourModKit::detail::witness_of<std::variant<safetyhook::InlineHook, safetyhook::MidHook> >(std::variant<safetyhook::InlineHook, safetyhook::MidHook>&)::{lambda(auto:1&)#1}&&):
✓ Branch 8 → 9 taken 538 times.
✗ Branch 8 → 12 not taken.
bool DetourModKit::detail::backend_value_or<bool, std::variant<safetyhook::InlineHook, safetyhook::MidHook>, DetourModKit::hook::Hook::is_enabled() const::{lambda(auto:1&)#1}>(std::variant<safetyhook::InlineHook, safetyhook::MidHook>&, bool, DetourModKit::hook::Hook::is_enabled() const::{lambda(auto:1&)#1}&&):
✓ Branch 8 → 9 taken 15 times.
✗ Branch 8 → 12 not taken.
bool DetourModKit::detail::backend_value_or<bool, std::variant<safetyhook::InlineHook, safetyhook::MidHook>, DetourModKit::(anonymous namespace)::run_teardown_restore<std::variant<safetyhook::InlineHook, safetyhook::MidHook> >(std::variant<safetyhook::InlineHook, safetyhook::MidHook>&)::{lambda(auto:1&)#1}>(std::variant<safetyhook::InlineHook, safetyhook::MidHook>&, bool, DetourModKit::(anonymous namespace)::run_teardown_restore<std::variant<safetyhook::InlineHook, safetyhook::MidHook> >(std::variant<safetyhook::InlineHook, safetyhook::MidHook>&)::{lambda(auto:1&)#1}&&):
✓ Branch 8 → 9 taken 216 times.
✗ Branch 8 → 12 not taken.
bool DetourModKit::detail::backend_value_or<bool, std::variant<safetyhook::InlineHook, safetyhook::MidHook>, DetourModKit::hook::Hook::enable()::{lambda(auto:1&)#2}>(std::variant<safetyhook::InlineHook, safetyhook::MidHook>&, bool, DetourModKit::hook::Hook::enable()::{lambda(auto:1&)#2}&&):
✓ Branch 8 → 9 taken 61 times.
✗ Branch 8 → 12 not taken.
bool DetourModKit::detail::backend_value_or<bool, std::variant<safetyhook::InlineHook, safetyhook::MidHook>, DetourModKit::hook::Hook::enable()::{lambda(auto:1&)#3}>(std::variant<safetyhook::InlineHook, safetyhook::MidHook>&, bool, DetourModKit::hook::Hook::enable()::{lambda(auto:1&)#3}&&):
✓ Branch 8 → 9 taken 61 times.
✗ Branch 8 → 12 not taken.
bool DetourModKit::detail::backend_value_or<bool, std::variant<safetyhook::InlineHook, safetyhook::MidHook>, DetourModKit::hook::Hook::enable()::{lambda(auto:1&)#4}>(std::variant<safetyhook::InlineHook, safetyhook::MidHook>&, bool, DetourModKit::hook::Hook::enable()::{lambda(auto:1&)#4}&&):
✓ Branch 8 → 9 taken 2 times.
✗ Branch 8 → 12 not taken.
bool DetourModKit::detail::backend_value_or<bool, std::variant<safetyhook::InlineHook, safetyhook::MidHook>, DetourModKit::hook::Hook::enable()::{lambda(auto:1&)#6}>(std::variant<safetyhook::InlineHook, safetyhook::MidHook>&, bool, DetourModKit::hook::Hook::enable()::{lambda(auto:1&)#6}&&):
✓ Branch 8 → 9 taken 4 times.
✗ Branch 8 → 12 not taken.
bool DetourModKit::detail::backend_value_or<bool, std::variant<safetyhook::InlineHook, safetyhook::MidHook>, DetourModKit::hook::Hook::enable()::{lambda(auto:1&)#1}>(std::variant<safetyhook::InlineHook, safetyhook::MidHook>&, bool, DetourModKit::hook::Hook::enable()::{lambda(auto:1&)#1}&&):
✓ Branch 8 → 9 taken 62 times.
✗ Branch 8 → 12 not taken.
bool DetourModKit::detail::backend_value_or<bool, std::variant<safetyhook::InlineHook, safetyhook::MidHook>, DetourModKit::hook::Hook::disable()::{lambda(auto:1&)#2}>(std::variant<safetyhook::InlineHook, safetyhook::MidHook>&, bool, DetourModKit::hook::Hook::disable()::{lambda(auto:1&)#2}&&):
✓ Branch 8 → 9 taken 14 times.
✗ Branch 8 → 12 not taken.
bool DetourModKit::detail::backend_value_or<bool, std::variant<safetyhook::InlineHook, safetyhook::MidHook>, DetourModKit::hook::Hook::disable()::{lambda(auto:1&)#1}>(std::variant<safetyhook::InlineHook, safetyhook::MidHook>&, bool, DetourModKit::hook::Hook::disable()::{lambda(auto:1&)#1}&&):
✓ Branch 8 → 9 taken 14 times.
✗ Branch 8 → 12 not taken.
unsigned long long DetourModKit::detail::backend_value_or<unsigned long long, std::variant<safetyhook::InlineHook, safetyhook::MidHook>, DetourModKit::(anonymous namespace)::drain_backend_route<std::variant<safetyhook::InlineHook, safetyhook::MidHook> >(std::variant<safetyhook::InlineHook, safetyhook::MidHook>&)::{lambda()#1}::operator()() const::{lambda(auto:1 const&)#1}>(std::variant<safetyhook::InlineHook, safetyhook::MidHook>&, unsigned long long, DetourModKit::(anonymous namespace)::drain_backend_route<std::variant<safetyhook::InlineHook, safetyhook::MidHook> >(std::variant<safetyhook::InlineHook, safetyhook::MidHook>&)::{lambda()#1}::operator()() const::{lambda(auto:1 const&)#1}&&):
✓ Branch 9 → 10 taken 663 times.
✗ Branch 9 → 14 not taken.
|
1650 | if (auto *mid_backend = std::get_if<safetyhook::MidHook>(&backend)) |
| 63 | { | ||
| 64 | 1650 | return std::forward<Visitor>(visitor)(*mid_backend); | |
| 65 | } | ||
| 66 | ✗ | return fallback; | |
| 67 | } | ||
| 68 | |||
| 69 | /// Applies a visitor that does not throw and reports whether a managed backend is active. | ||
| 70 | template <typename BackendVariant, typename Visitor> | ||
| 71 | 5014 | [[nodiscard]] bool apply_backend(BackendVariant &backend, Visitor &&visitor) noexcept | |
| 72 | { | ||
| 73 | using InlineReference = decltype(*std::get_if<safetyhook::InlineHook>(&backend)); | ||
| 74 | using MidReference = decltype(*std::get_if<safetyhook::MidHook>(&backend)); | ||
| 75 | static_assert(std::is_nothrow_invocable_v<Visitor, InlineReference>); | ||
| 76 | static_assert(std::is_nothrow_invocable_v<Visitor, MidReference>); | ||
| 77 | |||
| 78 |
19/20bool DetourModKit::detail::apply_backend<std::variant<safetyhook::InlineHook, safetyhook::MidHook>, DetourModKit::(anonymous namespace)::run_teardown_restore<std::variant<safetyhook::InlineHook, safetyhook::MidHook> >(std::variant<safetyhook::InlineHook, safetyhook::MidHook>&)::{lambda(auto:1&)#2}>(std::variant<safetyhook::InlineHook, safetyhook::MidHook>&, DetourModKit::(anonymous namespace)::run_teardown_restore<std::variant<safetyhook::InlineHook, safetyhook::MidHook> >(std::variant<safetyhook::InlineHook, safetyhook::MidHook>&)::{lambda(auto:1&)#2}&&):
✓ Branch 3 → 4 taken 259 times.
✓ Branch 3 → 8 taken 215 times.
bool DetourModKit::detail::apply_backend<std::variant<safetyhook::InlineHook, safetyhook::MidHook>, DetourModKit::hook::(anonymous namespace)::reconcile_published_state<DetourModKit::hook::Hook::Impl, DetourModKit::hook::Hook::CallGate>(DetourModKit::hook::Hook::Impl&, DetourModKit::hook::Hook::CallGate&, bool)::{lambda(auto:1&)#1}>(DetourModKit::hook::Hook::Impl&, DetourModKit::hook::Hook::CallGate&&):
✓ Branch 3 → 4 taken 2 times.
✗ Branch 3 → 8 not taken.
bool DetourModKit::detail::apply_backend<std::variant<safetyhook::InlineHook, safetyhook::MidHook>, DetourModKit::hook::Hook::enable()::{lambda(auto:1&)#5}>(std::variant<safetyhook::InlineHook, safetyhook::MidHook>&, DetourModKit::hook::Hook::enable()::{lambda(auto:1&)#5}&&):
✓ Branch 3 → 4 taken 1 time.
✓ Branch 3 → 8 taken 1 time.
bool DetourModKit::detail::apply_backend<std::variant<safetyhook::InlineHook, safetyhook::MidHook>, DetourModKit::hook::Hook::enable()::{lambda(auto:1&)#7}>(std::variant<safetyhook::InlineHook, safetyhook::MidHook>&, DetourModKit::hook::Hook::enable()::{lambda(auto:1&)#7}&&):
✓ Branch 3 → 4 taken 2 times.
✓ Branch 3 → 8 taken 2 times.
bool DetourModKit::detail::apply_backend<std::variant<safetyhook::InlineHook, safetyhook::MidHook>, DetourModKit::hook::Hook::enable()::{lambda(auto:1&)#8}>(std::variant<safetyhook::InlineHook, safetyhook::MidHook>&, DetourModKit::hook::Hook::enable()::{lambda(auto:1&)#8}&&):
✓ Branch 3 → 4 taken 4 times.
✓ Branch 3 → 8 taken 2 times.
bool DetourModKit::detail::apply_backend<std::variant<safetyhook::InlineHook, safetyhook::MidHook>, DetourModKit::hook::Hook::disable()::{lambda(auto:1&)#3}>(std::variant<safetyhook::InlineHook, safetyhook::MidHook>&, DetourModKit::hook::Hook::disable()::{lambda(auto:1&)#3}&&):
✓ Branch 3 → 4 taken 3536 times.
✓ Branch 3 → 8 taken 11 times.
bool DetourModKit::detail::apply_backend<std::variant<safetyhook::InlineHook, safetyhook::MidHook>, DetourModKit::hook::Hook::disable()::{lambda(auto:1&)#4}>(std::variant<safetyhook::InlineHook, safetyhook::MidHook>&, DetourModKit::hook::Hook::disable()::{lambda(auto:1&)#4}&&):
✓ Branch 3 → 4 taken 2 times.
✓ Branch 3 → 8 taken 3 times.
bool DetourModKit::detail::apply_backend<std::variant<safetyhook::InlineHook, safetyhook::MidHook>, DetourModKit::hook::Hook::~Hook()::{lambda(auto:1&)#2}>(std::variant<safetyhook::InlineHook, safetyhook::MidHook>&, DetourModKit::hook::Hook::~Hook()::{lambda(auto:1&)#2}&&):
✓ Branch 3 → 4 taken 9 times.
✓ Branch 3 → 8 taken 4 times.
bool DetourModKit::detail::apply_backend<std::variant<safetyhook::InlineHook, safetyhook::MidHook>, DetourModKit::hook::Hook::~Hook()::{lambda(auto:1&)#3}>(std::variant<safetyhook::InlineHook, safetyhook::MidHook>&, DetourModKit::hook::Hook::~Hook()::{lambda(auto:1&)#3}&&):
✓ Branch 3 → 4 taken 259 times.
✓ Branch 3 → 8 taken 215 times.
bool DetourModKit::detail::apply_backend<std::variant<safetyhook::InlineHook, safetyhook::MidHook>, DetourModKit::hook::Hook::~Hook()::{lambda(auto:1&)#1}>(std::variant<safetyhook::InlineHook, safetyhook::MidHook>&, DetourModKit::hook::Hook::~Hook()::{lambda(auto:1&)#1}&&):
✓ Branch 3 → 4 taken 268 times.
✓ Branch 3 → 8 taken 219 times.
|
5014 | if (auto *inline_backend = std::get_if<safetyhook::InlineHook>(&backend)) |
| 79 | { | ||
| 80 | 4342 | std::forward<Visitor>(visitor)(*inline_backend); | |
| 81 | 4342 | return true; | |
| 82 | } | ||
| 83 |
9/20bool DetourModKit::detail::apply_backend<std::variant<safetyhook::InlineHook, safetyhook::MidHook>, DetourModKit::(anonymous namespace)::run_teardown_restore<std::variant<safetyhook::InlineHook, safetyhook::MidHook> >(std::variant<safetyhook::InlineHook, safetyhook::MidHook>&)::{lambda(auto:1&)#2}>(std::variant<safetyhook::InlineHook, safetyhook::MidHook>&, DetourModKit::(anonymous namespace)::run_teardown_restore<std::variant<safetyhook::InlineHook, safetyhook::MidHook> >(std::variant<safetyhook::InlineHook, safetyhook::MidHook>&)::{lambda(auto:1&)#2}&&):
✓ Branch 9 → 10 taken 215 times.
✗ Branch 9 → 14 not taken.
bool DetourModKit::detail::apply_backend<std::variant<safetyhook::InlineHook, safetyhook::MidHook>, DetourModKit::hook::(anonymous namespace)::reconcile_published_state<DetourModKit::hook::Hook::Impl, DetourModKit::hook::Hook::CallGate>(DetourModKit::hook::Hook::Impl&, DetourModKit::hook::Hook::CallGate&, bool)::{lambda(auto:1&)#1}>(DetourModKit::hook::Hook::Impl&, DetourModKit::hook::Hook::CallGate&&):
✗ Branch 9 → 10 not taken.
✗ Branch 9 → 14 not taken.
bool DetourModKit::detail::apply_backend<std::variant<safetyhook::InlineHook, safetyhook::MidHook>, DetourModKit::hook::Hook::enable()::{lambda(auto:1&)#5}>(std::variant<safetyhook::InlineHook, safetyhook::MidHook>&, DetourModKit::hook::Hook::enable()::{lambda(auto:1&)#5}&&):
✓ Branch 9 → 10 taken 1 time.
✗ Branch 9 → 14 not taken.
bool DetourModKit::detail::apply_backend<std::variant<safetyhook::InlineHook, safetyhook::MidHook>, DetourModKit::hook::Hook::enable()::{lambda(auto:1&)#7}>(std::variant<safetyhook::InlineHook, safetyhook::MidHook>&, DetourModKit::hook::Hook::enable()::{lambda(auto:1&)#7}&&):
✓ Branch 9 → 10 taken 2 times.
✗ Branch 9 → 14 not taken.
bool DetourModKit::detail::apply_backend<std::variant<safetyhook::InlineHook, safetyhook::MidHook>, DetourModKit::hook::Hook::enable()::{lambda(auto:1&)#8}>(std::variant<safetyhook::InlineHook, safetyhook::MidHook>&, DetourModKit::hook::Hook::enable()::{lambda(auto:1&)#8}&&):
✓ Branch 9 → 10 taken 2 times.
✗ Branch 9 → 14 not taken.
bool DetourModKit::detail::apply_backend<std::variant<safetyhook::InlineHook, safetyhook::MidHook>, DetourModKit::hook::Hook::disable()::{lambda(auto:1&)#3}>(std::variant<safetyhook::InlineHook, safetyhook::MidHook>&, DetourModKit::hook::Hook::disable()::{lambda(auto:1&)#3}&&):
✓ Branch 9 → 10 taken 11 times.
✗ Branch 9 → 14 not taken.
bool DetourModKit::detail::apply_backend<std::variant<safetyhook::InlineHook, safetyhook::MidHook>, DetourModKit::hook::Hook::disable()::{lambda(auto:1&)#4}>(std::variant<safetyhook::InlineHook, safetyhook::MidHook>&, DetourModKit::hook::Hook::disable()::{lambda(auto:1&)#4}&&):
✓ Branch 9 → 10 taken 3 times.
✗ Branch 9 → 14 not taken.
bool DetourModKit::detail::apply_backend<std::variant<safetyhook::InlineHook, safetyhook::MidHook>, DetourModKit::hook::Hook::~Hook()::{lambda(auto:1&)#2}>(std::variant<safetyhook::InlineHook, safetyhook::MidHook>&, DetourModKit::hook::Hook::~Hook()::{lambda(auto:1&)#2}&&):
✓ Branch 9 → 10 taken 4 times.
✗ Branch 9 → 14 not taken.
bool DetourModKit::detail::apply_backend<std::variant<safetyhook::InlineHook, safetyhook::MidHook>, DetourModKit::hook::Hook::~Hook()::{lambda(auto:1&)#3}>(std::variant<safetyhook::InlineHook, safetyhook::MidHook>&, DetourModKit::hook::Hook::~Hook()::{lambda(auto:1&)#3}&&):
✓ Branch 9 → 10 taken 215 times.
✗ Branch 9 → 14 not taken.
bool DetourModKit::detail::apply_backend<std::variant<safetyhook::InlineHook, safetyhook::MidHook>, DetourModKit::hook::Hook::~Hook()::{lambda(auto:1&)#1}>(std::variant<safetyhook::InlineHook, safetyhook::MidHook>&, DetourModKit::hook::Hook::~Hook()::{lambda(auto:1&)#1}&&):
✓ Branch 9 → 10 taken 219 times.
✗ Branch 9 → 14 not taken.
|
672 | if (auto *mid_backend = std::get_if<safetyhook::MidHook>(&backend)) |
| 84 | { | ||
| 85 | 672 | std::forward<Visitor>(visitor)(*mid_backend); | |
| 86 | 672 | return true; | |
| 87 | } | ||
| 88 | ✗ | return false; | |
| 89 | } | ||
| 90 | |||
| 91 | /** | ||
| 92 | * @brief Reports whether the backend left this hook's own patch armed after a target toggle. | ||
| 93 | * @details enable() publishes Active only for bytes it can attribute to itself. | ||
| 94 | */ | ||
| 95 | 3806 | template <class Backend> [[nodiscard]] bool enable_patch_is_confirmed(const Backend &backend) noexcept | |
| 96 | { | ||
| 97 |
6/8bool DetourModKit::detail::enable_patch_is_confirmed<safetyhook::InlineHook>(safetyhook::InlineHook const&):
✓ Branch 3 → 4 taken 3744 times.
✓ Branch 3 → 7 taken 1 time.
✓ Branch 5 → 6 taken 3744 times.
✗ Branch 5 → 7 not taken.
bool DetourModKit::detail::enable_patch_is_confirmed<safetyhook::MidHook>(safetyhook::MidHook const&):
✓ Branch 3 → 4 taken 60 times.
✓ Branch 3 → 7 taken 1 time.
✓ Branch 5 → 6 taken 60 times.
✗ Branch 5 → 7 not taken.
|
3806 | const bool confirmed = backend.enabled() && detail::witness_patch(backend) == detail::PatchWitness::OwnedPatch; |
| 98 | #if defined(DMK_ENABLE_TEST_SEAMS) | ||
| 99 |
4/4bool DetourModKit::detail::enable_patch_is_confirmed<safetyhook::InlineHook>(safetyhook::InlineHook const&):
✓ Branch 8 → 9 taken 8 times.
✓ Branch 8 → 10 taken 3737 times.
bool DetourModKit::detail::enable_patch_is_confirmed<safetyhook::MidHook>(safetyhook::MidHook const&):
✓ Branch 8 → 9 taken 4 times.
✓ Branch 8 → 10 taken 57 times.
|
3806 | if (auto *override_fn = DetourModKit::detail::g_hook_enable_witness_override) |
| 100 | { | ||
| 101 | 12 | return override_fn(confirmed); | |
| 102 | } | ||
| 103 | #endif | ||
| 104 | 3794 | return confirmed; | |
| 105 | } | ||
| 106 | |||
| 107 | /// Runs a managed backend enable and contains backend synchronization or allocation exceptions. | ||
| 108 | 3806 | template <class Backend> [[nodiscard]] bool try_backend_enable(Backend &backend) noexcept | |
| 109 | { | ||
| 110 | try | ||
| 111 | { | ||
| 112 |
4/4bool DetourModKit::detail::try_backend_enable<safetyhook::InlineHook>(safetyhook::InlineHook&):
✓ Branch 2 → 3 taken 3741 times.
✓ Branch 2 → 6 taken 4 times.
bool DetourModKit::detail::try_backend_enable<safetyhook::MidHook>(safetyhook::MidHook&):
✓ Branch 2 → 3 taken 59 times.
✓ Branch 2 → 6 taken 2 times.
|
3806 | return backend.enable().has_value(); |
| 113 | } | ||
| 114 | 6 | catch (...) | |
| 115 | { | ||
| 116 | #if defined(DMK_ENABLE_TEST_SEAMS) | ||
| 117 | DetourModKit::detail::g_backend_toggle_exception_catches.fetch_add(1, std::memory_order_relaxed); | ||
| 118 | #endif | ||
| 119 | 6 | return false; | |
| 120 | } | ||
| 121 | } | ||
| 122 | |||
| 123 | /// Runs a managed backend disable and contains backend synchronization or allocation exceptions. | ||
| 124 | 4036 | template <class Backend> [[nodiscard]] bool try_backend_disable(Backend &backend) noexcept | |
| 125 | { | ||
| 126 | try | ||
| 127 | { | ||
| 128 |
4/4bool DetourModKit::detail::try_backend_disable<safetyhook::InlineHook>(safetyhook::InlineHook&):
✓ Branch 2 → 3 taken 3793 times.
✓ Branch 2 → 8 taken 9 times.
bool DetourModKit::detail::try_backend_disable<safetyhook::MidHook>(safetyhook::MidHook&):
✓ Branch 2 → 3 taken 227 times.
✓ Branch 2 → 8 taken 7 times.
|
4036 | const bool disabled = backend.disable().has_value(); |
| 129 | #if defined(DMK_ENABLE_TEST_SEAMS) | ||
| 130 |
3/4bool DetourModKit::detail::try_backend_disable<safetyhook::InlineHook>(safetyhook::InlineHook&):
✓ Branch 4 → 5 taken 1 time.
✓ Branch 4 → 6 taken 3792 times.
bool DetourModKit::detail::try_backend_disable<safetyhook::MidHook>(safetyhook::MidHook&):
✗ Branch 4 → 5 not taken.
✓ Branch 4 → 6 taken 227 times.
|
4020 | if (auto *probe = DetourModKit::detail::g_hook_backend_disable_probe) |
| 131 | { | ||
| 132 | 1 | probe(); | |
| 133 | } | ||
| 134 | #endif | ||
| 135 | 4020 | return disabled; | |
| 136 | } | ||
| 137 | 16 | catch (...) | |
| 138 | { | ||
| 139 | #if defined(DMK_ENABLE_TEST_SEAMS) | ||
| 140 | DetourModKit::detail::g_backend_toggle_exception_catches.fetch_add(1, std::memory_order_relaxed); | ||
| 141 |
4/4bool DetourModKit::detail::try_backend_disable<safetyhook::InlineHook>(safetyhook::InlineHook&):
✓ Branch 13 → 14 taken 1 time.
✓ Branch 13 → 15 taken 8 times.
bool DetourModKit::detail::try_backend_disable<safetyhook::MidHook>(safetyhook::MidHook&):
✓ Branch 13 → 14 taken 2 times.
✓ Branch 13 → 15 taken 5 times.
|
16 | if (auto *probe = DetourModKit::detail::g_hook_backend_disable_probe) |
| 142 | { | ||
| 143 | 3 | probe(); | |
| 144 | } | ||
| 145 | #endif | ||
| 146 | 16 | return false; | |
| 147 | } | ||
| 148 | } | ||
| 149 | |||
| 150 | /// Returns the current target-byte witness, or Indeterminate when no backend is reachable. | ||
| 151 | 11937 | template <class BackendVariant> [[nodiscard]] detail::PatchWitness witness_of(BackendVariant &backend) noexcept | |
| 152 | { | ||
| 153 | 11937 | return backend_value_or( | |
| 154 | backend, | ||
| 155 | detail::PatchWitness::Indeterminate, | ||
| 156 | 23874 | [](auto &one) noexcept { return detail::witness_patch(one); } | |
| 157 | 11937 | ); | |
| 158 | } | ||
| 159 | } // namespace DetourModKit::detail | ||
| 160 | |||
| 161 | #endif // DETOURMODKIT_INTERNAL_HOOK_BACKEND_VISIT_HPP | ||
| 162 |