plugify  1.0.0.0
mem_addr.hpp
1 #pragma once
2 
3 #include <cstddef>
4 #include <cstdint>
5 #include <type_traits>
6 
7 namespace plugify {
11  class MemAddr {
12  public:
16  MemAddr() noexcept : _ptr{0} {}
17 
22  MemAddr(uintptr_t ptr) noexcept : _ptr{ptr} {}
23 
29  template<typename T> requires (std::is_pointer_v<T> or std::is_null_pointer_v<T>)
30  MemAddr(T ptr) noexcept : _ptr{reinterpret_cast<uintptr_t>(ptr)} {}
31 
36  operator uintptr_t() const noexcept {
37  return _ptr;
38  }
39 
44  operator void*() const noexcept {
45  return reinterpret_cast<void*>(_ptr);
46  }
47 
52  explicit operator bool() const noexcept {
53  return _ptr != 0;
54  }
55 
61  bool operator!=(const MemAddr& addr) const noexcept {
62  return _ptr != addr._ptr;
63  }
64 
70  bool operator==(const MemAddr& addr) const noexcept {
71  return _ptr == addr._ptr;
72  }
73 
79  bool operator==(const uintptr_t& addr) const noexcept {
80  return _ptr == addr;
81  }
82 
87  uintptr_t GetPtr() const noexcept {
88  return _ptr;
89  }
90 
96  template<class T>
97  T GetValue() const noexcept {
98  return *reinterpret_cast<T*>(_ptr);
99  }
100 
106  template<typename T>
107  T CCast() const noexcept {
108  return (T) _ptr;
109  }
110 
116  template<typename T>
117  T RCast() const noexcept {
118  return reinterpret_cast<T>(_ptr);
119  }
120 
126  template<typename T>
127  T UCast() const noexcept {
128  union {
129  uintptr_t m_ptr;
130  T cptr;
131  } cast;
132  return cast.m_ptr = _ptr, cast.cptr;
133  }
134 
140  MemAddr Offset(ptrdiff_t offset) const noexcept {
141  return _ptr + static_cast<uintptr_t>(offset);
142  }
143 
149  MemAddr& OffsetSelf(ptrdiff_t offset) noexcept {
150  _ptr += static_cast<uintptr_t>(offset);
151  return *this;
152  }
153 
159  MemAddr Deref(ptrdiff_t deref = 1) const {
160  uintptr_t reference = _ptr;
161 
162  while (deref--) {
163  if (reference)
164  reference = *reinterpret_cast<uintptr_t*>(reference);
165  }
166 
167  return reference;
168  }
169 
175  MemAddr& DerefSelf(ptrdiff_t deref = 1) {
176  while (deref--) {
177  if (_ptr)
178  _ptr = *reinterpret_cast<uintptr_t*>(_ptr);
179  }
180 
181  return *this;
182  }
183 
190  MemAddr FollowNearCall(ptrdiff_t opcodeOffset = 0x1, ptrdiff_t nextInstructionOffset = 0x5) const {
191  return ResolveRelativeAddress(opcodeOffset, nextInstructionOffset);
192  }
193 
200  MemAddr& FollowNearCallSelf(ptrdiff_t opcodeOffset = 0x1, ptrdiff_t nextInstructionOffset = 0x5) {
201  return ResolveRelativeAddressSelf(opcodeOffset, nextInstructionOffset);
202  }
203 
210  MemAddr ResolveRelativeAddress(ptrdiff_t registerOffset = 0x0, ptrdiff_t nextInstructionOffset = 0x4) const {
211  const uintptr_t skipRegister = _ptr + static_cast<uintptr_t>(registerOffset);
212  const int32_t relativeAddress = *reinterpret_cast<int32_t*>(skipRegister);
213  const uintptr_t nextInstruction = _ptr + static_cast<uintptr_t>(nextInstructionOffset);
214  return nextInstruction + (uintptr_t) relativeAddress;
215  }
216 
223  MemAddr& ResolveRelativeAddressSelf(ptrdiff_t registerOffset = 0x0, ptrdiff_t nextInstructionOffset = 0x4) {
224  const uintptr_t skipRegister = _ptr + static_cast<uintptr_t>(registerOffset);
225  const int32_t relativeAddress = *reinterpret_cast<int32_t*>(skipRegister);
226  const uintptr_t nextInstruction = _ptr + static_cast<uintptr_t>(nextInstructionOffset);
227  _ptr = nextInstruction + static_cast<uintptr_t>(relativeAddress);
228  return *this;
229  }
230 
231  private:
232  uintptr_t _ptr;
233  };
234 }// namespace plugify
A wrapper class for memory addresses, providing utility functions for pointer manipulation.
Definition: mem_addr.hpp:11
MemAddr & FollowNearCallSelf(ptrdiff_t opcodeOffset=0x1, ptrdiff_t nextInstructionOffset=0x5)
Follows a near call to resolve the address in-place.
Definition: mem_addr.hpp:200
requires(std::is_pointer_v< T > or std::is_null_pointer_v< T >) MemAddr(T ptr) noexcept
Template constructor initializing the pointer with a typed pointer.
Definition: mem_addr.hpp:29
MemAddr Offset(ptrdiff_t offset) const noexcept
Offsets the memory address by a specified amount.
Definition: mem_addr.hpp:140
MemAddr() noexcept
Default constructor initializing the pointer to 0.
Definition: mem_addr.hpp:16
MemAddr(uintptr_t ptr) noexcept
Constructor initializing the pointer with a uintptr_t value.
Definition: mem_addr.hpp:22
MemAddr ResolveRelativeAddress(ptrdiff_t registerOffset=0x0, ptrdiff_t nextInstructionOffset=0x4) const
Resolves a relative address.
Definition: mem_addr.hpp:210
MemAddr & ResolveRelativeAddressSelf(ptrdiff_t registerOffset=0x0, ptrdiff_t nextInstructionOffset=0x4)
Resolves a relative address in-place.
Definition: mem_addr.hpp:223
MemAddr & OffsetSelf(ptrdiff_t offset) noexcept
Offsets the memory address by a specified amount in-place.
Definition: mem_addr.hpp:149
T RCast() const noexcept
Casts the pointer to a specified type using reinterpret_cast.
Definition: mem_addr.hpp:117
MemAddr & DerefSelf(ptrdiff_t deref=1)
Dereferences the memory address a specified number of times in-place.
Definition: mem_addr.hpp:175
T UCast() const noexcept
Casts the pointer to a specified type using a union cast.
Definition: mem_addr.hpp:127
bool operator==(const MemAddr &addr) const noexcept
Equality operator.
Definition: mem_addr.hpp:70
bool operator==(const uintptr_t &addr) const noexcept
Equality operator for comparing with uintptr_t.
Definition: mem_addr.hpp:79
MemAddr FollowNearCall(ptrdiff_t opcodeOffset=0x1, ptrdiff_t nextInstructionOffset=0x5) const
Follows a near call to resolve the address.
Definition: mem_addr.hpp:190
MemAddr Deref(ptrdiff_t deref=1) const
Dereferences the memory address a specified number of times.
Definition: mem_addr.hpp:159
uintptr_t GetPtr() const noexcept
Returns the uintptr_t representation of the pointer.
Definition: mem_addr.hpp:87
T CCast() const noexcept
Casts the pointer to a specified type using C-style cast.
Definition: mem_addr.hpp:107
bool operator!=(const MemAddr &addr) const noexcept
Inequality operator.
Definition: mem_addr.hpp:61
T GetValue() const noexcept
Retrieves the value at the memory address.
Definition: mem_addr.hpp:97