diff --git a/api/adapter.c b/api/adapter.c index 963f17d..3c65bb2 100644 --- a/api/adapter.c +++ b/api/adapter.c @@ -20,7 +20,6 @@ #include #include "adapter.h" -#include "elevate.h" #include "entry.h" #include "logger.h" #include "namespace.h" @@ -1421,62 +1420,6 @@ static _Return_type_success_(return != NULL) WINTUN_ADAPTER *CreateAdapter( if (!IsWindows10()) RequestedGUID = NULL; - if (RequestedGUID) - { - WCHAR RegPath[MAX_REG_PATH]; - WCHAR RequestedGUIDStr[MAX_GUID_STRING_LEN]; - int GuidStrLen = StringFromGUID2(RequestedGUID, RequestedGUIDStr, _countof(RequestedGUIDStr)) * sizeof(WCHAR); - if (_snwprintf_s( - RegPath, - MAX_REG_PATH, - _TRUNCATE, - L"SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\%.*s\\Connection", - GuidStrLen, - RequestedGUIDStr) == -1) - goto guidIsFresh; - HKEY Key; - if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, RegPath, 0, KEY_QUERY_VALUE, &Key) != ERROR_SUCCESS) - goto guidIsFresh; - WCHAR *InstanceID = RegistryQueryString(Key, L"PnPInstanceId", FALSE); - RegCloseKey(Key); - if (!InstanceID) - goto guidIsFresh; - int Ret = _snwprintf_s(RegPath, MAX_REG_PATH, _TRUNCATE, L"SYSTEM\\CurrentControlSet\\Enum\\%s", InstanceID); - Free(InstanceID); - if (Ret == -1) - goto guidIsFresh; - if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, RegPath, 0, KEY_QUERY_VALUE, &Key) == ERROR_SUCCESS) - { - RegCloseKey(Key); - MIB_IF_ROW2 IfRow = { 0 }; - if (ConvertInterfaceGuidToLuid(RequestedGUID, &IfRow.InterfaceLuid) == NO_ERROR && - GetIfEntry2(&IfRow) == NO_ERROR && IfRow.OperStatus != IfOperStatusNotPresent) - { - SetLastError( - LOG_ERROR(ERROR_ALREADY_EXISTS, L"Requested GUID is already in use: %s", RequestedGUIDStr)); - return NULL; - } - } - LOG(WINTUN_LOG_WARN, L"Requested GUID %s has leftover residue", RequestedGUIDStr); - HANDLE OriginalToken; - if (!ImpersonateService(L"NetSetupSvc", &OriginalToken)) - { - LOG_LAST_ERROR(L"Unable to impersonate NetSetupSvc"); - goto guidIsFresh; // non-fatal - } - if (_snwprintf_s( - RegPath, - MAX_REG_PATH, - _TRUNCATE, - L"SYSTEM\\CurrentControlSet\\Control\\NetworkSetup2\\Interfaces\\%.*s", - GuidStrLen, - RequestedGUIDStr) == -1 || - !RegistryDeleteKeyRecursive(HKEY_LOCAL_MACHINE, RegPath)) - LOG_LAST_ERROR(L"Unable to delete NetworkSetup2 registry key"); // non-fatal - RestoreToken(OriginalToken); - guidIsFresh:; - } - HDEVINFO DevInfo = SetupDiCreateDeviceInfoListExW(&GUID_DEVCLASS_NET, NULL, NULL, NULL); if (DevInfo == INVALID_HANDLE_VALUE) { @@ -1566,19 +1509,13 @@ static _Return_type_success_(return != NULL) WINTUN_ADAPTER *CreateAdapter( } if (RequestedGUID) { - WCHAR RequestedGUIDStr[MAX_GUID_STRING_LEN]; LastError = RegSetValueExW( - NetDevRegKey, - L"NetSetupAnticipatedInstanceId", - 0, - REG_SZ, - (const BYTE *)RequestedGUIDStr, - StringFromGUID2(RequestedGUID, RequestedGUIDStr, _countof(RequestedGUIDStr)) * sizeof(WCHAR)); + NetDevRegKey, L"SuggestedInstanceId", 0, REG_BINARY, (const BYTE *)RequestedGUID, sizeof(*RequestedGUID)); if (LastError != ERROR_SUCCESS) { WCHAR RegPath[MAX_REG_PATH]; LoggerGetRegistryKeyPath(NetDevRegKey, RegPath); - LOG_ERROR(LastError, L"Failed to set %.*s\\NetSetupAnticipatedInstanceId", MAX_REG_PATH, RegPath); + LOG_ERROR(LastError, L"Failed to set %.*s\\SuggestedInstanceId", MAX_REG_PATH, RegPath); goto cleanupNetDevRegKey; } } diff --git a/api/api.vcxproj b/api/api.vcxproj index 5e7d462..79a9932 100644 --- a/api/api.vcxproj +++ b/api/api.vcxproj @@ -156,7 +156,6 @@ - true @@ -171,7 +170,6 @@ - diff --git a/api/api.vcxproj.filters b/api/api.vcxproj.filters index 682681e..05c580d 100644 --- a/api/api.vcxproj.filters +++ b/api/api.vcxproj.filters @@ -49,9 +49,6 @@ Header Files - - Header Files - Header Files @@ -84,11 +81,8 @@ Source Files - - Source Files - Source Files - \ No newline at end of file + diff --git a/api/elevate.c b/api/elevate.c deleted file mode 100644 index 61cd7ee..0000000 --- a/api/elevate.c +++ /dev/null @@ -1,248 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 - * - * Copyright (C) 2018-2021 WireGuard LLC. All Rights Reserved. - */ - -#include "elevate.h" -#include "logger.h" - -#include -#include - -static _Return_type_success_(return != FALSE) BOOL ElevateToSystem(void) -{ - HANDLE CurrentProcessToken, ThreadToken, ProcessSnapshot, WinlogonProcess, WinlogonToken, DuplicatedToken; - PROCESSENTRY32W ProcessEntry = { .dwSize = sizeof(PROCESSENTRY32W) }; - BOOL Ret; - DWORD LastError = ERROR_SUCCESS; - TOKEN_PRIVILEGES Privileges = { .PrivilegeCount = 1, .Privileges = { { .Attributes = SE_PRIVILEGE_ENABLED } } }; - CHAR LocalSystemSid[MAX_SID_SIZE]; - DWORD RequiredBytes = sizeof(LocalSystemSid); - struct - { - TOKEN_USER MaybeLocalSystem; - CHAR LargeEnoughForLocalSystem[MAX_SID_SIZE]; - } TokenUserBuffer; - - Ret = CreateWellKnownSid(WinLocalSystemSid, NULL, &LocalSystemSid, &RequiredBytes); - if (!Ret) - { - LastError = LOG_LAST_ERROR(L"Failed to create SID"); - goto cleanup; - } - Ret = OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &CurrentProcessToken); - if (!Ret) - { - LastError = LOG_LAST_ERROR(L"Failed to open process token"); - goto cleanup; - } - Ret = - GetTokenInformation(CurrentProcessToken, TokenUser, &TokenUserBuffer, sizeof(TokenUserBuffer), &RequiredBytes); - LastError = GetLastError(); - CloseHandle(CurrentProcessToken); - if (!Ret) - { - LOG_ERROR(LastError, L"Failed to get token information"); - goto cleanup; - } - if (EqualSid(TokenUserBuffer.MaybeLocalSystem.User.Sid, LocalSystemSid)) - return ImpersonateSelf(SecurityImpersonation); - Ret = LookupPrivilegeValueW(NULL, SE_DEBUG_NAME, &Privileges.Privileges[0].Luid); - if (!Ret) - { - LastError = LOG_LAST_ERROR(L"Failed to lookup privilege value"); - goto cleanup; - } - ProcessSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); - if (ProcessSnapshot == INVALID_HANDLE_VALUE) - { - LastError = LOG_LAST_ERROR(L"Failed to create toolhelp snapshot"); - goto cleanup; - } - for (Ret = Process32FirstW(ProcessSnapshot, &ProcessEntry); Ret; - Ret = Process32NextW(ProcessSnapshot, &ProcessEntry)) - { - if (_wcsicmp(ProcessEntry.szExeFile, L"winlogon.exe")) - continue; - RevertToSelf(); - Ret = ImpersonateSelf(SecurityImpersonation); - if (!Ret) - { - LastError = GetLastError(); - continue; - } - Ret = OpenThreadToken(GetCurrentThread(), TOKEN_ADJUST_PRIVILEGES, FALSE, &ThreadToken); - if (!Ret) - { - LastError = GetLastError(); - continue; - } - Ret = AdjustTokenPrivileges(ThreadToken, FALSE, &Privileges, 0, NULL, NULL); - LastError = GetLastError(); - CloseHandle(ThreadToken); - if (!Ret) - continue; - - WinlogonProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, ProcessEntry.th32ProcessID); - if (!WinlogonProcess) - { - LastError = GetLastError(); - continue; - } - Ret = OpenProcessToken(WinlogonProcess, TOKEN_IMPERSONATE | TOKEN_DUPLICATE, &WinlogonToken); - LastError = GetLastError(); - CloseHandle(WinlogonProcess); - if (!Ret) - continue; - Ret = DuplicateToken(WinlogonToken, SecurityImpersonation, &DuplicatedToken); - LastError = GetLastError(); - CloseHandle(WinlogonToken); - if (!Ret) - continue; - if (!GetTokenInformation(DuplicatedToken, TokenUser, &TokenUserBuffer, sizeof(TokenUserBuffer), &RequiredBytes)) - goto next; - if (!EqualSid(TokenUserBuffer.MaybeLocalSystem.User.Sid, LocalSystemSid)) - { - SetLastError(ERROR_ACCESS_DENIED); - goto next; - } - if (!SetThreadToken(NULL, DuplicatedToken)) - goto next; - CloseHandle(DuplicatedToken); - CloseHandle(ProcessSnapshot); - return TRUE; - next: - LastError = GetLastError(); - CloseHandle(DuplicatedToken); - } - RevertToSelf(); - CloseHandle(ProcessSnapshot); -cleanup: - SetLastError(LastError); - return FALSE; -} - -_Return_type_success_(return != FALSE) BOOL ImpersonateService(_In_z_ WCHAR *ServiceName, _In_ HANDLE *OriginalToken) -{ - HANDLE ThreadToken, ServiceProcess, ServiceToken, DuplicatedToken; - SC_HANDLE Scm, ServiceHandle; - DWORD LastError = ERROR_SUCCESS; - TOKEN_PRIVILEGES Privileges = { .PrivilegeCount = 1, .Privileges = { { .Attributes = SE_PRIVILEGE_ENABLED } } }; - SERVICE_STATUS_PROCESS ServiceStatus; - DWORD RequiredBytes; - BOOL Ret = FALSE; - - *OriginalToken = NULL; - if (!OpenThreadToken(GetCurrentThread(), TOKEN_IMPERSONATE, FALSE, OriginalToken) && - GetLastError() != ERROR_NO_TOKEN) - return FALSE; - - if (!ElevateToSystem()) - goto cleanup; - - if (!LookupPrivilegeValueW(NULL, SE_DEBUG_NAME, &Privileges.Privileges[0].Luid)) - { - LastError = LOG_LAST_ERROR(L"Failed to lookup privilege value"); - goto cleanup; - } - if (!OpenThreadToken(GetCurrentThread(), TOKEN_ADJUST_PRIVILEGES, FALSE, &ThreadToken)) - { - LastError = LOG_LAST_ERROR(L"Failed to open thread token"); - goto cleanup; - } - if (!AdjustTokenPrivileges(ThreadToken, FALSE, &Privileges, 0, NULL, NULL)) - { - LastError = LOG_LAST_ERROR(L"Failed to enable SE_DEBUG_NAME"); - goto cleanupThreadToken; - } - - Scm = OpenSCManagerW(NULL, NULL, SC_MANAGER_CONNECT); - if (!Scm) - { - LastError = LOG_LAST_ERROR(L"Failed to open SCM"); - goto cleanupThreadToken; - } - ServiceHandle = OpenServiceW(Scm, ServiceName, SERVICE_START | SERVICE_QUERY_STATUS); - if (!ServiceHandle) - { - LastError = LOG_LAST_ERROR(L"Failed to open service %s", ServiceName); - goto cleanupScm; - } - if (!StartServiceW(ServiceHandle, 0, NULL) && GetLastError() != ERROR_SERVICE_ALREADY_RUNNING) - { - LastError = LOG_LAST_ERROR(L"Failed to start service %s", ServiceName); - goto cleanupService; - } - for (int i = 0; i < 1000; ++i) - { - if (!QueryServiceStatusEx( - ServiceHandle, SC_STATUS_PROCESS_INFO, (BYTE *)&ServiceStatus, sizeof(ServiceStatus), &RequiredBytes)) - { - LastError = LOG_LAST_ERROR(L"Failed to query service %s", ServiceName); - goto cleanupService; - } - if (ServiceStatus.dwProcessId) - break; - - if (i != 999) - Sleep(4); - } - ServiceProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, ServiceStatus.dwProcessId); - if (!ServiceProcess) - { - LastError = LOG_LAST_ERROR(L"Failed to open service %s process %u", ServiceName, ServiceStatus.dwProcessId); - goto cleanupService; - } - if (!OpenProcessToken(ServiceProcess, TOKEN_IMPERSONATE | TOKEN_DUPLICATE, &ServiceToken)) - { - LastError = - LOG_LAST_ERROR(L"Failed to open token of service %s process %u", ServiceName, ServiceStatus.dwProcessId); - goto cleanupServiceProcess; - } - if (!DuplicateToken(ServiceToken, SecurityImpersonation, &DuplicatedToken)) - { - LastError = LOG_LAST_ERROR( - L"Failed to duplicate token of service %s process %u", ServiceName, ServiceStatus.dwProcessId); - goto cleanupServiceToken; - } - if (!SetThreadToken(NULL, DuplicatedToken)) - { - LastError = LOG_LAST_ERROR( - L"Failed to set thread token to service %s process %u token", ServiceName, ServiceStatus.dwProcessId); - goto cleanupDuplicatedToken; - } - Ret = TRUE; - -cleanupDuplicatedToken: - CloseHandle(DuplicatedToken); -cleanupServiceToken: - CloseHandle(ServiceToken); -cleanupServiceProcess: - CloseHandle(ServiceProcess); -cleanupService: - CloseServiceHandle(ServiceHandle); -cleanupScm: - CloseServiceHandle(Scm); -cleanupThreadToken: - CloseHandle(ThreadToken); -cleanup: - if (!Ret) - { - RestoreToken(*OriginalToken); - *OriginalToken = NULL; - } - SetLastError(LastError); - return Ret; -} - -_Return_type_success_(return != FALSE) BOOL RestoreToken(_In_ HANDLE OriginalToken) -{ - RevertToSelf(); - if (!OriginalToken) - return TRUE; - BOOL Ret = SetThreadToken(NULL, OriginalToken); - DWORD LastError = Ret ? ERROR_SUCCESS : LOG_LAST_ERROR(L"Failed to restore original token"); - CloseHandle(OriginalToken); - SetLastError(LastError); - return Ret; -} diff --git a/api/elevate.h b/api/elevate.h deleted file mode 100644 index 04367b4..0000000 --- a/api/elevate.h +++ /dev/null @@ -1,12 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 - * - * Copyright (C) 2018-2021 WireGuard LLC. All Rights Reserved. - */ - -#pragma once - -#include - -_Return_type_success_(return != FALSE) BOOL ImpersonateService(_In_z_ WCHAR *ServiceName, _In_ HANDLE *OriginalToken); - -_Return_type_success_(return != FALSE) BOOL RestoreToken(_In_ HANDLE OriginalToken); diff --git a/api/session.c b/api/session.c index d266d5d..7c408d5 100644 --- a/api/session.c +++ b/api/session.c @@ -4,7 +4,6 @@ */ #include "adapter.h" -#include "elevate.h" #include "entry.h" #include "logger.h" #include "wintun.h" diff --git a/driver/driver.vcxproj b/driver/driver.vcxproj index 4457db2..3705bff 100644 --- a/driver/driver.vcxproj +++ b/driver/driver.vcxproj @@ -1,131 +1,155 @@ - - - - - Debug - ARM - - - Debug - ARM64 - - - Debug - Win32 - - - Debug - x64 - - - Release - ARM - - - Release - ARM64 - - - Release - Win32 - - - Release - x64 - - - - {F7679B65-2FEC-469A-8BAC-B07BF4439422} - wintun - $(LatestTargetPlatformVersion) - wintun - - - - WindowsKernelModeDriver10.0 - Driver - WDM - false - true - - - false - - - true - - - Windows7 - - - Windows8 - - - Windows7 - - - Windows10 - - - - - - - - - - - <_ProjectFileVersion>15.0.28127.55 - ..\$(Configuration)\$(WintunPlatform)\$(ProjectName)-intermediate\ - ..\$(ConfigurationName)\$(WintunPlatform)\ - true - - - $(WDKContentRoot)CodeAnalysis\DriverMustFixRules.ruleset - - - AllRules.ruleset - - - - NDIS_MINIPORT_DRIVER=1;NDIS620_MINIPORT=1;NDIS683_MINIPORT=1;NDIS_WDM=1;%(PreprocessorDefinitions) - /volatile:iso %(AdditionalOptions) - true - - - NDIS_MINIPORT_DRIVER=1;NDIS620_MINIPORT=1;NDIS683_MINIPORT=1;NDIS_WDM=1;%(PreprocessorDefinitions) - - - ndis.lib;wdmsec.lib;%(AdditionalDependencies) - - - sha256 - - - - - $(WintunVersion) - - - - - * - - - - - - - - - - - - - - - - - - - + + + + + Debug + ARM + + + Debug + ARM64 + + + Debug + Win32 + + + Debug + x64 + + + Release + ARM + + + Release + ARM64 + + + Release + Win32 + + + Release + x64 + + + + {F7679B65-2FEC-469A-8BAC-B07BF4439422} + wintun + $(LatestTargetPlatformVersion) + wintun + + + + WindowsKernelModeDriver10.0 + Driver + WDM + false + true + + + false + + + true + + + Windows7 + + + Windows8 + + + Windows7 + + + Windows10 + + + false + + + false + + + false + + + false + + + false + + + false + + + false + + + false + + + + + + + + + + + <_ProjectFileVersion>15.0.28127.55 + ..\$(Configuration)\$(WintunPlatform)\$(ProjectName)-intermediate\ + ..\$(ConfigurationName)\$(WintunPlatform)\ + true + + + $(WDKContentRoot)CodeAnalysis\DriverMustFixRules.ruleset + + + AllRules.ruleset + + + + NDIS_MINIPORT_DRIVER=1;NDIS620_MINIPORT=1;NDIS683_MINIPORT=1;NDIS_WDM=1;%(PreprocessorDefinitions) + /volatile:iso %(AdditionalOptions) + true + + + NDIS_MINIPORT_DRIVER=1;NDIS620_MINIPORT=1;NDIS683_MINIPORT=1;NDIS_WDM=1;%(PreprocessorDefinitions) + + + ndis.lib;wdmsec.lib;%(AdditionalDependencies) + + + sha256 + + + + + $(WintunVersion) + + + + + * + + + + + + + + + + + + + + + + + + + \ No newline at end of file