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) { |
