Files
ReshadePluginsCore/external/safetyhook/include/safetyhook/utility.hpp

63 lines
2.0 KiB
C++

#pragma once
#ifndef SAFETYHOOK_USE_CXXMODULES
#include <algorithm>
#include <cstdint>
#include <optional>
#include <type_traits>
#else
import std.compat;
#endif
#include "safetyhook/common.hpp"
namespace safetyhook {
template <typename T> constexpr void store(uint8_t* address, const T& value) {
std::copy_n(reinterpret_cast<const uint8_t*>(&value), sizeof(T), address);
}
template <typename T, typename U> constexpr T address_cast(U address) {
if constexpr (std::is_integral_v<T> && std::is_integral_v<U>) {
return static_cast<T>(address);
} else {
return reinterpret_cast<T>(address);
}
}
bool SAFETYHOOK_API is_executable(uint8_t* address);
class SAFETYHOOK_API UnprotectMemory {
public:
UnprotectMemory() = delete;
~UnprotectMemory();
UnprotectMemory(const UnprotectMemory&) = delete;
UnprotectMemory(UnprotectMemory&& other) noexcept;
UnprotectMemory& operator=(const UnprotectMemory&) = delete;
UnprotectMemory& operator=(UnprotectMemory&& other) noexcept;
private:
friend std::optional<UnprotectMemory> SAFETYHOOK_API unprotect(uint8_t*, size_t);
UnprotectMemory(uint8_t* address, size_t size, uint32_t original_protection)
: m_address{address}, m_size{size}, m_original_protection{original_protection} {}
uint8_t* m_address{};
size_t m_size{};
uint32_t m_original_protection{};
};
[[nodiscard]] std::optional<UnprotectMemory> SAFETYHOOK_API unprotect(uint8_t* address, size_t size);
template <typename T> constexpr T align_up(T address, size_t align) {
const auto unaligned_address = address_cast<uintptr_t>(address);
const auto aligned_address = (unaligned_address + align - 1) & ~(align - 1);
return address_cast<T>(aligned_address);
}
template <typename T> constexpr T align_down(T address, size_t align) {
const auto unaligned_address = address_cast<uintptr_t>(address);
const auto aligned_address = unaligned_address & ~(align - 1);
return address_cast<T>(aligned_address);
}
} // namespace safetyhook