VirtualBox

Changeset 107767 in vbox


Ignore:
Timestamp:
Jan 15, 2025 11:55:29 AM (3 months ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
166902
Message:

Windows driver installation/VBoxDrvInst: Added crude hack from r153608 to suppress the WHQL dialog on windows 2000 and XP. ​bugref:10261 ​bugref:8691

Needs some more work later.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/GuestHost/installation/VBoxWinDrvInst.cpp

    r107765 r107767  
    3434#include <newdev.h> /* For INSTALLFLAG_XXX. */
    3535#include <cfgmgr32.h> /* For MAX_DEVICE_ID_LEN. */
     36#ifdef RT_ARCH_X86
     37# include <wintrust.h>
     38# include <softpub.h>
     39#endif
    3640
    3741#include <iprt/assert.h>
     
    4448#include <iprt/once.h>
    4549#include <iprt/path.h>
     50#include <iprt/stream.h>
    4651#include <iprt/string.h>
    4752#include <iprt/system.h>
     
    931936}
    932937
     938#ifdef RT_ARCH_X86
     939/** @todo Make use of the regular logging facilities of VBoxWinDrvInst. */
     940DECLINLINE(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. */
     957DECLINLINE(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 */
     978static 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 */
     1137static 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
    9331212/**
    9341213 * Performs the actual driver installation.
     
    9511230            BOOL fReboot = FALSE;
    9521231
     1232#ifdef RT_ARCH_X86
     1233            vboxWinDrvInstallWinVerifyTrustInterceptorInSetupApi();
     1234#endif
    9531235            /*
    9541236             * Pre-install driver.
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette