Skip to content

Commit 55081a8

Browse files
authored
Merge pull request #1 from DrP3pp3r/master
Remove usage of the Tool Help API
2 parents 8340aaf + 1ca4d65 commit 55081a8

File tree

1 file changed

+47
-42
lines changed

1 file changed

+47
-42
lines changed

PipeServer/MemoryHelper.cpp

Lines changed: 47 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
#include <cstdint>
44
#include <algorithm>
55
#include <functional>
6-
#include <tlhelp32.h>
6+
#include <psapi.h>
77

88
#include "ReClassNET_Plugin.hpp"
99

@@ -207,65 +207,70 @@ void EnumerateRemoteSectionsAndModules(RC_Pointer remoteId, const std::function<
207207
address = reinterpret_cast<size_t>(memInfo.BaseAddress) + memInfo.RegionSize;
208208
}
209209

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))
212212
{
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))
216215
{
217-
do
216+
for (HMODULE curModule : modules)
218217
{
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] = {};
220220

221-
auto it = std::lower_bound(std::begin(sections), std::end(sections), static_cast<LPVOID>(me32.modBaseAddr), [&sections](const auto& lhs, const LPVOID& rhs)
221+
if (GetModuleInformation(remoteId, curModule, &moduleInfo, sizeof(moduleInfo)) &&
222+
GetModuleFileNameExW(remoteId, curModule, modulepath, MAX_PATH))
222223
{
223-
return lhs.BaseAddress < rhs;
224-
});
224+
moduleCallback((RC_Pointer)moduleInfo.lpBaseOfDll, (RC_Pointer)moduleInfo.SizeOfImage, modulepath);
225225

226-
IMAGE_DOS_HEADER DosHdr = {};
227-
IMAGE_NT_HEADERS NtHdr = {};
228226

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), [&sections](const auto& lhs, const LPVOID& rhs)
228+
{
229+
return lhs.BaseAddress < rhs;
230+
});
231231

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);
237240

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)
240242
{
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];
246244

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))
252249
{
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;
254267
}
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;
260268
}
261269
}
262-
263270
}
264-
} while (Module32NextW(handle, &me32));
271+
}
265272
}
266273

267-
CloseHandle(handle);
268-
269274
for (auto&& section : sections)
270275
{
271276
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

Comments
 (0)