| 89 | } |
| 90 | |
| 91 | __forceinline auto get_kmodule_base(const char* module_name) -> std::uintptr_t |
| 92 | { |
| 93 | void* buffer = nullptr; |
| 94 | DWORD buffer_size = NULL; |
| 95 | |
| 96 | auto status = NtQuerySystemInformation( |
| 97 | static_cast<SYSTEM_INFORMATION_CLASS>(SystemModuleInformation), |
| 98 | buffer, buffer_size, &buffer_size); |
| 99 | |
| 100 | while (status == STATUS_INFO_LENGTH_MISMATCH) |
| 101 | { |
| 102 | VirtualFree(buffer, NULL, MEM_RELEASE); |
| 103 | buffer = VirtualAlloc(nullptr, buffer_size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); |
| 104 | status = NtQuerySystemInformation( |
| 105 | static_cast<SYSTEM_INFORMATION_CLASS>(SystemModuleInformation), |
| 106 | buffer, buffer_size, &buffer_size); |
| 107 | } |
| 108 | |
| 109 | if (!NT_SUCCESS(status)) |
| 110 | { |
| 111 | VirtualFree(buffer, NULL, MEM_RELEASE); |
| 112 | return NULL; |
| 113 | } |
| 114 | |
| 115 | const auto modules = static_cast<PRTL_PROCESS_MODULES>(buffer); |
| 116 | for (auto idx = 0u; idx < modules->NumberOfModules; ++idx) |
| 117 | { |
| 118 | const std::string current_module_name = std::string(reinterpret_cast<char*>(modules->Modules[idx].FullPathName) + modules->Modules[idx].OffsetToFileName); |
| 119 | if (!_stricmp(current_module_name.c_str(), module_name)) |
| 120 | { |
| 121 | const uint64_t result = reinterpret_cast<uint64_t>(modules->Modules[idx].ImageBase); |
| 122 | VirtualFree(buffer, NULL, MEM_RELEASE); |
| 123 | return result; |
| 124 | } |
| 125 | } |
| 126 | |
| 127 | VirtualFree(buffer, NULL, MEM_RELEASE); |
| 128 | return NULL; |
| 129 | } |
| 130 | |
| 131 | __forceinline auto get_kmodule_export(const char* module_name, const char* export_name, bool rva = false) -> void* |
| 132 | { |
nothing calls this directly
no outgoing calls
no test coverage detected