Dota2Patcher
 
Loading...
Searching...
No Matches
Memory.h
Go to the documentation of this file.
1#pragma once
2#include <unordered_map>
3#include "..\Dota2Patcher.h"
4#include "ProcessHandle.h"
5
6class Memory {
7public:
14
15 static bool load_modules(const DWORD process_ID);
16 static optional<uintptr_t> pattern_scan(const string& target_module, const string& target_pattern);
17 static bool patch(const uintptr_t& patch_addr, const PATCH_TYPE patch_type, const optional<string>& replace_str = nullopt);
18
19 template<typename T, typename N>
22
23 if constexpr (std::is_pointer_v<N>)
24 address = reinterpret_cast<uintptr_t>(instruction_ptr);
25 else if constexpr (std::is_integral_v<N>)
26 address = static_cast<uintptr_t>(instruction_ptr);
27
28 ptrdiff_t offset = 0;
29 uint32_t size = 0;
30 switch (instr_type) {
31 case ASM_TYPE::LEA:
32 offset = 3;
33 size = 7;
34 break;
35 case ASM_TYPE::CALL:
36 offset = 2;
37 size = 6;
38 break;
39 default:
40 LOG::ERR("(absolute_address) Unsupported instruction type");
41 return nullopt;
42 }
43
45 if (!ReadProcessMemory(ProcessHandle::get_handle(), reinterpret_cast<LPCVOID>(address + offset), &relative_offset, sizeof(relative_offset), nullptr)) {
46 LOG::ERR("(absolute_address) ReadProcessMemory failed: {}", GetLastError());
47 return nullopt;
48 }
49
51
52 return absolute_address;
53 }
54
55 template<typename T, typename N>
56 static optional<T> virtual_function(const N& vmt, const int function_index) {
58
59 if constexpr (std::is_pointer_v<N>)
60 address = reinterpret_cast<uintptr_t>(vmt);
61 else if constexpr (std::is_integral_v<N>)
62 address = static_cast<uintptr_t>(vmt);
63
65 if (!base_ptr)
66 return nullopt;
67
68 int actual_index = (function_index - 1) * 8;
69
71 if (!instruction_ptr)
72 return nullopt;
73
74 return instruction_ptr;
75 }
76
77 template<typename T, typename N>
79 T value{};
80 SIZE_T bytesRead = 0;
81
83 return nullopt;
84
85 if (!ReadProcessMemory(ProcessHandle::get_handle(), reinterpret_cast<LPCVOID>(address), &value, sizeof(T), &bytesRead)) {
86 LOG::ERR("(read_memory) Failed to read memory: {}", GetLastError());
87 return nullopt;
88 }
89
90 if (bytesRead != sizeof(T)) {
91 LOG::ERR("(read_memory) Partial read at {}", (void*)address);
92 return nullopt;
93 }
94
95 return value;
96 }
97
98 template<typename T, typename N>
99 static bool write_memory(const N& address, const T& value) {
101 if (!WriteProcessMemory(ProcessHandle::get_handle(), reinterpret_cast<LPVOID>(address), &value, sizeof(T), &bytesWritten)) {
102 LOG::ERR("(write_memory) Failed to write memory at {}: {}", (void*)address, GetLastError());
103 return false;
104 }
105
106 if (bytesWritten != sizeof(T)) {
107 LOG::ERR("(write_memory) Partial write at {}", (void*)address);
108 return false;
109 }
110
111 return true;
112 }
113
114 template<typename T>
115 static void write_string(const T& address, const string& text) {
116 size_t text_size = strlen(text.c_str()) + 1;
118
120 WriteProcessMemory(hproc, reinterpret_cast<LPVOID>(address), text.c_str(), text_size, nullptr);
121 VirtualFreeEx(hproc, reinterpret_cast<LPVOID>(address), 0, MEM_RELEASE);
122 }
123
124 template<typename T>
125 static optional <string> read_string(const T& address, const size_t max_length = 64) {
126 std::vector<char> buffer(max_length, 0);
128
129 if (!ReadProcessMemory(ProcessHandle::get_handle(), reinterpret_cast<LPCVOID>(address), buffer.data(), buffer.size(), &bytesRead))
130 return nullopt;
131
132 return string(buffer.data());
133 }
134
135 template<typename T>
136 static bool is_valid_ptr(const T& ptr) {
138
139 if (!VirtualQueryEx(ProcessHandle::get_handle(), reinterpret_cast<LPCVOID>(ptr), &mbi, sizeof(mbi)))
140 return false;
141
142 uintptr_t test = 0;
143 if (!ReadProcessMemory(ProcessHandle::get_handle(), reinterpret_cast<LPCVOID>(ptr), &test, sizeof(test), nullptr))
144 return false;
145
146 return true;
147 }
148
149 template<typename T>
150 static int count_vms(const T& vmt) {
151 int count = 1;
152
153 while (true) {
155 if (!vfunc || vfunc.value_or(0) == 0)
156 break;
157
158 if (!Memory::is_valid_ptr(vfunc.value()))
159 return count;
160
161 count++;
162 }
163
164 return count;
165 }
166
167 static std::unordered_map<string, ModuleInfo> loaded_modules;
168};
ASM_TYPE
Definition Enums.h:36
PATCH_TYPE
Definition Enums.h:28
Definition Memory.h:6
static optional< T > read_memory(const N &address)
Definition Memory.h:78
static bool is_valid_ptr(const T &ptr)
Definition Memory.h:136
static bool patch(const uintptr_t &patch_addr, const PATCH_TYPE patch_type, const optional< string > &replace_str=nullopt)
Definition Memory.cpp:125
static optional< string > read_string(const T &address, const size_t max_length=64)
Definition Memory.h:125
static optional< uintptr_t > pattern_scan(const string &target_module, const string &target_pattern)
Definition Memory.cpp:25
static bool load_modules(const DWORD process_ID)
Definition Memory.cpp:73
static int count_vms(const T &vmt)
Definition Memory.h:150
static optional< T > absolute_address(const N &instruction_ptr, const ASM_TYPE instr_type=ASM_TYPE::LEA)
Definition Memory.h:20
static bool write_memory(const N &address, const T &value)
Definition Memory.h:99
static optional< T > virtual_function(const N &vmt, const int function_index)
Definition Memory.h:56
static std::unordered_map< string, ModuleInfo > loaded_modules
Definition Memory.h:167
static void write_string(const T &address, const string &text)
Definition Memory.h:115
static HANDLE get_handle()
Definition ProcessHandle.h:53
Definition Memory.h:8
HMODULE hmodule
Definition Memory.h:12
uintptr_t start_address
Definition Memory.h:9
size_t region_size
Definition Memory.h:11
uintptr_t end_address
Definition Memory.h:10