diff --git a/api/adapter.c b/api/adapter.c index d216578..8fa1ff6 100644 --- a/api/adapter.c +++ b/api/adapter.c @@ -1126,6 +1126,8 @@ SelectDriver( WCHAR CatPath[MAX_PATH] = { 0 }; WCHAR SysPath[MAX_PATH] = { 0 }; WCHAR InfPath[MAX_PATH] = { 0 }; + WCHAR DownlevelShimPath[MAX_PATH] = { 0 }; + if (!PathCombineW(CatPath, RandomTempSubDirectory, L"wintun.cat") || !PathCombineW(SysPath, RandomTempSubDirectory, L"wintun.sys") || !PathCombineW(InfPath, RandomTempSubDirectory, L"wintun.inf")) @@ -1141,6 +1143,53 @@ SelectDriver( LastError = LOG_LAST_ERROR(L"Failed to extract driver"); goto cleanupDelete; } + + WCHAR *WintrustKeyOriginalValue = NULL; + HKEY WintrustKey = NULL; + if (!IsWindows10) + { + LOG(WINTUN_LOG_INFO, L"Shimming downlevel driver loader"); + if (!PathCombineW(DownlevelShimPath, RandomTempSubDirectory, L"downlevelshim.dll")) + { + DownlevelShimPath[0] = L'\0'; + LastError = ERROR_BUFFER_OVERFLOW; + goto cleanupDelete; + } + if (!ResourceCopyToFile(DownlevelShimPath, L"downlevelshim.dll")) + { + LastError = LOG_LAST_ERROR(L"Failed to extract downlevel shim"); + goto cleanupDelete; + } + LastError = RegOpenKeyExW( + HKEY_LOCAL_MACHINE, + L"SOFTWARE\\Microsoft\\Cryptography\\Providers\\Trust\\FinalPolicy\\{F750E6C3-38EE-11D1-85E5-00C04FC295EE}", + 0, + KEY_QUERY_VALUE | KEY_SET_VALUE, + &WintrustKey); + if (LastError != ERROR_SUCCESS) + { + LOG_ERROR(LastError, L"Failed to open Wintrust FinalPolicy key"); + goto cleanupDelete; + } + WintrustKeyOriginalValue = RegistryQueryString(WintrustKey, L"$DLL", TRUE); + if (!WintrustKeyOriginalValue) + { + LastError = LOG_LAST_ERROR(L"Failed to read current Wintrust FinalPolicy key"); + goto cleanupWintrustKey; + } + LastError = RegSetValueExW( + WintrustKey, + L"$DLL", + 0, + REG_SZ, + (BYTE *)DownlevelShimPath, + (DWORD)((wcslen(DownlevelShimPath) + 1) * sizeof(DownlevelShimPath[0]))); + if (LastError != ERROR_SUCCESS) + { + LOG_ERROR(LastError, L"Failed to set Wintrust FinalPolicy key"); + goto cleanupWintrustChangedKey; + } + } LOG(WINTUN_LOG_INFO, L"Installing driver"); WCHAR InfStorePath[MAX_PATH]; if (!SetupCopyOEMInfW(InfPath, NULL, SPOST_NONE, 0, InfStorePath, MAX_PATH, NULL, NULL)) @@ -1185,10 +1234,26 @@ SelectDriver( LastError = ERROR_SUCCESS; DestroyDriverInfoListOnCleanup = FALSE; +cleanupWintrustChangedKey: + if (WintrustKeyOriginalValue) + RegSetValueExW( + WintrustKey, + L"$DLL", + 0, + REG_SZ, + (BYTE *)WintrustKeyOriginalValue, + (DWORD)((wcslen(WintrustKeyOriginalValue) + 1) * sizeof(WintrustKeyOriginalValue[0]))); +cleanupWintrustKey: + if (WintrustKey) + RegCloseKey(WintrustKey); + if (WintrustKeyOriginalValue) + Free(WintrustKeyOriginalValue); cleanupDelete: DeleteFileW(CatPath); DeleteFileW(SysPath); DeleteFileW(InfPath); + if (DownlevelShimPath[0]) + DeleteFileW(DownlevelShimPath); cleanupDirectory: RemoveDirectoryW(RandomTempSubDirectory); cleanupExistingAdapters: diff --git a/api/resources.rc b/api/resources.rc index ad4c98c..822ed3f 100644 --- a/api/resources.rc +++ b/api/resources.rc @@ -12,6 +12,8 @@ wintun.cat RCDATA "driver\\wintun.cat" wintun.inf RCDATA "driver\\wintun.inf" wintun.sys RCDATA "driver\\wintun.sys" +downlevelshim.dll RCDATA "downlevelshim.dll" + #if defined(WANT_AMD64_WOW64) # if defined(BUILT_AMD64_WOW64) wintun-amd64.dll RCDATA "amd64\\wintun.dll" diff --git a/downlevelshim/downlevelshim.vcxproj b/downlevelshim/downlevelshim.vcxproj new file mode 100644 index 0000000..cf403e0 --- /dev/null +++ b/downlevelshim/downlevelshim.vcxproj @@ -0,0 +1,35 @@ + + + + {6E8213E6-5046-4DE8-A760-0932C7D6E33E} + downlevelshim + downlevelshim + + + DynamicLibrary + WindowsApplicationForDrivers10.0 + + + + downlevelshim + + + + _WINDOWS;_USRDLL;%(PreprocessorDefinitions) + /volatile:iso %(AdditionalOptions) + + + exports.def + Windows + + + + + + + + + + + + diff --git a/downlevelshim/exports.def b/downlevelshim/exports.def new file mode 100644 index 0000000..7d2ec36 --- /dev/null +++ b/downlevelshim/exports.def @@ -0,0 +1,3 @@ +LIBRARY downlevelshim.dll +EXPORTS + DriverFinalPolicy \ No newline at end of file diff --git a/downlevelshim/shim.c b/downlevelshim/shim.c new file mode 100644 index 0000000..d277639 --- /dev/null +++ b/downlevelshim/shim.c @@ -0,0 +1,32 @@ +/* SPDX-License-Identifier: GPL-2.0 + * + * Copyright (C) 2018-2021 WireGuard LLC. All Rights Reserved. + */ + +#include +#include + +typedef DWORD(DRIVER_FINAL_POLICY_FN)(CRYPT_PROVIDER_DATA *); +typedef DRIVER_FINAL_POLICY_FN *PDRIVER_FINAL_POLICY_FN; + +DRIVER_FINAL_POLICY_FN DriverFinalPolicy; + +DWORD +DriverFinalPolicy(CRYPT_PROVIDER_DATA *ProvData) +{ + DWORD OriginalLastError = GetLastError(); + HMODULE WintrustModule = GetModuleHandleA("WINTRUST.DLL"); + if (!WintrustModule) + return ERROR_INVALID_LIBRARY; + PDRIVER_FINAL_POLICY_FN RealDriverFinalPolicy = + (PDRIVER_FINAL_POLICY_FN)GetProcAddress(WintrustModule, "DriverFinalPolicy"); + if (!RealDriverFinalPolicy) + return ERROR_INVALID_FUNCTION; + DWORD Ret = RealDriverFinalPolicy(ProvData); + if (Ret == ERROR_APP_WRONG_OS) + { + Ret = ERROR_SUCCESS; + SetLastError(OriginalLastError); + } + return Ret; +} diff --git a/wintun.proj b/wintun.proj index a1cd244..3715f93 100644 --- a/wintun.proj +++ b/wintun.proj @@ -80,21 +80,21 @@ - + - + - + - +