diff options
| author | David Lönnhager <david.l@mullvad.net> | 2021-02-17 12:04:28 +0100 |
|---|---|---|
| committer | David Lönnhager <david.l@mullvad.net> | 2021-02-17 13:03:21 +0100 |
| commit | b36a32c4fe8247f032b55dd0dce23d114d6e4e73 (patch) | |
| tree | c1cfcca1e51005c0a1064af9f424867a30855115 /windows | |
| parent | bc64150c42fa16d4bbd180dd06aadb7a35a8eb4e (diff) | |
| download | mullvadvpn-b36a32c4fe8247f032b55dd0dce23d114d6e4e73.tar.xz mullvadvpn-b36a32c4fe8247f032b55dd0dce23d114d6e4e73.zip | |
Use file mapping for patch check
Diffstat (limited to 'windows')
| -rw-r--r-- | windows/nsis-plugins/src/os/update.cpp | 71 |
1 files changed, 64 insertions, 7 deletions
diff --git a/windows/nsis-plugins/src/os/update.cpp b/windows/nsis-plugins/src/os/update.cpp index 2f349ac687..a300882407 100644 --- a/windows/nsis-plugins/src/os/update.cpp +++ b/windows/nsis-plugins/src/os/update.cpp @@ -2,6 +2,7 @@ #include "update.h" #include <libcommon/error.h> #include <libcommon/filesystem.h> +#include <libcommon/memory.h> #include <algorithm> #include <fstream> #include <filesystem> @@ -20,21 +21,77 @@ namespace update bool HasSetupApiSha2Fix() { + common::memory::ScopeDestructor destructor; + common::fs::ScopedNativeFileSystem nativeFileSystem; const auto systemDir = common::fs::GetKnownFolderPath(FOLDERID_System, KF_FLAG_DEFAULT, NULL); const auto setupApiPath = std::filesystem::path(systemDir).append(L"setupapi.dll"); - std::ifstream ifs(setupApiPath, std::ios_base::binary); - if (!ifs) + const auto setupApiHandle = CreateFileW( + setupApiPath.c_str(), + GENERIC_READ, + FILE_SHARE_READ, + nullptr, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + nullptr + ); + + if (INVALID_HANDLE_VALUE == setupApiHandle) + { + THROW_WINDOWS_ERROR(GetLastError(), "CreateFileW"); + } + + destructor += [=]() { + CloseHandle(setupApiHandle); + }; + + const auto mapping = CreateFileMappingW(setupApiHandle, nullptr, PAGE_READONLY, 0, 0, nullptr); + + if (nullptr == mapping) + { + THROW_WINDOWS_ERROR(GetLastError(), "CreateFileMappingW"); + } + + destructor += [=]() { + CloseHandle(mapping); + }; + + const auto bytes = MapViewOfFile(mapping, FILE_MAP_READ, 0, 0, 0); + + if (nullptr == bytes) + { + THROW_WINDOWS_ERROR(GetLastError(), "MapViewOfFile"); + } + + destructor += [=]() { + UnmapViewOfFile(bytes); + }; + + MEMORY_BASIC_INFORMATION meminfo; + + if (0 == VirtualQuery(bytes, &meminfo, sizeof(meminfo))) + { + THROW_WINDOWS_ERROR(GetLastError(), "CreateFileW"); + } + + constexpr auto PATCH_MARKER_SIZE = sizeof(PATCH_MARKER) - 1; + + if (meminfo.RegionSize < PATCH_MARKER_SIZE) + { + return false; + } + + for (size_t i = 0; i <= meminfo.RegionSize - PATCH_MARKER_SIZE; i++) { - // Maybe sketchy to rely on GLE here - THROW_WINDOWS_ERROR(GetLastError(), "Failed to open setupapi.dll"); + if (0 == memcmp((void*)((char*)bytes + i), PATCH_MARKER, PATCH_MARKER_SIZE)) + { + return true; + } } - const auto marker_end = PATCH_MARKER + sizeof(PATCH_MARKER) - sizeof('\0'); - const auto last = std::istreambuf_iterator<char>(); - return (last != std::search(std::istreambuf_iterator<char>(ifs), last, PATCH_MARKER, marker_end)); + return false; } } |
