Last active
April 6, 2023 12:22
-
-
Save 0x1F9F1/dbe1bcdc76e333c5c5128dc04f2b401c to your computer and use it in GitHub Desktop.
FindModule
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <Windows.h> | |
#include <TlHelp32.h> | |
#include <functional> | |
typedef struct _UNICODE_STRING | |
{ | |
USHORT Length; | |
USHORT MaximumLength; | |
PWSTR Buffer; | |
} UNICODE_STRING; | |
typedef enum _MEMORY_INFORMATION_CLASS | |
{ | |
MemoryBasicInformation, | |
MemoryWorkingSetList, | |
MemorySectionName, | |
MemoryBasicVlmInformation | |
} MEMORY_INFORMATION_CLASS; | |
typedef struct _MEMORY_SECTION_NAME | |
{ | |
UNICODE_STRING SectionFileName; | |
WCHAR NameBuffer[ANYSIZE_ARRAY]; | |
} MEMORY_SECTION_NAME, *PMEMORY_SECTION_NAME; | |
bool NtPathToDosPath(const wchar_t* ntPath, wchar_t* buffer, size_t length) | |
{ | |
wchar_t device_name[3] = L" :"; | |
wchar_t target_path[128]; | |
for (wchar_t i = L'A'; i <= L'Z'; ++i) | |
{ | |
device_name[0] = i; | |
if (QueryDosDeviceW(device_name, target_path, 128)) | |
{ | |
size_t target_length = wcslen(target_path); | |
if (!_wcsnicmp(ntPath, target_path, target_length)) | |
{ | |
wcscpy_s(buffer, length, device_name); | |
wcscat_s(buffer, length, ntPath + target_length); | |
return true; | |
} | |
} | |
} | |
return false; | |
} | |
const auto pNtQueryVirtualMemory = reinterpret_cast<NTSTATUS(*)( | |
HANDLE ProcessHandle, | |
PVOID BaseAddress, | |
MEMORY_INFORMATION_CLASS MemoryInformationClass, | |
PVOID MemoryInformation, | |
SIZE_T MemoryInformationLength, | |
PSIZE_T ReturnLength | |
)>(GetProcAddress(LoadLibraryA("ntdll.dll"), "NtQueryVirtualMemory")); | |
bool QueryMemoryPath(HANDLE hProc, void* address, wchar_t* buffer, size_t buffer_size) | |
{ | |
union | |
{ | |
MEMORY_SECTION_NAME value; | |
WCHAR buffer[1024]; | |
} data; | |
if (pNtQueryVirtualMemory(hProc, address, MemorySectionName, &data, sizeof(data), nullptr) == NO_ERROR) | |
{ | |
if (NtPathToDosPath(data.value.SectionFileName.Buffer, buffer, buffer_size)) | |
{ | |
return true; | |
} | |
} | |
return false; | |
} | |
void EnumAllMemory(HANDLE hProc, std::function<void(const MEMORY_BASIC_INFORMATION*)> callback) | |
{ | |
MEMORY_BASIC_INFORMATION data; | |
void* address = nullptr; | |
while (pNtQueryVirtualMemory(hProc, address, MemoryBasicInformation, &data, sizeof(data), nullptr) == NO_ERROR) | |
{ | |
callback(&data); | |
address = static_cast<uint8_t*>(data.BaseAddress) + data.RegionSize; | |
} | |
} | |
void EnumAllImages(HANDLE hProc, std::function<void(const MEMORY_BASIC_INFORMATION*, const wchar_t*)> callback) | |
{ | |
EnumAllMemory(hProc, [hProc, &callback] (const MEMORY_BASIC_INFORMATION* info) | |
{ | |
if (info->Type == MEM_IMAGE) | |
{ | |
wchar_t buffer[1024]; | |
if (QueryMemoryPath(hProc, info->BaseAddress, buffer, 1024)) | |
{ | |
callback(info, buffer); | |
} | |
} | |
}); | |
} | |
DWORD GetProcessID(const wchar_t* processName) | |
{ | |
HANDLE hProcSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL); | |
PROCESSENTRY32W processEntry = { sizeof(processEntry) }; | |
if (Process32FirstW(hProcSnapshot, &processEntry)) | |
{ | |
do | |
{ | |
if (_wcsicmp(processName, processEntry.szExeFile) == 0) // If the strings are equal (ignoring case) | |
{ | |
CloseHandle(hProcSnapshot); | |
return processEntry.th32ProcessID; | |
} | |
} while (Process32NextW(hProcSnapshot, &processEntry)); | |
} | |
CloseHandle(hProcSnapshot); | |
return 0; | |
} | |
int main() | |
{ | |
const wchar_t* module_name = L"namehere.dll"; | |
HANDLE hProc = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION | PROCESS_VM_READ, FALSE, GetProcessID(L"gta5.exe")); | |
uint8_t* start = nullptr; | |
uint8_t* end = nullptr; | |
EnumAllImages(hProc, [module_name, hProc, &start, &end] (const MEMORY_BASIC_INFORMATION* region, const wchar_t* path) | |
{ | |
// std::printf("%ls\n", path); | |
if (!_wcsicmp(wcsrchr(path, L'\\') + 1, module_name)) | |
{ | |
if (start == nullptr) | |
{ | |
start = (uint8_t*)(region->BaseAddress); | |
} | |
end = (uint8_t*)(region->BaseAddress) + region->RegionSize; | |
std::printf("%p => %8zX: %ls\n", region->BaseAddress, region->RegionSize, path); | |
#if 0 | |
wchar_t file_name[256]; | |
swprintf_s(file_name, L"%s_0x%p.dmp", module_name, region->BaseAddress); | |
FILE* output = nullptr; | |
_wfopen_s(&output, file_name, L"wb"); | |
uint8_t* buffer = new uint8_t[region->RegionSize]; | |
ReadProcessMemory(hProc, region->BaseAddress, buffer, region->RegionSize, nullptr); | |
fwrite(buffer, region->RegionSize, 1, output); | |
fclose(output); | |
delete buffer; | |
#endif | |
} | |
}); | |
std::printf("%p => %8zx\n", start, end - start); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment