SafetyHook
Loading...
Searching...
No Matches
utility.hpp
1#pragma once
2
3#ifndef SAFETYHOOK_USE_CXXMODULES
4#include <algorithm>
5#include <cstdint>
6#include <optional>
7#include <type_traits>
8#else
9import std.compat;
10#endif
11
12#include "safetyhook/common.hpp"
13
14namespace safetyhook {
15template <typename T> constexpr void store(uint8_t* address, const T& value) {
16 std::copy_n(reinterpret_cast<const uint8_t*>(&value), sizeof(T), address);
17}
18
19template <typename T, typename U> constexpr T address_cast(U address) {
20 if constexpr (std::is_integral_v<T> && std::is_integral_v<U>) {
21 return static_cast<T>(address);
22 } else {
23 return reinterpret_cast<T>(address);
24 }
25}
26
27bool SAFETYHOOK_API is_executable(uint8_t* address);
28
29class SAFETYHOOK_API UnprotectMemory {
30public:
31 UnprotectMemory() = delete;
32 ~UnprotectMemory();
33 UnprotectMemory(const UnprotectMemory&) = delete;
34 UnprotectMemory(UnprotectMemory&& other) noexcept;
35 UnprotectMemory& operator=(const UnprotectMemory&) = delete;
36 UnprotectMemory& operator=(UnprotectMemory&& other) noexcept;
37
38private:
39 friend std::optional<UnprotectMemory> SAFETYHOOK_API unprotect(uint8_t*, size_t);
40
41 UnprotectMemory(uint8_t* address, size_t size, uint32_t original_protection)
42 : m_address{address}, m_size{size}, m_original_protection{original_protection} {}
43
44 uint8_t* m_address{};
45 size_t m_size{};
46 uint32_t m_original_protection{};
47};
48
49[[nodiscard]] std::optional<UnprotectMemory> SAFETYHOOK_API unprotect(uint8_t* address, size_t size);
50
51template <typename T> constexpr T align_up(T address, size_t align) {
52 const auto unaligned_address = address_cast<uintptr_t>(address);
53 const auto aligned_address = (unaligned_address + align - 1) & ~(align - 1);
54 return address_cast<T>(aligned_address);
55}
56
57template <typename T> constexpr T align_down(T address, size_t align) {
58 const auto unaligned_address = address_cast<uintptr_t>(address);
59 const auto aligned_address = unaligned_address & ~(align - 1);
60 return address_cast<T>(aligned_address);
61}
62} // namespace safetyhook