Changeset 107767 in vbox
- Timestamp:
- Jan 15, 2025 11:55:29 AM (3 months ago)
- svn:sync-xref-src-repo-rev:
- 166902
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/GuestHost/installation/VBoxWinDrvInst.cpp
r107765 r107767 34 34 #include <newdev.h> /* For INSTALLFLAG_XXX. */ 35 35 #include <cfgmgr32.h> /* For MAX_DEVICE_ID_LEN. */ 36 #ifdef RT_ARCH_X86 37 # include <wintrust.h> 38 # include <softpub.h> 39 #endif 36 40 37 41 #include <iprt/assert.h> … … 44 48 #include <iprt/once.h> 45 49 #include <iprt/path.h> 50 #include <iprt/stream.h> 46 51 #include <iprt/string.h> 47 52 #include <iprt/system.h> … … 931 936 } 932 937 938 #ifdef RT_ARCH_X86 939 /** @todo Make use of the regular logging facilities of VBoxWinDrvInst. */ 940 DECLINLINE(int) vboxWinDrvInterceptedWinVerifyTrustError(const char *pszFormat, ...) 941 { 942 va_list args; 943 va_start(args, pszFormat); 944 char *psz = NULL; 945 RTStrAPrintfV(&psz, pszFormat, args); 946 AssertPtrReturn(psz, -1); 947 948 RTStrmPrintf(g_pStdErr, "Error: %s\n", psz); 949 950 RTStrFree(psz); 951 va_end(args); 952 953 return -1; 954 } 955 956 /** @todo Make use of the regular logging facilities of VBoxWinDrvInst. */ 957 DECLINLINE(void) vboxWinDrvInterceptedWinVerifyTrustPrint(const char *pszFormat, ...) 958 { 959 va_list args; 960 va_start(args, pszFormat); 961 char *psz = NULL; 962 RTStrAPrintfV(&psz, pszFormat, args); 963 AssertPtrReturnVoid(psz); 964 965 RTStrmPrintf(g_pStdOut, "%s\n", psz); 966 967 RTStrFree(psz); 968 va_end(args); 969 } 970 971 /** 972 * Interceptor WinVerifyTrust function for SetupApi.dll on Windows 2000, XP, 973 * W2K3 and XP64. 974 * 975 * This crudely modifies the driver verification request from a WHQL/logo driver 976 * check to a simple Authenticode check. 977 */ 978 static LONG WINAPI vboxWinDrvInterceptedWinVerifyTrust(HWND hwnd, GUID *pActionId, void *pvData) 979 { 980 /* 981 * Resolve the real WinVerifyTrust function. 982 */ 983 static decltype(WinVerifyTrust) * volatile s_pfnRealWinVerifyTrust = NULL; 984 decltype(WinVerifyTrust) *pfnRealWinVerifyTrust = s_pfnRealWinVerifyTrust; 985 if (!pfnRealWinVerifyTrust) 986 { 987 HMODULE hmod = GetModuleHandleW(L"WINTRUST.DLL"); 988 if (!hmod) 989 hmod = LoadLibraryW(L"WINTRUST.DLL"); 990 if (!hmod) 991 { 992 vboxWinDrvInterceptedWinVerifyTrustError("InterceptedWinVerifyTrust: Failed to load wintrust.dll"); 993 return TRUST_E_SYSTEM_ERROR; 994 } 995 pfnRealWinVerifyTrust = (decltype(WinVerifyTrust) *)GetProcAddress(hmod, "WinVerifyTrust"); 996 if (!pfnRealWinVerifyTrust) 997 { 998 vboxWinDrvInterceptedWinVerifyTrustError("InterceptedWinVerifyTrust: Failed to locate WinVerifyTrust in wintrust.dll"); 999 return TRUST_E_SYSTEM_ERROR; 1000 } 1001 s_pfnRealWinVerifyTrust = pfnRealWinVerifyTrust; 1002 } 1003 1004 /* 1005 * Modify the ID if appropriate. 1006 */ 1007 static const GUID s_GuidDriverActionVerify = DRIVER_ACTION_VERIFY; 1008 static const GUID s_GuidActionGenericChainVerify = WINTRUST_ACTION_GENERIC_CHAIN_VERIFY; 1009 static const GUID s_GuidActionGenericVerify2 = WINTRUST_ACTION_GENERIC_VERIFY_V2; 1010 if (pActionId) 1011 { 1012 if (memcmp(pActionId, &s_GuidDriverActionVerify, sizeof(*pActionId)) == 0) 1013 { 1014 /** @todo don't apply to obvious NT components... */ 1015 vboxWinDrvInterceptedWinVerifyTrustPrint("DRIVER_ACTION_VERIFY: Changing it to WINTRUST_ACTION_GENERIC_VERIFY_V2"); 1016 pActionId = (GUID *)&s_GuidActionGenericVerify2; 1017 } 1018 else if (memcmp(pActionId, &s_GuidActionGenericChainVerify, sizeof(*pActionId)) == 0) 1019 vboxWinDrvInterceptedWinVerifyTrustPrint("WINTRUST_ACTION_GENERIC_CHAIN_VERIFY"); 1020 else if (memcmp(pActionId, &s_GuidActionGenericVerify2, sizeof(*pActionId)) == 0) 1021 vboxWinDrvInterceptedWinVerifyTrustPrint("WINTRUST_ACTION_GENERIC_VERIFY_V2"); 1022 else 1023 vboxWinDrvInterceptedWinVerifyTrustPrint("WINTRUST_ACTION_UNKNOWN"); 1024 } 1025 1026 /* 1027 * Log the data. 1028 */ 1029 if (pvData) 1030 { 1031 WINTRUST_DATA *pData = (WINTRUST_DATA *)pvData; 1032 vboxWinDrvInterceptedWinVerifyTrustPrint(" cbStruct = %ld", pData->cbStruct); 1033 # ifdef DEBUG 1034 vboxWinDrvInterceptedWinVerifyTrustPrint(" dwUIChoice = %ld", pData->dwUIChoice); 1035 vboxWinDrvInterceptedWinVerifyTrustPrint(" fdwRevocationChecks = %ld", pData->fdwRevocationChecks); 1036 vboxWinDrvInterceptedWinVerifyTrustPrint(" dwStateAction = %ld", pData->dwStateAction); 1037 vboxWinDrvInterceptedWinVerifyTrustPrint(" hWVTStateData = %p", (uintptr_t)pData->hWVTStateData); 1038 # endif 1039 if (pData->cbStruct >= 7*sizeof(uint32_t)) 1040 { 1041 switch (pData->dwUnionChoice) 1042 { 1043 case WTD_CHOICE_FILE: 1044 vboxWinDrvInterceptedWinVerifyTrustPrint(" pFile = %p", (uintptr_t)pData->pFile); 1045 if (RT_VALID_PTR(pData->pFile)) 1046 { 1047 vboxWinDrvInterceptedWinVerifyTrustPrint(" pFile->cbStruct = %ld", pData->pFile->cbStruct); 1048 # ifndef DEBUG 1049 if (pData->pFile->hFile) 1050 # endif 1051 vboxWinDrvInterceptedWinVerifyTrustPrint(" pFile->hFile = %p", (uintptr_t)pData->pFile->hFile); 1052 if (RT_VALID_PTR(pData->pFile->pcwszFilePath)) 1053 vboxWinDrvInterceptedWinVerifyTrustPrint(" pFile->pcwszFilePath = %ls", pData->pFile->pcwszFilePath); 1054 # ifdef DEBUG 1055 else 1056 vboxWinDrvInterceptedWinVerifyTrustPrint(" pFile->pcwszFilePath = %ls", (uintptr_t)pData->pFile->pcwszFilePath); 1057 vboxWinDrvInterceptedWinVerifyTrustPrint(" pFile->pgKnownSubject = %p", (uintptr_t)pData->pFile->pgKnownSubject); 1058 # endif 1059 } 1060 break; 1061 1062 case WTD_CHOICE_CATALOG: 1063 vboxWinDrvInterceptedWinVerifyTrustPrint(" pCatalog = %p", (uintptr_t)pData->pCatalog); 1064 if (RT_VALID_PTR(pData->pCatalog)) 1065 { 1066 vboxWinDrvInterceptedWinVerifyTrustPrint(" pCat->cbStruct = %ld", pData->pCatalog->cbStruct); 1067 # ifdef DEBUG 1068 vboxWinDrvInterceptedWinVerifyTrustPrint(" pCat->dwCatalogVersion = %ld", pData->pCatalog->dwCatalogVersion); 1069 # endif 1070 if (RT_VALID_PTR(pData->pCatalog->pcwszCatalogFilePath)) 1071 vboxWinDrvInterceptedWinVerifyTrustPrint("pCat->pcwszCatalogFilePath = %ls", pData->pCatalog->pcwszCatalogFilePath); 1072 # ifdef DEBUG 1073 else 1074 vboxWinDrvInterceptedWinVerifyTrustPrint("pCat->pcwszCatalogFilePath = %ls", (uintptr_t)pData->pCatalog->pcwszCatalogFilePath); 1075 # endif 1076 if (RT_VALID_PTR(pData->pCatalog->pcwszMemberTag)) 1077 vboxWinDrvInterceptedWinVerifyTrustPrint(" pCat->pcwszMemberTag = %ls", pData->pCatalog->pcwszMemberTag); 1078 # ifdef DEBUG 1079 else 1080 vboxWinDrvInterceptedWinVerifyTrustPrint(" pCat->pcwszMemberTag = %ls", (uintptr_t)pData->pCatalog->pcwszMemberTag); 1081 # endif 1082 if (RT_VALID_PTR(pData->pCatalog->pcwszMemberFilePath)) 1083 vboxWinDrvInterceptedWinVerifyTrustPrint(" pCat->pcwszMemberFilePath = %ls", pData->pCatalog->pcwszMemberFilePath); 1084 # ifdef DEBUG 1085 else 1086 vboxWinDrvInterceptedWinVerifyTrustPrint(" pCat->pcwszMemberFilePath = %ls", (uintptr_t)pData->pCatalog->pcwszMemberFilePath); 1087 # else 1088 if (pData->pCatalog->hMemberFile) 1089 # endif 1090 vboxWinDrvInterceptedWinVerifyTrustPrint(" pCat->hMemberFile = %p", (uintptr_t)pData->pCatalog->hMemberFile); 1091 # ifdef DEBUG 1092 vboxWinDrvInterceptedWinVerifyTrustPrint("pCat->pbCalculatedFileHash = %p", (uintptr_t)pData->pCatalog->pbCalculatedFileHash); 1093 vboxWinDrvInterceptedWinVerifyTrustPrint("pCat->cbCalculatedFileHash = %ld", pData->pCatalog->cbCalculatedFileHash); 1094 vboxWinDrvInterceptedWinVerifyTrustPrint(" pCat->pcCatalogContext = %p", (uintptr_t)pData->pCatalog->pcCatalogContext); 1095 # endif 1096 } 1097 break; 1098 1099 case WTD_CHOICE_BLOB: 1100 vboxWinDrvInterceptedWinVerifyTrustPrint(" pBlob = %p\n", (uintptr_t)pData->pBlob); 1101 break; 1102 1103 case WTD_CHOICE_SIGNER: 1104 vboxWinDrvInterceptedWinVerifyTrustPrint(" pSgnr = %p", (uintptr_t)pData->pSgnr); 1105 break; 1106 1107 case WTD_CHOICE_CERT: 1108 vboxWinDrvInterceptedWinVerifyTrustPrint(" pCert = %p", (uintptr_t)pData->pCert); 1109 break; 1110 1111 default: 1112 vboxWinDrvInterceptedWinVerifyTrustPrint(" dwUnionChoice = %ld", pData->dwUnionChoice); 1113 break; 1114 } 1115 } 1116 } 1117 1118 /* 1119 * Make the call. 1120 */ 1121 vboxWinDrvInterceptedWinVerifyTrustPrint("Calling WinVerifyTrust ..."); 1122 LONG iRet = pfnRealWinVerifyTrust(hwnd, pActionId, pvData); 1123 vboxWinDrvInterceptedWinVerifyTrustPrint("WinVerifyTrust returns %ld", iRet); 1124 1125 return iRet; 1126 } 1127 1128 /** 1129 * Installs an WinVerifyTrust interceptor in setupapi.dll on Windows 2000, XP, 1130 * W2K3 and XP64. 1131 * 1132 * This is a very crude hack to lower the WHQL check to just require a valid 1133 * Authenticode signature by intercepting the verification call. 1134 * 1135 * @return Ignored, just a convenience for saving space in error paths. 1136 */ 1137 static int vboxWinDrvInstallWinVerifyTrustInterceptorInSetupApi(void) 1138 { 1139 /* Check the version: */ 1140 OSVERSIONINFOW VerInfo = { sizeof(VerInfo) }; 1141 GetVersionExW(&VerInfo); 1142 if (VerInfo.dwMajorVersion != 5) 1143 return 1; 1144 1145 /* The the target module: */ 1146 HMODULE hModSetupApi = GetModuleHandleW(L"SETUPAPI.DLL"); 1147 if (!hModSetupApi) 1148 { 1149 DWORD const dwLastErr = GetLastError(); 1150 return vboxWinDrvInterceptedWinVerifyTrustError("Failed to locate SETUPAPI.DLL in the process: %ld / %#x", 1151 dwLastErr, dwLastErr); 1152 } 1153 1154 /* 1155 * Find the delayed import table (at least that's how it's done in the RTM). 1156 */ 1157 IMAGE_DOS_HEADER const *pDosHdr = (IMAGE_DOS_HEADER const *)hModSetupApi; 1158 IMAGE_NT_HEADERS const *pNtHdrs = (IMAGE_NT_HEADERS const *)( (uintptr_t)hModSetupApi 1159 + ( pDosHdr->e_magic == IMAGE_DOS_SIGNATURE 1160 ? pDosHdr->e_lfanew : 0)); 1161 if (pNtHdrs->Signature != IMAGE_NT_SIGNATURE) 1162 return vboxWinDrvInterceptedWinVerifyTrustError("Failed to parse SETUPAPI.DLL for WinVerifyTrust interception:"); 1163 if (pNtHdrs->OptionalHeader.Magic != IMAGE_NT_OPTIONAL_HDR_MAGIC) 1164 return vboxWinDrvInterceptedWinVerifyTrustError("Failed to parse SETUPAPI.DLL for WinVerifyTrust interception:"); 1165 if (pNtHdrs->OptionalHeader.NumberOfRvaAndSizes <= IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT) 1166 return vboxWinDrvInterceptedWinVerifyTrustError("Failed to parse SETUPAPI.DLL for WinVerifyTrust interception:"); 1167 1168 uint32_t const cbDir = pNtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT].Size; 1169 if (cbDir < sizeof(IMAGE_DELAYLOAD_DESCRIPTOR)) 1170 return vboxWinDrvInterceptedWinVerifyTrustError("Failed to parse SETUPAPI.DLL for WinVerifyTrust interception:"); 1171 uint32_t const cbImages = pNtHdrs->OptionalHeader.SizeOfImage; 1172 if (cbDir >= cbImages) 1173 return vboxWinDrvInterceptedWinVerifyTrustError("Failed to parse SETUPAPI.DLL for WinVerifyTrust interception:"); 1174 uint32_t const offDir = pNtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT].VirtualAddress; 1175 if (offDir > cbImages - cbDir) 1176 return vboxWinDrvInterceptedWinVerifyTrustError("Failed to parse SETUPAPI.DLL for WinVerifyTrust interception:"); 1177 1178 /* 1179 * Scan the entries looking for wintrust.dll. 1180 */ 1181 IMAGE_DELAYLOAD_DESCRIPTOR const * const paEntries = (IMAGE_DELAYLOAD_DESCRIPTOR const *)((uintptr_t)hModSetupApi + offDir); 1182 uint32_t const cEntries = cbDir / sizeof(paEntries[0]); 1183 for (uint32_t iImp = 0; iImp < cEntries; iImp++) 1184 { 1185 const char * const pchRva2Ptr = paEntries[iImp].Attributes.RvaBased ? (const char *)hModSetupApi : (const char *)0; 1186 const char * const pszDllName = &pchRva2Ptr[paEntries[iImp].DllNameRVA]; 1187 if (RTStrICmpAscii(pszDllName, "WINTRUST.DLL") == 0) 1188 { 1189 /* 1190 * Scan the symbol names. 1191 */ 1192 //uint32_t const cbHdrs = pNtHdrs->OptionalHeader.SizeOfHeaders; 1193 uint32_t * const pauNameRvas = (uint32_t *)&pchRva2Ptr[paEntries[iImp].ImportNameTableRVA]; 1194 uintptr_t * const paIat = (uintptr_t *)&pchRva2Ptr[paEntries[iImp].ImportAddressTableRVA]; 1195 for (uint32_t iSym = 0; pauNameRvas[iSym] != NULL; iSym++) 1196 { 1197 IMAGE_IMPORT_BY_NAME const * const pName = (IMAGE_IMPORT_BY_NAME const *)&pchRva2Ptr[pauNameRvas[iSym]]; 1198 if (RTStrCmp(pName->Name, "WinVerifyTrust") == 0) 1199 { 1200 vboxWinDrvInterceptedWinVerifyTrustPrint("Intercepting WinVerifyTrust for SETUPAPI.DLL (old: %p)", paIat[iSym]); 1201 paIat[iSym] = (uintptr_t)vboxWinDrvInterceptedWinVerifyTrust; 1202 return 0; 1203 } 1204 } 1205 return vboxWinDrvInterceptedWinVerifyTrustError("Failed to parse SETUPAPI.DLL for WinVerifyTrust interception:"); 1206 } 1207 } 1208 return vboxWinDrvInterceptedWinVerifyTrustError("Failed to parse SETUPAPI.DLL for WinVerifyTrust interception:"); 1209 } 1210 #endif /* RT_ARCH_X86 */ 1211 933 1212 /** 934 1213 * Performs the actual driver installation. … … 951 1230 BOOL fReboot = FALSE; 952 1231 1232 #ifdef RT_ARCH_X86 1233 vboxWinDrvInstallWinVerifyTrustInterceptorInSetupApi(); 1234 #endif 953 1235 /* 954 1236 * Pre-install driver.
Note:
See TracChangeset
for help on using the changeset viewer.