SafetyHook
Loading...
Searching...
No Matches
allocator.hpp
Go to the documentation of this file.
1
3
4#pragma once
5
6#ifndef SAFETYHOOK_USE_CXXMODULES
7#include <cstdint>
8#include <expected>
9#include <memory>
10#include <mutex>
11#include <vector>
12#else
13import std.compat;
14#endif
15
16#include "safetyhook/common.hpp"
17
18namespace safetyhook {
19class Allocator;
20
22class SAFETYHOOK_API Allocation final {
23public:
24 Allocation() = default;
25 Allocation(const Allocation&) = delete;
26 Allocation(Allocation&& other) noexcept;
27 Allocation& operator=(const Allocation&) = delete;
28 Allocation& operator=(Allocation&& other) noexcept;
29 ~Allocation();
30
33 void free();
34
37 [[nodiscard]] uint8_t* data() const noexcept { return m_address; }
38
41 [[nodiscard]] uintptr_t address() const noexcept { return reinterpret_cast<uintptr_t>(m_address); }
42
45 [[nodiscard]] size_t size() const noexcept { return m_size; }
46
49 explicit operator bool() const noexcept { return m_address != nullptr && m_size != 0; }
50
51protected:
52 friend Allocator;
53
54 Allocation(std::shared_ptr<Allocator> allocator, uint8_t* address, size_t size) noexcept;
55
56private:
57 std::shared_ptr<Allocator> m_allocator{};
58 uint8_t* m_address{};
59 size_t m_size{};
60};
61
63class SAFETYHOOK_API Allocator final : public std::enable_shared_from_this<Allocator> {
64public:
67 [[nodiscard]] static std::shared_ptr<Allocator> global();
68
71 [[nodiscard]] static std::shared_ptr<Allocator> create();
72
73 Allocator(const Allocator&) = delete;
74 Allocator(Allocator&&) noexcept = delete;
75 Allocator& operator=(const Allocator&) = delete;
76 Allocator& operator=(Allocator&&) noexcept = delete;
77 ~Allocator() = default;
78
80 enum class Error : uint8_t {
83 };
84
88 [[nodiscard]] std::expected<Allocation, Error> allocate(size_t size);
89
95 [[nodiscard]] std::expected<Allocation, Error> allocate_near(
96 const std::vector<uint8_t*>& desired_addresses, size_t size, size_t max_distance = 0x7FFF'FFFF);
97
98protected:
99 friend Allocation;
100
101 void free(uint8_t* address, size_t size);
102
103private:
104 struct FreeNode {
105 std::unique_ptr<FreeNode> next{};
106 uint8_t* start{};
107 uint8_t* end{};
108 };
109
110 struct Memory {
111 uint8_t* address{};
112 size_t size{};
113 std::unique_ptr<FreeNode> freelist{};
114
115 ~Memory();
116 };
117
118 std::vector<std::unique_ptr<Memory>> m_memory{};
119 std::mutex m_mutex{};
120
121 Allocator() = default;
122
123 [[nodiscard]] std::expected<Allocation, Error> internal_allocate_near(
124 const std::vector<uint8_t*>& desired_addresses, size_t size, size_t max_distance = 0x7FFF'FFFF);
125 void internal_free(uint8_t* address, size_t size);
126
127 static void combine_adjacent_freenodes(Memory& memory);
128 [[nodiscard]] static std::expected<uint8_t*, Error> allocate_nearby_memory(
129 const std::vector<uint8_t*>& desired_addresses, size_t size, size_t max_distance);
130 [[nodiscard]] static bool in_range(
131 uint8_t* address, const std::vector<uint8_t*>& desired_addresses, size_t max_distance);
132};
133} // namespace safetyhook
A memory allocation.
Definition allocator.hpp:22
uint8_t * data() const noexcept
Returns a pointer to the data of the allocation.
Definition allocator.hpp:37
void free()
Frees the allocation.
size_t size() const noexcept
Returns the size of the allocation.
Definition allocator.hpp:45
uintptr_t address() const noexcept
Returns the address of the allocation.
Definition allocator.hpp:41
Allocates memory near target addresses.
Definition allocator.hpp:63
static std::shared_ptr< Allocator > global()
Returns the global Allocator.
std::expected< Allocation, Error > allocate_near(const std::vector< uint8_t * > &desired_addresses, size_t size, size_t max_distance=0x7FFF 'FFFF)
Allocates memory near a target address.
Error
The error type returned by the allocate functions.
Definition allocator.hpp:80
@ NO_MEMORY_IN_RANGE
No memory in range.
Definition allocator.hpp:82
@ BAD_VIRTUAL_ALLOC
VirtualAlloc failed.
Definition allocator.hpp:81
std::expected< Allocation, Error > allocate(size_t size)
Allocates memory.
static std::shared_ptr< Allocator > create()
Creates a new Allocator.