summaryrefslogtreecommitdiffhomepage
path: root/windows
diff options
context:
space:
mode:
authorDavid Lönnhager <david.l@mullvad.net>2021-02-17 12:04:28 +0100
committerDavid Lönnhager <david.l@mullvad.net>2021-02-17 13:03:21 +0100
commitb36a32c4fe8247f032b55dd0dce23d114d6e4e73 (patch)
treec1cfcca1e51005c0a1064af9f424867a30855115 /windows
parentbc64150c42fa16d4bbd180dd06aadb7a35a8eb4e (diff)
downloadmullvadvpn-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.cpp71
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;
}
}