include/DetourModKit/region.hpp
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | #ifndef DETOURMODKIT_REGION_HPP | ||
| 2 | #define DETOURMODKIT_REGION_HPP | ||
| 3 | |||
| 4 | /** | ||
| 5 | * @file region.hpp | ||
| 6 | * @brief The Region value type and the Prot protection flags, the shared range-of-memory vocabulary. | ||
| 7 | * @details Of all Region operations, only `module_named()` can allocate. | ||
| 8 | * @warning `[B-100]` `host()`, `own()`, and `module_named()` query loader state. Never call them under the Windows | ||
| 9 | * loader lock, for example from a namespace-scope static initializer in a DLL. `whole_process()` does not | ||
| 10 | * query loader state. `RegionLoaderBoundary.*` pins this boundary. | ||
| 11 | */ | ||
| 12 | |||
| 13 | #include "DetourModKit/address.hpp" | ||
| 14 | #include "DetourModKit/defines.hpp" | ||
| 15 | |||
| 16 | #include <cstddef> | ||
| 17 | #include <cstdint> | ||
| 18 | #include <string_view> | ||
| 19 | |||
| 20 | namespace DetourModKit | ||
| 21 | { | ||
| 22 | /** @brief A half-open span [base, base + size) with no invariant. A failed factory returns `Region{}`. */ | ||
| 23 | struct Region | ||
| 24 | { | ||
| 25 | /// Inclusive start of the span. | ||
| 26 | Address base{}; | ||
| 27 | /// Length of the span in bytes. A zero size denotes an empty Region. | ||
| 28 | std::size_t size{0}; | ||
| 29 | |||
| 30 | /// Returns the exclusive end address. | ||
| 31 | 3190 | [[nodiscard]] constexpr Address end() const noexcept { return base.offset(static_cast<std::ptrdiff_t>(size)); } | |
| 32 | |||
| 33 | /** @brief Tests whether base <= @p address < end(). An empty Region contains no address. */ | ||
| 34 | 19 | [[nodiscard]] constexpr bool contains(Address address) const noexcept | |
| 35 | { | ||
| 36 | 19 | return address >= base && address < end(); | |
| 37 | } | ||
| 38 | |||
| 39 | /** @brief Returns [base + @p offset, base + @p offset + @p length), unclamped. Keep it inside this Region. */ | ||
| 40 | 1 | [[nodiscard]] constexpr Region sub(std::size_t offset, std::size_t length) const noexcept | |
| 41 | { | ||
| 42 | 1 | return Region{base.offset(static_cast<std::ptrdiff_t>(offset)), length}; | |
| 43 | } | ||
| 44 | |||
| 45 | /** | ||
| 46 | * @brief Returns the image span of the host process EXE, or an empty Region if it cannot be resolved. | ||
| 47 | * @note Setup/control-plane only. See the file `[B-100]` loader-lock warning. | ||
| 48 | */ | ||
| 49 | [[nodiscard]] static Region host() noexcept; | ||
| 50 | |||
| 51 | /** | ||
| 52 | * @brief Returns the image span of the DLL or EXE that linked DetourModKit, or an empty Region on failure. | ||
| 53 | * @note Setup/control-plane only. See the file `[B-100]` loader-lock warning. | ||
| 54 | */ | ||
| 55 | [[nodiscard]] static Region own() noexcept; | ||
| 56 | |||
| 57 | /** | ||
| 58 | * @brief Returns the image span of loaded module @p name, or an empty Region for an empty, invalid, or unloaded | ||
| 59 | * name or a failed allocation. | ||
| 60 | * @param name UTF-8 module name as the loader knows it, for example "kernel32.dll". | ||
| 61 | * @note Setup/control-plane only. See the file `[B-100]` loader-lock warning. | ||
| 62 | */ | ||
| 63 | [[nodiscard]] static Region module_named(std::string_view name) noexcept; | ||
| 64 | |||
| 65 | /** | ||
| 66 | * @brief Returns the span from the system minimum application address through the maximum, inclusive. | ||
| 67 | * @note Setup/control-plane only. | ||
| 68 | */ | ||
| 69 | [[nodiscard]] static Region whole_process() noexcept; | ||
| 70 | }; | ||
| 71 | |||
| 72 | /** @brief Backend-neutral page protection as composable read, write, and execute flags. */ | ||
| 73 | enum class Prot : std::uint32_t | ||
| 74 | { | ||
| 75 | None = 0, | ||
| 76 | R = 1, | ||
| 77 | W = 2, | ||
| 78 | X = 4, | ||
| 79 | RW = R | W, | ||
| 80 | RWX = R | W | X | ||
| 81 | }; | ||
| 82 | |||
| 83 | 3691 | DMK_FLAG_ENUM(Prot) | |
| 84 | |||
| 85 | } // namespace DetourModKit | ||
| 86 | |||
| 87 | #endif // DETOURMODKIT_REGION_HPP | ||
| 88 |