src/internal/export_resolution.hpp
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | #ifndef DETOURMODKIT_INTERNAL_EXPORT_RESOLUTION_HPP | ||
| 2 | #define DETOURMODKIT_INTERNAL_EXPORT_RESOLUTION_HPP | ||
| 3 | |||
| 4 | /** | ||
| 5 | * @file internal/export_resolution.hpp | ||
| 6 | * @brief The resolved physical provenance of a named export, for callers that must tell two names for one EAT entry | ||
| 7 | * apart from two genuinely independent signals. | ||
| 8 | * @details A module's export table maps many names onto one function array. Two names may share an ordinal, or two | ||
| 9 | * ordinals may carry one function RVA, and in both cases a single patched instruction breaks every name that | ||
| 10 | * reaches it. A quorum that counts those names separately reports corroboration it does not have, so the | ||
| 11 | * resolver publishes the physical site it actually read instead of only the address it returns. | ||
| 12 | */ | ||
| 13 | |||
| 14 | #include "DetourModKit/address.hpp" | ||
| 15 | #include "DetourModKit/scan.hpp" | ||
| 16 | |||
| 17 | #include <cstdint> | ||
| 18 | #include <string_view> | ||
| 19 | |||
| 20 | namespace DetourModKit | ||
| 21 | { | ||
| 22 | namespace detail | ||
| 23 | { | ||
| 24 | /** | ||
| 25 | * @struct ExportResolution | ||
| 26 | * @brief Where a resolved export physically came from. | ||
| 27 | * @details @ref module_base identifies the mapping, since two images cannot occupy one base at once, and it is | ||
| 28 | * what keeps two modules that export the same RVA apart. @ref function_index is the slot in | ||
| 29 | * AddressOfFunctions the name mapped to, and @ref function_rva is the value read out of it. | ||
| 30 | */ | ||
| 31 | struct ExportResolution | ||
| 32 | { | ||
| 33 | std::uintptr_t module_base{0}; | ||
| 34 | std::uint32_t function_index{0}; | ||
| 35 | std::uint32_t function_rva{0}; | ||
| 36 | Address target{}; | ||
| 37 | |||
| 38 |
3/4✓ Branch 2 → 3 taken 25 times.
✓ Branch 2 → 6 taken 87 times.
✓ Branch 4 → 5 taken 25 times.
✗ Branch 4 → 6 not taken.
|
112 | [[nodiscard]] constexpr bool present() const noexcept { return module_base != 0 && target.raw() != 0; } |
| 39 | }; | ||
| 40 | |||
| 41 | /** | ||
| 42 | * @brief True when both resolutions name one physical export site. | ||
| 43 | * @details Equal slots are the same table entry read twice; equal RVAs in one image are the same code reached | ||
| 44 | * through two entries. Either makes the pair one failure domain, so a quorum must count them once. | ||
| 45 | * An absent resolution correlates with nothing: only a member that can name its physical source may | ||
| 46 | * take part in this test. | ||
| 47 | */ | ||
| 48 | 91 | [[nodiscard]] constexpr bool same_export_site(const ExportResolution &a, const ExportResolution &b) noexcept | |
| 49 | { | ||
| 50 |
7/8✓ Branch 3 → 4 taken 7 times.
✓ Branch 3 → 7 taken 84 times.
✓ Branch 5 → 6 taken 7 times.
✗ Branch 5 → 7 not taken.
✓ Branch 6 → 7 taken 1 time.
✓ Branch 6 → 8 taken 6 times.
✓ Branch 9 → 10 taken 85 times.
✓ Branch 9 → 11 taken 6 times.
|
91 | if (!a.present() || !b.present() || a.module_base != b.module_base) |
| 51 | { | ||
| 52 | 85 | return false; | |
| 53 | } | ||
| 54 |
4/4✓ Branch 11 → 12 taken 3 times.
✓ Branch 11 → 13 taken 3 times.
✓ Branch 12 → 13 taken 2 times.
✓ Branch 12 → 14 taken 1 time.
|
6 | return a.function_index == b.function_index || a.function_rva == b.function_rva; |
| 55 | } | ||
| 56 | |||
| 57 | /** | ||
| 58 | * @brief @ref scan::resolve_export, additionally publishing the physical site the match was read from. | ||
| 59 | * @param export_name Export name to resolve; matched byte-exactly and case-sensitively. | ||
| 60 | * @param module Module scope to walk. | ||
| 61 | * @param out Receives the resolved provenance on success; left default on any failure. | ||
| 62 | * @return The resolved address, or the same typed failure @ref scan::resolve_export reports. | ||
| 63 | */ | ||
| 64 | [[nodiscard]] Result<Address> | ||
| 65 | resolve_export_with_provenance(std::string_view export_name, Region module, ExportResolution &out) noexcept; | ||
| 66 | } // namespace detail | ||
| 67 | } // namespace DetourModKit | ||
| 68 | |||
| 69 | #endif // DETOURMODKIT_INTERNAL_EXPORT_RESOLUTION_HPP | ||
| 70 |