VirtualBox

Changeset 52366 in vbox for trunk/src/VBox/HostDrivers


Ignore:
Timestamp:
Aug 13, 2014 10:35:55 AM (10 years ago)
Author:
vboxsync
Message:

SUP: Cache images for process verficiation.

Location:
trunk/src/VBox/HostDrivers/Support
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/HostDrivers/Support/SUPLibInternal.h

    r52356 r52366  
    439439DECLHIDDEN(void)    supR3HardenedWinVerifyProcess(void);
    440440DECLHIDDEN(void)    supR3HardenedWinResolveVerifyTrustApiAndHookThreadCreation(const char *pszProgName);
     441DECLHIDDEN(void)    supR3HardenedWinFlushLoaderCache();
    441442DECLHIDDEN(bool)    supR3HardenedWinIsReSpawnNeeded(int iWhich, int cArgs, char **papszArgs);
    442443DECLHIDDEN(int)     supR3HardenedWinReSpawn(int iWhich);
  • trunk/src/VBox/HostDrivers/Support/SUPR3HardenedMain.cpp

    r52356 r52366  
    249249# else
    250250        DWORD cbWritten;
    251         WriteFile(hStdOut, pch, cch, &cbWritten, NULL);
     251        WriteFile(hStdOut, pch, (DWORD)cch, &cbWritten, NULL);
    252252# endif
    253253    }
     
    17261726        }
    17271727        SUP_DPRINTF(("SUPR3HardenedMain: Final process, opening VBoxDrv...\n"));
     1728        supR3HardenedWinFlushLoaderCache();
    17281729#endif /* RT_OS_WINDOWS */
    17291730
     
    17381739     * Windows: Enable the use of windows APIs to verify images at load time.
    17391740     */
     1741    supR3HardenedWinFlushLoaderCache();
    17401742    supR3HardenedWinResolveVerifyTrustApiAndHookThreadCreation(g_pszSupLibHardenedProgName);
    17411743    g_enmSupR3HardenedMainState = SUPR3HARDENEDMAINSTATE_VERIFY_TRUST_READY;
  • trunk/src/VBox/HostDrivers/Support/win/SUPHardenedVerify-win.h

    r52365 r52366  
    105105/** @} */
    106106
     107/**
     108 * Loader cache entry.
     109 *
     110 * This is for avoiding loading and signature checking a file multiple times,
     111 * due to multiple passes thru the process validation code (and syscall import
     112 * code of NTDLL).
     113 */
     114typedef struct SUPHNTLDRCACHEENTRY
     115{
     116    /** The file name (from g_apszSupNtVpAllowedDlls or
     117     *  g_apszSupNtVpAllowedVmExes). */
     118    const char         *pszName;
     119    /** Load module associated with the image during content verfication. */
     120    RTLDRMOD            hLdrMod;
     121    /** The file reader. */
     122    PSUPHNTVIRDR        pNtViRdr;
     123    /** The module file handle, if we've opened it.
     124     * (pNtviRdr does not close the file handle on destruction.)  */
     125    HANDLE              hFile;
     126    /** Bits buffer. */
     127    uint8_t            *pbBits;
     128    /** Set if verified. */
     129    bool                fVerified;
     130} SUPHNTLDRCACHEENTRY;
     131/** Pointer to a loader cache entry. */
     132typedef SUPHNTLDRCACHEENTRY *PSUPHNTLDRCACHEENTRY;
     133DECLHIDDEN(int)  supHardNtLdrCacheOpen(const char *pszName, PRTERRINFO pErrInfo, PSUPHNTLDRCACHEENTRY *ppEntry);
     134DECLHIDDEN(int)  supHardNtLdrCacheEntryVerify(PSUPHNTLDRCACHEENTRY pEntry, PCRTUTF16 pwszName, PRTERRINFO pErrInfo);
     135DECLHIDDEN(int)  supHardNtLdrCacheEntryAllocBits(PSUPHNTLDRCACHEENTRY pEntry, uint8_t **ppbBits, PRTERRINFO pErrInfo);
     136
     137
    107138/** Which directory under the system root to get. */
    108139typedef enum SUPHARDNTSYSROOTDIR
  • trunk/src/VBox/HostDrivers/Support/win/SUPHardenedVerifyImage-win.cpp

    r52365 r52366  
    423423    ULONG cbActual;
    424424    NTSTATUS rcNt = NtQuerySecurityObject(hFile, OWNER_SECURITY_INFORMATION, &uBuf.Abs, sizeof(uBuf), &cbActual);
    425 SUP_DPRINTF(("NtQuerySecurityObject: rcNt=%#x on '%ls'\n", rcNt, pwszName));
    426425    if (!NT_SUCCESS(rcNt))
    427426    {
  • trunk/src/VBox/HostDrivers/Support/win/SUPHardenedVerifyProcess-win.cpp

    r52365 r52366  
    112112    bool            f32bitResourceDll;
    113113
    114     /** Load module associated with the image during content verfication. */
    115     RTLDRMOD        hLdrMod;
    116     /** The file reader. */
    117     PSUPHNTVIRDR    pNtViRdr;
    118     /** The module file handle, if we've opened it.
    119      * (pNtviRdr does not close the file handle on destruction.)  */
    120     HANDLE          hFile;
    121     /** Image bits for lazy cleanup. */
    122     uint8_t        *pbBits;
     114    /** Pointer to the loader cache entry for the image. */
     115    PSUPHNTLDRCACHEENTRY    pCacheEntry;
     116#ifdef IN_RING0
     117    /** In ring-0 we don't currently cache images, so put it here. */
     118    SUPHNTLDRCACHEENTRY     CacheEntry;
     119#endif
    123120} SUPHNTVPIMAGE;
    124121/** Pointer to image info from the virtual address space scan. */
     
    231228#endif
    232229
     230#ifdef IN_RING3
     231/** The number of valid entries in the loader cache.. */
     232static uint32_t                 g_cSupNtVpLdrCacheEntries = 0;
     233/** The loader cache entries. */
     234static SUPHNTLDRCACHEENTRY      g_aSupNtVpLdrCacheEntries[RT_ELEMENTS(g_apszSupNtVpAllowedDlls) + 1 + 3];
     235#endif
     236
    233237
    234238/**
     
    305309static int supHardNtVpReadImage(PSUPHNTVPIMAGE pImage, uint64_t off, void *pvBuf, size_t cbRead)
    306310{
    307     return pImage->pNtViRdr->Core.pfnRead(&pImage->pNtViRdr->Core, pvBuf, cbRead, off);
     311    return pImage->pCacheEntry->pNtViRdr->Core.pfnRead(&pImage->pCacheEntry->pNtViRdr->Core, pvBuf, cbRead, off);
    308312}
    309313
     
    595599    if (pImage)
    596600    {
    597         rc = RTLdrGetSymbolEx(pImage->hLdrMod, NULL, pImage->uImageBase, uSymbol, pszSymbol, pValue);
     601        rc = RTLdrGetSymbolEx(pImage->pCacheEntry->hLdrMod, pImage->pCacheEntry->pbBits,
     602                              pImage->uImageBase, uSymbol, pszSymbol, pValue);
    598603        if (RT_SUCCESS(rc))
    599604            return rc;
     
    610615            if (pImage)
    611616            {
    612                 rc = RTLdrGetSymbolEx(pImage->hLdrMod, NULL, pImage->uImageBase, uSymbol, pszSymbol, pValue);
     617                rc = RTLdrGetSymbolEx(pImage->pCacheEntry->hLdrMod, pImage->pCacheEntry->pbBits,
     618                                      pImage->uImageBase, uSymbol, pszSymbol, pValue);
    613619                if (RT_SUCCESS(rc))
    614620                    return rc;
     
    628634        size_t           cbInfo = RT_MIN((uint32_t)*pValue, sizeof(RTLDRIMPORTINFO) + 32);
    629635        PRTLDRIMPORTINFO pInfo  = (PRTLDRIMPORTINFO)alloca(cbInfo);
    630         rc = RTLdrQueryForwarderInfo(pImage->hLdrMod, NULL, uSymbol, pszSymbol, pInfo, cbInfo);
     636        rc = RTLdrQueryForwarderInfo(pImage->pCacheEntry->hLdrMod, pImage->pCacheEntry->pbBits,
     637                                     uSymbol, pszSymbol, pInfo, cbInfo);
    631638        if (RT_SUCCESS(rc))
    632639        {
     
    635642            if (pImage)
    636643            {
    637                 rc = RTLdrGetSymbolEx(pImage->hLdrMod, NULL, pImage->uImageBase, pInfo->iOrdinal, pInfo->pszSymbol, pValue);
     644                rc = RTLdrGetSymbolEx(pImage->pCacheEntry->hLdrMod, pImage->pCacheEntry->pbBits,
     645                                      pImage->uImageBase, pInfo->iOrdinal, pInfo->pszSymbol, pValue);
    638646                if (RT_SUCCESS(rc))
    639647                    return rc;
     
    741749                                   "%s: SizeOfImage (%#x) isn't close enough to the mapping size (%#x)",
    742750                                   pImage->pszName, cbImage, pImage->cbImage);
    743     if (cbImage != RTLdrSize(pImage->hLdrMod))
     751    if (cbImage != RTLdrSize(pImage->pCacheEntry->hLdrMod))
    744752        return supHardNtVpSetInfo2(pThis, VERR_SUP_VP_BAD_IMAGE_SIZE,
    745753                                   "%s: SizeOfImage (%#x) differs from what RTLdrSize returns (%#zx)",
    746                                    pImage->pszName, cbImage, RTLdrSize(pImage->hLdrMod));
     754                                   pImage->pszName, cbImage, RTLdrSize(pImage->pCacheEntry->hLdrMod));
    747755
    748756    uint32_t const cbSectAlign = fIs32Bit ? pNtHdrs32->OptionalHeader.SectionAlignment : pNtHdrs->OptionalHeader.SectionAlignment;
     
    791799     * Get relocated bits.
    792800     */
    793     pImage->pbBits = (uint8_t *)suplibHardenedAllocZ(cbImage);
    794     if (RT_UNLIKELY(!pImage->pbBits))
    795         return supHardNtVpSetInfo2(pThis, VERR_SUP_VP_NO_MEMORY,
    796                                    "%s: Error allocating %#x bytes for fixed up image bits.", pImage->pszName, cbImage);
     801    uint8_t *pbBits;
     802    rc = supHardNtLdrCacheEntryAllocBits(pImage->pCacheEntry, &pbBits, pThis->pErrInfo);
     803    if (RT_FAILURE(rc))
     804        return rc;
    797805    if (pThis->enmKind == SUPHARDNTVPKIND_CHILD_PURIFICATION)
    798         rc = RTLdrGetBits(pImage->hLdrMod, pImage->pbBits, pImage->uImageBase, NULL /*pfnGetImport*/, pThis);
     806        rc = RTLdrGetBits(pImage->pCacheEntry->hLdrMod, pbBits, pImage->uImageBase, NULL /*pfnGetImport*/, pThis);
    799807    else
    800         rc = RTLdrGetBits(pImage->hLdrMod, pImage->pbBits, pImage->uImageBase, supHardNtVpGetImport, pThis);
     808        rc = RTLdrGetBits(pImage->pCacheEntry->hLdrMod, pbBits, pImage->uImageBase, supHardNtVpGetImport, pThis);
    801809    if (RT_FAILURE(rc))
    802810        return supHardNtVpSetInfo2(pThis, rc, "%s: RTLdrGetBits failed: %Rrc", pImage->pszName, rc);
     
    806814    {
    807815        if (fIs32Bit)
    808             ((PIMAGE_NT_HEADERS32)&pImage->pbBits[offNtHdrs])->OptionalHeader.ImageBase = (uint32_t)pImage->uImageBase;
     816            ((PIMAGE_NT_HEADERS32)&pbBits[offNtHdrs])->OptionalHeader.ImageBase = (uint32_t)pImage->uImageBase;
    809817        else
    810             ((PIMAGE_NT_HEADERS)&pImage->pbBits[offNtHdrs])->OptionalHeader.ImageBase   = pImage->uImageBase;
     818            ((PIMAGE_NT_HEADERS)&pbBits[offNtHdrs])->OptionalHeader.ImageBase   = pImage->uImageBase;
    811819    }
    812820
     
    822830        {
    823831            /* Ignore our NtCreateSection hack. */
    824             rc = RTLdrGetSymbolEx(pImage->hLdrMod, pImage->pbBits, 0, UINT32_MAX, "NtCreateSection", &uValue);
     832            rc = RTLdrGetSymbolEx(pImage->pCacheEntry->hLdrMod, pbBits, 0, UINT32_MAX, "NtCreateSection", &uValue);
    825833            if (RT_FAILURE(rc))
    826834                return supHardNtVpSetInfo2(pThis, rc, "%s: Failed to find 'NtCreateSection': %Rrc", pImage->pszName, rc);
     
    830838
    831839        /* LdrSystemDllInitBlock is filled in by the kernel. It mainly contains addresses of 32-bit ntdll method for wow64. */
    832         rc = RTLdrGetSymbolEx(pImage->hLdrMod, pImage->pbBits, 0, UINT32_MAX, "LdrSystemDllInitBlock", &uValue);
     840        rc = RTLdrGetSymbolEx(pImage->pCacheEntry->hLdrMod, pbBits, 0, UINT32_MAX, "LdrSystemDllInitBlock", &uValue);
    833841        if (RT_SUCCESS(rc))
    834842        {
    835843            aSkipAreas[cSkipAreas].uRva = (uint32_t)uValue;
    836             aSkipAreas[cSkipAreas++].cb = RT_MAX(pImage->pbBits[(uint32_t)uValue], 0x50);
     844            aSkipAreas[cSkipAreas++].cb = RT_MAX(pbBits[(uint32_t)uValue], 0x50);
    837845        }
    838846    }
     
    844852    if (!pImage->fApiSetSchemaOnlySection1)
    845853    {
    846         rc = supHardNtVpFileMemCompareSection(pThis, pImage, 0 /*uRva*/, cbHdrsFile, pImage->pbBits, -1, NULL, 0, PAGE_READONLY);
     854        rc = supHardNtVpFileMemCompareSection(pThis, pImage, 0 /*uRva*/, cbHdrsFile, pbBits, -1, NULL, 0, PAGE_READONLY);
    847855        if (RT_FAILURE(rc))
    848856            return rc;
     
    912920                rc = VINF_SUCCESS;
    913921                if (uRva < uSectRva && !pImage->fApiSetSchemaOnlySection1) /* Any gap worth checking? */
    914                     rc = supHardNtVpFileMemCompareSection(pThis, pImage, uRva, uSectRva - uRva, pImage->pbBits + uRva,
     922                    rc = supHardNtVpFileMemCompareSection(pThis, pImage, uRva, uSectRva - uRva, pbBits + uRva,
    915923                                                          i - 1, NULL, 0, fPrevProt);
    916924                if (RT_SUCCESS(rc))
    917                     rc = supHardNtVpFileMemCompareSection(pThis, pImage, uSectRva, cbMap, pImage->pbBits + uSectRva,
     925                    rc = supHardNtVpFileMemCompareSection(pThis, pImage, uSectRva, cbMap, pbBits + uSectRva,
    918926                                                          i, aSkipAreas, cSkipAreas, fProt);
    919927                if (RT_SUCCESS(rc))
     
    963971     */
    964972    int rc;
    965     if (pImage->hLdrMod != NIL_RTLDRMOD)
    966     {
    967         rc = supHardenedWinVerifyImageByLdrMod(pImage->hLdrMod, pImage->Name.UniStr.Buffer, pImage->pNtViRdr,
    968                                                NULL /*pfCacheable*/, pThis->pErrInfo);
     973    if (   pImage->pCacheEntry != NULL
     974        && pImage->pCacheEntry->hLdrMod != NIL_RTLDRMOD)
     975    {
     976        rc = supHardNtLdrCacheEntryVerify(pImage->pCacheEntry, pImage->Name.UniStr.Buffer, pThis->pErrInfo);
    969977        if (RT_SUCCESS(rc))
    970         {
    971978            rc = supHardNtVpVerifyImageMemoryCompare(pThis, pImage, hProcess, pThis->pErrInfo);
    972 
    973             if (pImage->pbBits)
    974             {
    975                 suplibHardenedFree(pImage->pbBits);
    976                 pImage->pbBits = NULL;
    977             }
    978         }
    979979    }
    980980    else
    981         rc = supHardNtVpSetInfo2(pThis, VERR_OPEN_FAILED, "hLdrMod is NIL! Impossible!");
     981        rc = supHardNtVpSetInfo2(pThis, VERR_OPEN_FAILED, "pCacheEntry/hLdrMod is NIL! Impossible!");
    982982    return rc;
    983983}
     
    12161216    pImage->uImageBase = (uintptr_t)pMemInfo->AllocationBase;
    12171217    pImage->cbImage    = pMemInfo->RegionSize;
    1218     pImage->hFile      = NULL;
    1219     pImage->hLdrMod    = NIL_RTLDRMOD;
    1220     pImage->pNtViRdr   = NULL;
     1218    pImage->pCacheEntry= NULL;
    12211219    pImage->cRegions   = 1;
    12221220    pImage->aRegions[0].uRva    = 0;
     
    14881486}
    14891487
     1488
     1489/**
     1490 * Verifies the loader image, i.e. check cryptographic signatures if present.
     1491 *
     1492 * @returns VBox status code.
     1493 * @param   pEntry              The loader cache entry.
     1494 * @param   pwszName            The filename to use in error messages.
     1495 * @param   pErRInfo            Where to return extened error information.
     1496 */
     1497DECLHIDDEN(int) supHardNtLdrCacheEntryVerify(PSUPHNTLDRCACHEENTRY pEntry, PCRTUTF16 pwszName, PRTERRINFO pErrInfo)
     1498{
     1499    int rc = VINF_SUCCESS;
     1500    if (!pEntry->fVerified)
     1501    {
     1502        rc = supHardenedWinVerifyImageByLdrMod(pEntry->hLdrMod, pwszName, pEntry->pNtViRdr, NULL /*pfCacheable*/, pErrInfo);
     1503        pEntry->fVerified = RT_SUCCESS(rc);
     1504    }
     1505    return rc;
     1506}
     1507
     1508
     1509/**
     1510 * Allocates a image bits buffer for use with RTLdrGetBits.
     1511 *
     1512 * An assumption here is that there won't ever be concurrent use of the cache.
     1513 * It's currently 104% single threaded, non-reentrant.  Thus, we can't reuse the
     1514 * pbBits allocation.
     1515 *
     1516 * @returns VBox status code
     1517 * @param   pEntry              The loader cache entry.
     1518 * @param   ppbBits             Where to return the pointer to the allocation.
     1519 * @param   pErRInfo            Where to return extened error information.
     1520 */
     1521DECLHIDDEN(int) supHardNtLdrCacheEntryAllocBits(PSUPHNTLDRCACHEENTRY pEntry, uint8_t **ppbBits, PRTERRINFO pErrInfo)
     1522{
     1523    if (!pEntry->pbBits)
     1524    {
     1525        size_t cbBits = RTLdrSize(pEntry->hLdrMod);
     1526        if (cbBits >= _1M*32U)
     1527            return supHardNtVpSetInfo1(pErrInfo, VERR_SUP_VP_IMAGE_TOO_BIG, "Image %s is too large: %zu bytes (%#zx).",
     1528                                       pEntry->pszName, cbBits, cbBits);
     1529
     1530        pEntry->pbBits = (uint8_t *)suplibHardenedAllocZ(cbBits);
     1531        if (!pEntry->pbBits)
     1532            return supHardNtVpSetInfo1(pErrInfo, VERR_SUP_VP_NO_MEMORY, "Failed to allocate %zu bytes for image %s.",
     1533                                       cbBits, pEntry->pszName);
     1534    }
     1535
     1536    /** @todo Try cache RTLdrGetBits calls too. */
     1537
     1538    *ppbBits = pEntry->pbBits;
     1539    return VINF_SUCCESS;
     1540}
     1541
     1542
     1543/**
     1544 * Frees all resources associated with a cache entry and wipes the members
     1545 * clean.
     1546 *
     1547 * @param   pEntry              The entry to delete.
     1548 */
     1549static void supHardNTLdrCacheDeleteEntry(PSUPHNTLDRCACHEENTRY pEntry)
     1550{
     1551    if (pEntry->pbBits)
     1552    {
     1553        suplibHardenedFree(pEntry->pbBits);
     1554        pEntry->pbBits = NULL;
     1555    }
     1556
     1557    if (pEntry->hLdrMod != NIL_RTLDRMOD)
     1558    {
     1559        RTLdrClose(pEntry->hLdrMod);
     1560        pEntry->hLdrMod = NIL_RTLDRMOD;
     1561        pEntry->pNtViRdr = NULL;
     1562    }
     1563    else if (pEntry->pNtViRdr)
     1564    {
     1565        pEntry->pNtViRdr->Core.pfnDestroy(&pEntry->pNtViRdr->Core);
     1566        pEntry->pNtViRdr = NULL;
     1567    }
     1568
     1569    if (pEntry->hFile)
     1570    {
     1571        NtClose(pEntry->hFile);
     1572        pEntry->hFile = NULL;
     1573    }
     1574
     1575    pEntry->pszName   = NULL;
     1576    pEntry->fVerified = false;
     1577}
     1578
     1579#ifdef IN_RING3
     1580
     1581/**
     1582 * Flushes the cache.
     1583 *
     1584 * This is called from one of two points in the hardened main code, first is
     1585 * after respawning and the second is when we open the vboxdrv device for
     1586 * unrestricted access.
     1587 */
     1588DECLHIDDEN(void) supR3HardenedWinFlushLoaderCache(void)
     1589{
     1590    uint32_t i = g_cSupNtVpLdrCacheEntries;
     1591    while (i-- > 0)
     1592        supHardNTLdrCacheDeleteEntry(&g_aSupNtVpLdrCacheEntries[i]);
     1593    g_cSupNtVpLdrCacheEntries = 0;
     1594}
     1595
     1596
     1597/**
     1598 * Searches the cache for a loader image.
     1599 *
     1600 * @returns Pointer to the cache entry if found, NULL if not.
     1601 * @param   pszName             The name (from g_apszSupNtVpAllowedVmExes or
     1602 *                              g_apszSupNtVpAllowedDlls).
     1603 */
     1604static PSUPHNTLDRCACHEENTRY supHardNtLdrCacheLookupEntry(const char *pszName)
     1605{
     1606    /*
     1607     * Since the caller is supplying us a pszName from one of the two tables,
     1608     * we can dispense with string compare and simply compare string pointers.
     1609     */
     1610    uint32_t i = g_cSupNtVpLdrCacheEntries;
     1611    while (i-- > 0)
     1612        if (g_aSupNtVpLdrCacheEntries[i].pszName == pszName)
     1613            return &g_aSupNtVpLdrCacheEntries[i];
     1614    return NULL;
     1615}
     1616
     1617#endif /* IN_RING3 */
     1618
     1619static int supHardNtLdrCacheNewEntry(PSUPHNTLDRCACHEENTRY pEntry, const char *pszName, PUNICODE_STRING pUniStrPath,
     1620                                     bool fDll, bool f32bitResourceDll, PRTERRINFO pErrInfo)
     1621{
     1622    /*
     1623     * Open the image file.
     1624     */
     1625    HANDLE              hFile = RTNT_INVALID_HANDLE_VALUE;
     1626    IO_STATUS_BLOCK     Ios   = RTNT_IO_STATUS_BLOCK_INITIALIZER;
     1627
     1628    OBJECT_ATTRIBUTES   ObjAttr;
     1629    InitializeObjectAttributes(&ObjAttr, pUniStrPath, OBJ_CASE_INSENSITIVE, NULL /*hRootDir*/, NULL /*pSecDesc*/);
     1630#ifdef IN_RING0
     1631    ObjAttr.Attributes |= OBJ_KERNEL_HANDLE;
     1632#endif
     1633
     1634    NTSTATUS rcNt = NtCreateFile(&hFile,
     1635                                 GENERIC_READ,
     1636                                 &ObjAttr,
     1637                                 &Ios,
     1638                                 NULL /* Allocation Size*/,
     1639                                 FILE_ATTRIBUTE_NORMAL,
     1640                                 FILE_SHARE_READ,
     1641                                 FILE_OPEN,
     1642                                 FILE_NON_DIRECTORY_FILE, /** @todo nonalert? */
     1643                                 NULL /*EaBuffer*/,
     1644                                 0 /*EaLength*/);
     1645    if (NT_SUCCESS(rcNt))
     1646        rcNt = Ios.Status;
     1647    if (!NT_SUCCESS(rcNt))
     1648        return supHardNtVpSetInfo1(pErrInfo, VERR_SUP_VP_IMAGE_FILE_OPEN_ERROR,
     1649                                   "Error opening image for scanning: %#x (name %ls)", rcNt, pUniStrPath->Buffer);
     1650
     1651    /*
     1652     * Figure out validation flags we'll be using and create the reader
     1653     * for this image.
     1654     */
     1655    uint32_t fFlags = fDll
     1656                    ? SUPHNTVI_F_TRUSTED_INSTALLER_OWNER | SUPHNTVI_F_ALLOW_CAT_FILE_VERIFICATION
     1657                    : SUPHNTVI_F_REQUIRE_BUILD_CERT;
     1658    if (f32bitResourceDll)
     1659        fFlags |= SUPHNTVI_F_RESOURCE_IMAGE;
     1660
     1661    PSUPHNTVIRDR pNtViRdr;
     1662    int rc = supHardNtViRdrCreate(hFile, pUniStrPath->Buffer, fFlags, &pNtViRdr);
     1663    if (RT_FAILURE(rc))
     1664    {
     1665        NtClose(hFile);
     1666        return rc;
     1667    }
     1668
     1669    /*
     1670     * Finally, open the image with the loader
     1671     */
     1672    RTLDRMOD hLdrMod;
     1673    RTLDRARCH enmArch = fFlags & SUPHNTVI_F_RC_IMAGE ? RTLDRARCH_X86_32 : RTLDRARCH_HOST;
     1674    if (fFlags & SUPHNTVI_F_RESOURCE_IMAGE)
     1675        enmArch = RTLDRARCH_WHATEVER;
     1676    rc = RTLdrOpenWithReader(&pNtViRdr->Core, RTLDR_O_FOR_VALIDATION, enmArch, &hLdrMod, pErrInfo);
     1677    if (RT_FAILURE(rc))
     1678        return supHardNtVpSetInfo1(pErrInfo, rc, "RTLdrOpenWithReader failed: %Rrc (Image='%ls').",
     1679                                   rc, pUniStrPath->Buffer);
     1680
     1681    /*
     1682     * Fill in the cache entry.
     1683     */
     1684    pEntry->pszName   = pszName;
     1685    pEntry->hLdrMod   = hLdrMod;
     1686    pEntry->pNtViRdr  = pNtViRdr;
     1687    pEntry->hFile     = hFile;
     1688    pEntry->pbBits    = NULL;
     1689    pEntry->fVerified = false;
     1690
     1691    return VINF_SUCCESS;
     1692}
     1693
     1694#if 0//def IN_RING3
     1695DECLHIDDEN(int) supHardNtLdrCacheOpen(const char *pszName, PRTERRINFO pErrInfo, PSUPHNTLDRCACHEENTRY *ppEntry)
     1696{
     1697}
     1698#endif
     1699
     1700
    14901701/**
    14911702 * Opens all the images with the IPRT loader, setting both, hFile, pNtViRdr and
     
    15021713        PSUPHNTVPIMAGE pImage = &pThis->aImages[i];
    15031714
     1715#ifdef IN_RING3
    15041716        /*
    1505          * Open the image file.
     1717         * Try the cache first.
    15061718         */
    1507         HANDLE              hFile = RTNT_INVALID_HANDLE_VALUE;
    1508         IO_STATUS_BLOCK     Ios   = RTNT_IO_STATUS_BLOCK_INITIALIZER;
    1509 
    1510         OBJECT_ATTRIBUTES   ObjAttr;
    1511         InitializeObjectAttributes(&ObjAttr, &pImage->Name.UniStr, OBJ_CASE_INSENSITIVE, NULL /*hRootDir*/, NULL /*pSecDesc*/);
    1512 #ifdef IN_RING0
    1513         ObjAttr.Attributes |= OBJ_KERNEL_HANDLE;
    1514 #endif
    1515 
    1516         NTSTATUS rcNt = NtCreateFile(&hFile,
    1517                                      GENERIC_READ,
    1518                                      &ObjAttr,
    1519                                      &Ios,
    1520                                      NULL /* Allocation Size*/,
    1521                                      FILE_ATTRIBUTE_NORMAL,
    1522                                      FILE_SHARE_READ,
    1523                                      FILE_OPEN,
    1524                                      FILE_NON_DIRECTORY_FILE,
    1525                                      NULL /*EaBuffer*/,
    1526                                      0 /*EaLength*/);
    1527         if (NT_SUCCESS(rcNt))
    1528             rcNt = Ios.Status;
    1529         if (!NT_SUCCESS(rcNt))
    1530             return supHardNtVpSetInfo2(pThis, VERR_SUP_VP_IMAGE_FILE_OPEN_ERROR,
    1531                                       "Error opening image for scanning: %#x (name %ls)", rcNt, pImage->Name.UniStr.Buffer);
     1719        pImage->pCacheEntry = supHardNtLdrCacheLookupEntry(pImage->pszName);
     1720        if (pImage->pCacheEntry)
     1721            continue;
    15321722
    15331723        /*
    1534          * Figure out validation flags we'll be using and create the reader
    1535          * for this image.
     1724         * Not in the cache, so load it into the cache.
    15361725         */
    1537         uint32_t fFlags = pImage->fDll
    1538                         ? SUPHNTVI_F_TRUSTED_INSTALLER_OWNER | SUPHNTVI_F_ALLOW_CAT_FILE_VERIFICATION
    1539                         : SUPHNTVI_F_REQUIRE_BUILD_CERT;
    1540         if (pImage->f32bitResourceDll)
    1541             fFlags |= SUPHNTVI_F_RESOURCE_IMAGE;
    1542 
    1543         PSUPHNTVIRDR pNtViRdr;
    1544         int rc = supHardNtViRdrCreate(hFile, pImage->Name.UniStr.Buffer, fFlags, &pNtViRdr);
     1726        if (g_cSupNtVpLdrCacheEntries >= RT_ELEMENTS(g_aSupNtVpLdrCacheEntries))
     1727            return supHardNtVpSetInfo2(pThis, VERR_INTERNAL_ERROR_3, "Loader cache overflow.");
     1728        pImage->pCacheEntry = &g_aSupNtVpLdrCacheEntries[g_cSupNtVpLdrCacheEntries];
     1729#else
     1730        /*
     1731         * In ring-0 we don't have a cache at the moment (resource reasons), so
     1732         * we have a static cache entry in each image structure that we use instead.
     1733         */
     1734        pImage->pCacheEntry = &pImage->CacheEntry;
     1735#endif
     1736
     1737        int rc = supHardNtLdrCacheNewEntry(pImage->pCacheEntry, pImage->pszName, &pImage->Name.UniStr,
     1738                                           pImage->fDll, pImage->f32bitResourceDll, pThis->pErrInfo);
    15451739        if (RT_FAILURE(rc))
    1546         {
    1547             NtClose(hFile);
    15481740            return rc;
    1549         }
    1550         pImage->hFile    = hFile;
    1551         pImage->pNtViRdr = pNtViRdr;
    1552 
    1553         /*
    1554          * Finally, open the image with the laoder.
    1555          */
    1556         RTLDRMOD hLdrMod;
    1557         RTLDRARCH enmArch = fFlags & SUPHNTVI_F_RC_IMAGE ? RTLDRARCH_X86_32 : RTLDRARCH_HOST;
    1558         if (fFlags & SUPHNTVI_F_RESOURCE_IMAGE)
    1559             enmArch = RTLDRARCH_WHATEVER;
    1560         rc = RTLdrOpenWithReader(&pNtViRdr->Core, RTLDR_O_FOR_VALIDATION, enmArch, &hLdrMod, pThis->pErrInfo);
    1561         if (RT_FAILURE(rc))
    1562             return supHardNtVpSetInfo2(pThis, rc, "RTLdrOpenWithReader failed: %Rrc (Image='%ls').",
    1563                                        rc, pImage->Name.UniStr.Buffer);
    1564 
    1565         pImage->hLdrMod = hLdrMod;
     1741#ifdef IN_RING3
     1742        g_cSupNtVpLdrCacheEntries++;
     1743#endif
    15661744    }
    15671745
     
    18031981             * Clean up the state.
    18041982             */
     1983#ifdef IN_RING0
    18051984            for (uint32_t i = 0; i < pThis->cImages; i++)
    1806             {
    1807                 if (pThis->aImages[i].hLdrMod != NIL_RTLDRMOD)
    1808                     RTLdrClose(pThis->aImages[i].hLdrMod);
    1809                 else if (pThis->aImages[i].pNtViRdr)
    1810                     pThis->aImages[i].pNtViRdr->Core.pfnDestroy(&pThis->aImages[i].pNtViRdr->Core);
    1811                 if (pThis->aImages[i].hFile)
    1812                     NtClose(pThis->aImages[i].hFile);
    1813             }
     1985                supHardNTLdrCacheDeleteEntry(&pThis->aImages[i].CacheEntry);
     1986#endif
    18141987            suplibHardenedFree(pThis);
    18151988        }
  • trunk/src/VBox/HostDrivers/Support/win/SUPR3HardenedMain-win.cpp

    r52365 r52366  
    21282128
    21292129    /*
     2130     * Ditch the loader cache so we don't sit on too much memory while waiting.
     2131     */
     2132    supR3HardenedWinFlushLoaderCache();
     2133    HeapCompact(GetProcessHeap(), 0 /*dwFlags*/);
     2134
     2135    /*
    21302136     * If this is the middle process, wait for both parent and child to quit.
    21312137     */
  • trunk/src/VBox/HostDrivers/Support/win/import-template-kernel32.h

    r52365 r52366  
    1313SUPHARNT_IMPORT_STDCALL(GetTickCount, 0)
    1414SUPHARNT_IMPORT_STDCALL(HeapAlloc, 12)
     15SUPHARNT_IMPORT_STDCALL(HeapCompact, 8)
    1516SUPHARNT_IMPORT_STDCALL(HeapFree, 8)
    1617SUPHARNT_IMPORT_STDCALL(HeapReAlloc, 16)
Note: See TracChangeset for help on using the changeset viewer.

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