diff options
Diffstat (limited to 'Source/Memory.cpp')
-rw-r--r-- | Source/Memory.cpp | 162 |
1 files changed, 81 insertions, 81 deletions
diff --git a/Source/Memory.cpp b/Source/Memory.cpp index d90c402..26ef7e4 100644 --- a/Source/Memory.cpp +++ b/Source/Memory.cpp | |||
@@ -73,124 +73,124 @@ void Memory::Heartbeat(HWND window) { | |||
73 | 73 | ||
74 | [[nodiscard]] | 74 | [[nodiscard]] |
75 | bool Memory::Initialize() { | 75 | bool Memory::Initialize() { |
76 | // First, get the handle of the process | 76 | // First, get the handle of the process |
77 | PROCESSENTRY32W entry; | 77 | PROCESSENTRY32W entry; |
78 | entry.dwSize = sizeof(entry); | 78 | entry.dwSize = sizeof(entry); |
79 | HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); | 79 | HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); |
80 | while (Process32NextW(snapshot, &entry)) { | 80 | while (Process32NextW(snapshot, &entry)) { |
81 | if (_processName == entry.szExeFile) { | 81 | if (_processName == entry.szExeFile) { |
82 | _handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, entry.th32ProcessID); | 82 | _handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, entry.th32ProcessID); |
83 | break; | 83 | break; |
84 | } | 84 | } |
85 | } | 85 | } |
86 | if (!_handle) { | 86 | if (!_handle) { |
87 | std::cerr << "Couldn't find " << _processName.c_str() << ", is it open?" << std::endl; | 87 | std::cerr << "Couldn't find " << _processName.c_str() << ", is it open?" << std::endl; |
88 | return false; | 88 | return false; |
89 | } | 89 | } |
90 | 90 | ||
91 | // Next, get the process base address | 91 | // Next, get the process base address |
92 | DWORD numModules; | 92 | DWORD numModules; |
93 | std::vector<HMODULE> moduleList(1024); | 93 | std::vector<HMODULE> moduleList(1024); |
94 | EnumProcessModulesEx(_handle, &moduleList[0], static_cast<DWORD>(moduleList.size()), &numModules, 3); | 94 | EnumProcessModulesEx(_handle, &moduleList[0], static_cast<DWORD>(moduleList.size()), &numModules, 3); |
95 | 95 | ||
96 | std::wstring name(64, '\0'); | 96 | std::wstring name(64, '\0'); |
97 | for (DWORD i = 0; i < numModules / sizeof(HMODULE); i++) { | 97 | for (DWORD i = 0; i < numModules / sizeof(HMODULE); i++) { |
98 | int length = GetModuleBaseNameW(_handle, moduleList[i], &name[0], static_cast<DWORD>(name.size())); | 98 | int length = GetModuleBaseNameW(_handle, moduleList[i], &name[0], static_cast<DWORD>(name.size())); |
99 | name.resize(length); | 99 | name.resize(length); |
100 | if (_processName == name) { | 100 | if (_processName == name) { |
101 | _baseAddress = (uintptr_t)moduleList[i]; | 101 | _baseAddress = (uintptr_t)moduleList[i]; |
102 | break; | 102 | break; |
103 | } | 103 | } |
104 | } | 104 | } |
105 | if (_baseAddress == 0) { | 105 | if (_baseAddress == 0) { |
106 | std::cerr << "Couldn't locate base address" << std::endl; | 106 | std::cerr << "Couldn't locate base address" << std::endl; |
107 | return false; | 107 | return false; |
108 | } | 108 | } |
109 | 109 | ||
110 | return true; | 110 | return true; |
111 | } | 111 | } |
112 | 112 | ||
113 | void Memory::AddSigScan(const std::vector<byte>& scanBytes, const std::function<void(int index)>& scanFunc) | 113 | void Memory::AddSigScan(const std::vector<byte>& scanBytes, const std::function<void(int index)>& scanFunc) |
114 | { | 114 | { |
115 | _sigScans[scanBytes] = {scanFunc, false}; | 115 | _sigScans[scanBytes] = {scanFunc, false}; |
116 | } | 116 | } |
117 | 117 | ||
118 | int find(const std::vector<byte> &data, const std::vector<byte>& search, size_t startIndex = 0) { | 118 | int find(const std::vector<byte> &data, const std::vector<byte>& search, size_t startIndex = 0) { |
119 | for (size_t i=startIndex; i<data.size() - search.size(); i++) { | 119 | for (size_t i=startIndex; i<data.size() - search.size(); i++) { |
120 | bool match = true; | 120 | bool match = true; |
121 | for (size_t j=0; j<search.size(); j++) { | 121 | for (size_t j=0; j<search.size(); j++) { |
122 | if (data[i+j] == search[j]) { | 122 | if (data[i+j] == search[j]) { |
123 | continue; | 123 | continue; |
124 | } | 124 | } |
125 | match = false; | 125 | match = false; |
126 | break; | 126 | break; |
127 | } | 127 | } |
128 | if (match) return static_cast<int>(i); | 128 | if (match) return static_cast<int>(i); |
129 | } | 129 | } |
130 | return -1; | 130 | return -1; |
131 | } | 131 | } |
132 | 132 | ||
133 | int Memory::ExecuteSigScans() | 133 | int Memory::ExecuteSigScans() |
134 | { | 134 | { |
135 | for (int i=0; i<0x200000; i+=0x1000) { | 135 | for (int i=0; i<0x200000; i+=0x1000) { |
136 | std::vector<byte> data = ReadData<byte>({i}, 0x1100); | 136 | std::vector<byte> data = ReadData<byte>({i}, 0x1100); |
137 | 137 | ||
138 | for (auto& [scanBytes, sigScan] : _sigScans) { | 138 | for (auto& [scanBytes, sigScan] : _sigScans) { |
139 | if (sigScan.found) continue; | 139 | if (sigScan.found) continue; |
140 | int index = find(data, scanBytes); | 140 | int index = find(data, scanBytes); |
141 | if (index == -1) continue; | 141 | if (index == -1) continue; |
142 | sigScan.scanFunc(i + index); | 142 | sigScan.scanFunc(i + index); |
143 | sigScan.found = true; | 143 | sigScan.found = true; |
144 | } | 144 | } |
145 | } | 145 | } |
146 | 146 | ||
147 | int notFound = 0; | 147 | int notFound = 0; |
148 | for (auto it : _sigScans) { | 148 | for (auto it : _sigScans) { |
149 | if (it.second.found == false) notFound++; | 149 | if (it.second.found == false) notFound++; |
150 | } | 150 | } |
151 | return notFound; | 151 | return notFound; |
152 | } | 152 | } |
153 | 153 | ||
154 | void Memory::ThrowError() { | 154 | void Memory::ThrowError() { |
155 | std::wstring message(256, '\0'); | 155 | std::wstring message(256, '\0'); |
156 | DWORD error = GetLastError(); | 156 | DWORD error = GetLastError(); |
157 | int length = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM, nullptr, error, 1024, &message[0], static_cast<DWORD>(message.size()), nullptr); | 157 | int length = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM, nullptr, error, 1024, &message[0], static_cast<DWORD>(message.size()), nullptr); |
158 | message.resize(length); | 158 | message.resize(length); |
159 | #ifndef NDEBUG | 159 | #ifndef NDEBUG |
160 | MessageBox(NULL, message.c_str(), L"Please tell darkid about this", MB_OK); | 160 | MessageBox(NULL, message.c_str(), L"Please tell darkid about this", MB_OK); |
161 | #endif | 161 | #endif |
162 | } | 162 | } |
163 | 163 | ||
164 | void* Memory::ComputeOffset(std::vector<int> offsets) { | 164 | void* Memory::ComputeOffset(std::vector<int> offsets) { |
165 | // Leave off the last offset, since it will be either read/write, and may not be of type uintptr_t. | 165 | // Leave off the last offset, since it will be either read/write, and may not be of type uintptr_t. |
166 | int final_offset = offsets.back(); | 166 | int final_offset = offsets.back(); |
167 | offsets.pop_back(); | 167 | offsets.pop_back(); |
168 | 168 | ||
169 | uintptr_t cumulativeAddress = _baseAddress; | 169 | uintptr_t cumulativeAddress = _baseAddress; |
170 | for (const int offset : offsets) { | 170 | for (const int offset : offsets) { |
171 | cumulativeAddress += offset; | 171 | cumulativeAddress += offset; |
172 | 172 | ||
173 | const auto search = _computedAddresses.find(cumulativeAddress); | 173 | const auto search = _computedAddresses.find(cumulativeAddress); |
174 | // This is an issue with re-randomization. Always. Just disable it in debug mode! | 174 | // This is an issue with re-randomization. Always. Just disable it in debug mode! |
175 | #ifdef NDEBUG | 175 | #ifdef NDEBUG |
176 | if (search == std::end(_computedAddresses)) { | 176 | if (search == std::end(_computedAddresses)) { |
177 | #endif | 177 | #endif |
178 | // If the address is not yet computed, then compute it. | 178 | // If the address is not yet computed, then compute it. |
179 | uintptr_t computedAddress = 0; | 179 | uintptr_t computedAddress = 0; |
180 | if (bool result = !ReadProcessMemory(_handle, reinterpret_cast<LPVOID>(cumulativeAddress), &computedAddress, sizeof(uintptr_t), NULL)) { | 180 | if (bool result = !ReadProcessMemory(_handle, reinterpret_cast<LPVOID>(cumulativeAddress), &computedAddress, sizeof(uintptr_t), NULL)) { |
181 | ThrowError(); | 181 | ThrowError(); |
182 | } | 182 | } |
183 | if (computedAddress == 0) { // Attempting to dereference a nullptr | 183 | if (computedAddress == 0) { // Attempting to dereference a nullptr |
184 | ThrowError(); | 184 | ThrowError(); |
185 | } | 185 | } |
186 | _computedAddresses[cumulativeAddress] = computedAddress; | 186 | _computedAddresses[cumulativeAddress] = computedAddress; |
187 | #ifdef NDEBUG | 187 | #ifdef NDEBUG |
188 | } | 188 | } |
189 | #endif | 189 | #endif |
190 | 190 | ||
191 | cumulativeAddress = _computedAddresses[cumulativeAddress]; | 191 | cumulativeAddress = _computedAddresses[cumulativeAddress]; |
192 | } | 192 | } |
193 | return reinterpret_cast<void*>(cumulativeAddress + final_offset); | 193 | return reinterpret_cast<void*>(cumulativeAddress + final_offset); |
194 | } | 194 | } |
195 | 195 | ||
196 | uintptr_t Memory::Allocate(size_t bytes) { | 196 | uintptr_t Memory::Allocate(size_t bytes) { |