Skip to content

Instantly share code, notes, and snippets.

@0x1F9F1
Last active April 6, 2023 12:22
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save 0x1F9F1/dbe1bcdc76e333c5c5128dc04f2b401c to your computer and use it in GitHub Desktop.
Save 0x1F9F1/dbe1bcdc76e333c5c5128dc04f2b401c to your computer and use it in GitHub Desktop.
FindModule
#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