|
34 | 34 |
|
35 | 35 | #pragma comment(lib, "rpcrt4.lib") |
36 | 36 | #pragma comment(lib, "httpapi.lib") |
| 37 | +#pragma comment(lib, "psapi.lib") |
37 | 38 |
|
38 | 39 | #include <cstdio> |
39 | 40 | #include <iostream> |
40 | 41 | #include <memory> |
41 | 42 | #include <algorithm> |
| 43 | +#include <psapi.h> |
42 | 44 | #include <stdexcept> |
43 | 45 | #include <string> |
44 | 46 | #include <array> |
@@ -80,6 +82,7 @@ void integrity_watchdog(); |
80 | 82 | std::string extract_host(const std::string& url); |
81 | 83 | bool hosts_override_present(const std::string& host); |
82 | 84 | bool module_paths_ok(); |
| 85 | +bool duplicate_system_modules_present(); |
83 | 86 | std::string seed; |
84 | 87 | void cleanUpSeedData(const std::string& seed); |
85 | 88 | std::string signature; |
@@ -1795,6 +1798,42 @@ bool module_paths_ok() |
1795 | 1798 | return true; |
1796 | 1799 | } |
1797 | 1800 |
|
| 1801 | +bool duplicate_system_modules_present() |
| 1802 | +{ |
| 1803 | + const wchar_t* kModules[] = { L"ntdll.dll", L"kernel32.dll", L"kernelbase.dll", L"user32.dll" }; |
| 1804 | + const wchar_t* sysroot_env = _wgetenv(L"SystemRoot"); |
| 1805 | + std::wstring sysroot = sysroot_env ? sysroot_env : L"C:\\Windows"; |
| 1806 | + std::wstring sys32 = to_lower_ws(sysroot + L"\\System32\\"); |
| 1807 | + std::wstring syswow = to_lower_ws(sysroot + L"\\SysWOW64\\"); |
| 1808 | + |
| 1809 | + HMODULE mods[1024] = {}; |
| 1810 | + DWORD needed = 0; |
| 1811 | + if (!EnumProcessModules(GetCurrentProcess(), mods, sizeof(mods), &needed)) |
| 1812 | + return false; |
| 1813 | + |
| 1814 | + const size_t count = needed / sizeof(HMODULE); |
| 1815 | + for (size_t i = 0; i < count; ++i) { |
| 1816 | + wchar_t path[MAX_PATH] = {}; |
| 1817 | + if (!GetModuleFileNameExW(GetCurrentProcess(), mods[i], path, MAX_PATH)) |
| 1818 | + continue; |
| 1819 | + std::wstring p = to_lower_ws(path); |
| 1820 | + const auto name_pos = p.find_last_of(L"\\/"); |
| 1821 | + const std::wstring name = (name_pos == std::wstring::npos) ? p : p.substr(name_pos + 1); |
| 1822 | + bool is_target = false; |
| 1823 | + for (const auto* modname : kModules) { |
| 1824 | + if (name == modname) { |
| 1825 | + is_target = true; |
| 1826 | + break; |
| 1827 | + } |
| 1828 | + } |
| 1829 | + if (!is_target) |
| 1830 | + continue; |
| 1831 | + if (p.rfind(sys32, 0) != 0 && p.rfind(syswow, 0) != 0) |
| 1832 | + return true; |
| 1833 | + } |
| 1834 | + return false; |
| 1835 | +} |
| 1836 | + |
1798 | 1837 | void KeyAuth::api::setDebug(bool value) { |
1799 | 1838 | KeyAuth::api::debug = value; |
1800 | 1839 | } |
@@ -2181,7 +2220,7 @@ void checkInit() { |
2181 | 2220 | const auto last_mod = last_module_check.load(); |
2182 | 2221 | if (now - last_mod > 60) { |
2183 | 2222 | last_module_check.store(now); |
2184 | | - if (!module_paths_ok()) { |
| 2223 | + if (!module_paths_ok() || duplicate_system_modules_present()) { |
2185 | 2224 | error(XorStr("module path check failed, possible side-load detected.")); |
2186 | 2225 | } |
2187 | 2226 | } |
@@ -2213,7 +2252,7 @@ void integrity_watchdog() { |
2213 | 2252 | const auto last_mod = last_module_check.load(); |
2214 | 2253 | if (now - last_mod > 120) { |
2215 | 2254 | last_module_check.store(now); |
2216 | | - if (!module_paths_ok()) { |
| 2255 | + if (!module_paths_ok() || duplicate_system_modules_present()) { |
2217 | 2256 | error(XorStr("module path check failed, possible side-load detected.")); |
2218 | 2257 | } |
2219 | 2258 | } |
|
0 commit comments