| 25 | EXTERN_C NTSYSAPI NTSTATUS NTAPI NtQueryVirtualMemory(HANDLE processHandle, void* baseAddress, MEMORY_INFORMATION_CLASS memoryInformationClass, void* memoryInformation, size_t memoryInformationLength, size_t* returnLength); |
| 26 | |
| 27 | ULONG64 GetModule(UINT32 pid, const wchar_t* moduleName) |
| 28 | { |
| 29 | HANDLE targetProcessHandle = OpenProcess(PROCESS_QUERY_INFORMATION, 0, pid); |
| 30 | if (!targetProcessHandle || targetProcessHandle == INVALID_HANDLE_VALUE) |
| 31 | return 0; |
| 32 | |
| 33 | ULONG64 currentAddress = 0; |
| 34 | MEMORY_BASIC_INFORMATION memoryInformation; |
| 35 | while (VirtualQueryEx(targetProcessHandle, reinterpret_cast<void*>(currentAddress), &memoryInformation, sizeof(MEMORY_BASIC_INFORMATION64))) |
| 36 | { |
| 37 | if (memoryInformation.Type == MEM_MAPPED || memoryInformation.Type == MEM_IMAGE) |
| 38 | { |
| 39 | constexpr size_t bufferSize = 1024; |
| 40 | void* buffer = malloc(bufferSize); |
| 41 | |
| 42 | size_t bytesOut; |
| 43 | NTSTATUS status = NtQueryVirtualMemory(targetProcessHandle, memoryInformation.BaseAddress, MemoryMappedFilenameInformation, buffer, bufferSize, &bytesOut); |
| 44 | if (status == 0) |
| 45 | { |
| 46 | UNICODE_STRING* stringBuffer = static_cast<UNICODE_STRING*>(buffer); |
| 47 | if (wcsstr(stringBuffer->Buffer, moduleName) && !wcsstr(stringBuffer->Buffer, L".mui")) |
| 48 | { |
| 49 | free(buffer); |
| 50 | CloseHandle(targetProcessHandle); |
| 51 | return reinterpret_cast<ULONG64>(memoryInformation.BaseAddress); |
| 52 | } |
| 53 | } |
| 54 | |
| 55 | free(buffer); |
| 56 | } |
| 57 | |
| 58 | currentAddress = reinterpret_cast<ULONG64>(memoryInformation.BaseAddress) + memoryInformation.RegionSize; |
| 59 | } |
| 60 | |
| 61 | CloseHandle(targetProcessHandle); |
| 62 | return 0; |
| 63 | } |
| 64 | |
| 65 | UINT32 LookupProcessId(const wchar_t* processName) |
| 66 | { |