|
3 | 3 | #include <cstdint>
|
4 | 4 | #include <algorithm>
|
5 | 5 | #include <functional>
|
6 |
| -#include <tlhelp32.h> |
| 6 | +#include <psapi.h> |
7 | 7 |
|
8 | 8 | #include "ReClassNET_Plugin.hpp"
|
9 | 9 |
|
@@ -207,65 +207,70 @@ void EnumerateRemoteSectionsAndModules(RC_Pointer remoteId, const std::function<
|
207 | 207 | address = reinterpret_cast<size_t>(memInfo.BaseAddress) + memInfo.RegionSize;
|
208 | 208 | }
|
209 | 209 |
|
210 |
| - const auto handle = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, GetProcessId(remoteId)); |
211 |
| - if (handle != INVALID_HANDLE_VALUE) |
| 210 | + DWORD needed; |
| 211 | + if (EnumProcessModules(remoteId, nullptr, 0, &needed)) |
212 | 212 | {
|
213 |
| - MODULEENTRY32W me32 = {}; |
214 |
| - me32.dwSize = sizeof(MODULEENTRY32W); |
215 |
| - if (Module32FirstW(handle, &me32)) |
| 213 | + std::vector<HMODULE> modules(needed / sizeof(HMODULE)); |
| 214 | + if (EnumProcessModules(remoteId, modules.data(), needed, &needed)) |
216 | 215 | {
|
217 |
| - do |
| 216 | + for (HMODULE curModule : modules) |
218 | 217 | {
|
219 |
| - moduleCallback(static_cast<RC_Pointer>(me32.modBaseAddr), reinterpret_cast<RC_Pointer>(me32.modBaseSize), me32.szExePath); |
| 218 | + MODULEINFO moduleInfo = {}; |
| 219 | + wchar_t modulepath[MAX_PATH] = {}; |
220 | 220 |
|
221 |
| - auto it = std::lower_bound(std::begin(sections), std::end(sections), static_cast<LPVOID>(me32.modBaseAddr), [§ions](const auto& lhs, const LPVOID& rhs) |
| 221 | + if (GetModuleInformation(remoteId, curModule, &moduleInfo, sizeof(moduleInfo)) && |
| 222 | + GetModuleFileNameExW(remoteId, curModule, modulepath, MAX_PATH)) |
222 | 223 | {
|
223 |
| - return lhs.BaseAddress < rhs; |
224 |
| - }); |
| 224 | + moduleCallback((RC_Pointer)moduleInfo.lpBaseOfDll, (RC_Pointer)moduleInfo.SizeOfImage, modulepath); |
225 | 225 |
|
226 |
| - IMAGE_DOS_HEADER DosHdr = {}; |
227 |
| - IMAGE_NT_HEADERS NtHdr = {}; |
228 | 226 |
|
229 |
| - ReadProcessMemory(remoteId, me32.modBaseAddr, &DosHdr, sizeof(IMAGE_DOS_HEADER), nullptr); |
230 |
| - ReadProcessMemory(remoteId, me32.modBaseAddr + DosHdr.e_lfanew, &NtHdr, sizeof(IMAGE_NT_HEADERS), nullptr); |
| 227 | + auto it = std::lower_bound(std::begin(sections), std::end(sections), static_cast<LPVOID>(moduleInfo.lpBaseOfDll), [§ions](const auto& lhs, const LPVOID& rhs) |
| 228 | + { |
| 229 | + return lhs.BaseAddress < rhs; |
| 230 | + }); |
231 | 231 |
|
232 |
| - std::vector<IMAGE_SECTION_HEADER> sectionHeaders(NtHdr.FileHeader.NumberOfSections); |
233 |
| - ReadProcessMemory(remoteId, me32.modBaseAddr + DosHdr.e_lfanew + sizeof(IMAGE_NT_HEADERS), sectionHeaders.data(), NtHdr.FileHeader.NumberOfSections * sizeof(IMAGE_SECTION_HEADER), nullptr); |
234 |
| - for (auto i = 0; i < NtHdr.FileHeader.NumberOfSections; ++i) |
235 |
| - { |
236 |
| - auto&& sectionHeader = sectionHeaders[i]; |
| 232 | + IMAGE_DOS_HEADER DosHdr = {}; |
| 233 | + IMAGE_NT_HEADERS NtHdr = {}; |
| 234 | + |
| 235 | + ReadProcessMemory(remoteId, ((BYTE*)moduleInfo.lpBaseOfDll), &DosHdr, sizeof(IMAGE_DOS_HEADER), NULL); |
| 236 | + ReadProcessMemory(remoteId, ((BYTE*)moduleInfo.lpBaseOfDll) + DosHdr.e_lfanew, &NtHdr, sizeof(IMAGE_NT_HEADERS), NULL); |
| 237 | + |
| 238 | + std::vector<IMAGE_SECTION_HEADER> sectionHeaders(NtHdr.FileHeader.NumberOfSections); |
| 239 | + ReadProcessMemory(remoteId, ((BYTE*)moduleInfo.lpBaseOfDll) + DosHdr.e_lfanew + sizeof(IMAGE_NT_HEADERS), sectionHeaders.data(), NtHdr.FileHeader.NumberOfSections * sizeof(IMAGE_SECTION_HEADER), NULL); |
237 | 240 |
|
238 |
| - const auto sectionAddress = reinterpret_cast<size_t>(me32.modBaseAddr) + sectionHeader.VirtualAddress; |
239 |
| - for (auto j = it; j != std::end(sections); ++j) |
| 241 | + for (auto i = 0; i < NtHdr.FileHeader.NumberOfSections; ++i) |
240 | 242 | {
|
241 |
| - if (sectionAddress >= reinterpret_cast<size_t>(j->BaseAddress) && sectionAddress < reinterpret_cast<size_t>(j->BaseAddress) + static_cast<size_t>(j->Size)) |
242 |
| - { |
243 |
| - // Copy the name because it is not null padded. |
244 |
| - char buffer[IMAGE_SIZEOF_SHORT_NAME + 1] = { 0 }; |
245 |
| - std::memcpy(buffer, sectionHeader.Name, IMAGE_SIZEOF_SHORT_NAME); |
| 243 | + auto&& sectionHeader = sectionHeaders[i]; |
246 | 244 |
|
247 |
| - if (std::strcmp(buffer, ".text") == 0 || std::strcmp(buffer, "code") == 0) |
248 |
| - { |
249 |
| - j->Category = SectionCategory::CODE; |
250 |
| - } |
251 |
| - else if (std::strcmp(buffer, ".data") == 0 || std::strcmp(buffer, "data") == 0 || std::strcmp(buffer, ".rdata") == 0 || std::strcmp(buffer, ".idata") == 0) |
| 245 | + auto sectionAddress = reinterpret_cast<size_t>(moduleInfo.lpBaseOfDll) + sectionHeader.VirtualAddress; |
| 246 | + for (auto j = it; j != std::end(sections); ++j) |
| 247 | + { |
| 248 | + if (sectionAddress >= reinterpret_cast<size_t>(j->BaseAddress) && sectionAddress < reinterpret_cast<size_t>(j->BaseAddress) + static_cast<size_t>(j->Size)) |
252 | 249 | {
|
253 |
| - j->Category = SectionCategory::DATA; |
| 250 | + // Copy the name because it is not null padded. |
| 251 | + char buffer[IMAGE_SIZEOF_SHORT_NAME + 1] = { 0 }; |
| 252 | + std::memcpy(buffer, sectionHeader.Name, IMAGE_SIZEOF_SHORT_NAME); |
| 253 | + |
| 254 | + if (std::strcmp(buffer, ".text") == 0 || std::strcmp(buffer, "code") == 0) |
| 255 | + { |
| 256 | + j->Category = SectionCategory::CODE; |
| 257 | + } |
| 258 | + else if (std::strcmp(buffer, ".data") == 0 || std::strcmp(buffer, "data") == 0 || std::strcmp(buffer, ".rdata") == 0 || std::strcmp(buffer, ".idata") == 0) |
| 259 | + { |
| 260 | + j->Category = SectionCategory::DATA; |
| 261 | + } |
| 262 | + |
| 263 | + MultiByteToUnicode(buffer, j->Name, IMAGE_SIZEOF_SHORT_NAME); |
| 264 | + std::memcpy(j->ModulePath, modulepath, std::min(MAX_PATH, PATH_MAXIMUM_LENGTH)); |
| 265 | + |
| 266 | + break; |
254 | 267 | }
|
255 |
| - |
256 |
| - MultiByteToUnicode(buffer, j->Name, IMAGE_SIZEOF_SHORT_NAME); |
257 |
| - std::memcpy(j->ModulePath, me32.szExePath, std::min(MAX_PATH, PATH_MAXIMUM_LENGTH)); |
258 |
| - |
259 |
| - break; |
260 | 268 | }
|
261 | 269 | }
|
262 |
| - |
263 | 270 | }
|
264 |
| - } while (Module32NextW(handle, &me32)); |
| 271 | + } |
265 | 272 | }
|
266 | 273 |
|
267 |
| - CloseHandle(handle); |
268 |
| - |
269 | 274 | for (auto&& section : sections)
|
270 | 275 | {
|
271 | 276 | sectionCallback(section.BaseAddress, reinterpret_cast<RC_Pointer>(section.Size), section.Type, section.Category, section.Protection, reinterpret_cast<const WCHAR*>(section.Name), reinterpret_cast<const WCHAR*>(section.ModulePath));
|
|
0 commit comments