Changeset 52366 in vbox for trunk/src/VBox/HostDrivers
- Timestamp:
- Aug 13, 2014 10:35:55 AM (10 years ago)
- Location:
- trunk/src/VBox/HostDrivers/Support
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/HostDrivers/Support/SUPLibInternal.h
r52356 r52366 439 439 DECLHIDDEN(void) supR3HardenedWinVerifyProcess(void); 440 440 DECLHIDDEN(void) supR3HardenedWinResolveVerifyTrustApiAndHookThreadCreation(const char *pszProgName); 441 DECLHIDDEN(void) supR3HardenedWinFlushLoaderCache(); 441 442 DECLHIDDEN(bool) supR3HardenedWinIsReSpawnNeeded(int iWhich, int cArgs, char **papszArgs); 442 443 DECLHIDDEN(int) supR3HardenedWinReSpawn(int iWhich); -
trunk/src/VBox/HostDrivers/Support/SUPR3HardenedMain.cpp
r52356 r52366 249 249 # else 250 250 DWORD cbWritten; 251 WriteFile(hStdOut, pch, cch, &cbWritten, NULL);251 WriteFile(hStdOut, pch, (DWORD)cch, &cbWritten, NULL); 252 252 # endif 253 253 } … … 1726 1726 } 1727 1727 SUP_DPRINTF(("SUPR3HardenedMain: Final process, opening VBoxDrv...\n")); 1728 supR3HardenedWinFlushLoaderCache(); 1728 1729 #endif /* RT_OS_WINDOWS */ 1729 1730 … … 1738 1739 * Windows: Enable the use of windows APIs to verify images at load time. 1739 1740 */ 1741 supR3HardenedWinFlushLoaderCache(); 1740 1742 supR3HardenedWinResolveVerifyTrustApiAndHookThreadCreation(g_pszSupLibHardenedProgName); 1741 1743 g_enmSupR3HardenedMainState = SUPR3HARDENEDMAINSTATE_VERIFY_TRUST_READY; -
trunk/src/VBox/HostDrivers/Support/win/SUPHardenedVerify-win.h
r52365 r52366 105 105 /** @} */ 106 106 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 */ 114 typedef 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. */ 132 typedef SUPHNTLDRCACHEENTRY *PSUPHNTLDRCACHEENTRY; 133 DECLHIDDEN(int) supHardNtLdrCacheOpen(const char *pszName, PRTERRINFO pErrInfo, PSUPHNTLDRCACHEENTRY *ppEntry); 134 DECLHIDDEN(int) supHardNtLdrCacheEntryVerify(PSUPHNTLDRCACHEENTRY pEntry, PCRTUTF16 pwszName, PRTERRINFO pErrInfo); 135 DECLHIDDEN(int) supHardNtLdrCacheEntryAllocBits(PSUPHNTLDRCACHEENTRY pEntry, uint8_t **ppbBits, PRTERRINFO pErrInfo); 136 137 107 138 /** Which directory under the system root to get. */ 108 139 typedef enum SUPHARDNTSYSROOTDIR -
trunk/src/VBox/HostDrivers/Support/win/SUPHardenedVerifyImage-win.cpp
r52365 r52366 423 423 ULONG cbActual; 424 424 NTSTATUS rcNt = NtQuerySecurityObject(hFile, OWNER_SECURITY_INFORMATION, &uBuf.Abs, sizeof(uBuf), &cbActual); 425 SUP_DPRINTF(("NtQuerySecurityObject: rcNt=%#x on '%ls'\n", rcNt, pwszName));426 425 if (!NT_SUCCESS(rcNt)) 427 426 { -
trunk/src/VBox/HostDrivers/Support/win/SUPHardenedVerifyProcess-win.cpp
r52365 r52366 112 112 bool f32bitResourceDll; 113 113 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 123 120 } SUPHNTVPIMAGE; 124 121 /** Pointer to image info from the virtual address space scan. */ … … 231 228 #endif 232 229 230 #ifdef IN_RING3 231 /** The number of valid entries in the loader cache.. */ 232 static uint32_t g_cSupNtVpLdrCacheEntries = 0; 233 /** The loader cache entries. */ 234 static SUPHNTLDRCACHEENTRY g_aSupNtVpLdrCacheEntries[RT_ELEMENTS(g_apszSupNtVpAllowedDlls) + 1 + 3]; 235 #endif 236 233 237 234 238 /** … … 305 309 static int supHardNtVpReadImage(PSUPHNTVPIMAGE pImage, uint64_t off, void *pvBuf, size_t cbRead) 306 310 { 307 return pImage->p NtViRdr->Core.pfnRead(&pImage->pNtViRdr->Core, pvBuf, cbRead, off);311 return pImage->pCacheEntry->pNtViRdr->Core.pfnRead(&pImage->pCacheEntry->pNtViRdr->Core, pvBuf, cbRead, off); 308 312 } 309 313 … … 595 599 if (pImage) 596 600 { 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); 598 603 if (RT_SUCCESS(rc)) 599 604 return rc; … … 610 615 if (pImage) 611 616 { 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); 613 619 if (RT_SUCCESS(rc)) 614 620 return rc; … … 628 634 size_t cbInfo = RT_MIN((uint32_t)*pValue, sizeof(RTLDRIMPORTINFO) + 32); 629 635 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); 631 638 if (RT_SUCCESS(rc)) 632 639 { … … 635 642 if (pImage) 636 643 { 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); 638 646 if (RT_SUCCESS(rc)) 639 647 return rc; … … 741 749 "%s: SizeOfImage (%#x) isn't close enough to the mapping size (%#x)", 742 750 pImage->pszName, cbImage, pImage->cbImage); 743 if (cbImage != RTLdrSize(pImage-> hLdrMod))751 if (cbImage != RTLdrSize(pImage->pCacheEntry->hLdrMod)) 744 752 return supHardNtVpSetInfo2(pThis, VERR_SUP_VP_BAD_IMAGE_SIZE, 745 753 "%s: SizeOfImage (%#x) differs from what RTLdrSize returns (%#zx)", 746 pImage->pszName, cbImage, RTLdrSize(pImage-> hLdrMod));754 pImage->pszName, cbImage, RTLdrSize(pImage->pCacheEntry->hLdrMod)); 747 755 748 756 uint32_t const cbSectAlign = fIs32Bit ? pNtHdrs32->OptionalHeader.SectionAlignment : pNtHdrs->OptionalHeader.SectionAlignment; … … 791 799 * Get relocated bits. 792 800 */ 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; 797 805 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); 799 807 else 800 rc = RTLdrGetBits(pImage-> hLdrMod, pImage->pbBits, pImage->uImageBase, supHardNtVpGetImport, pThis);808 rc = RTLdrGetBits(pImage->pCacheEntry->hLdrMod, pbBits, pImage->uImageBase, supHardNtVpGetImport, pThis); 801 809 if (RT_FAILURE(rc)) 802 810 return supHardNtVpSetInfo2(pThis, rc, "%s: RTLdrGetBits failed: %Rrc", pImage->pszName, rc); … … 806 814 { 807 815 if (fIs32Bit) 808 ((PIMAGE_NT_HEADERS32)&p Image->pbBits[offNtHdrs])->OptionalHeader.ImageBase = (uint32_t)pImage->uImageBase;816 ((PIMAGE_NT_HEADERS32)&pbBits[offNtHdrs])->OptionalHeader.ImageBase = (uint32_t)pImage->uImageBase; 809 817 else 810 ((PIMAGE_NT_HEADERS)&p Image->pbBits[offNtHdrs])->OptionalHeader.ImageBase = pImage->uImageBase;818 ((PIMAGE_NT_HEADERS)&pbBits[offNtHdrs])->OptionalHeader.ImageBase = pImage->uImageBase; 811 819 } 812 820 … … 822 830 { 823 831 /* 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); 825 833 if (RT_FAILURE(rc)) 826 834 return supHardNtVpSetInfo2(pThis, rc, "%s: Failed to find 'NtCreateSection': %Rrc", pImage->pszName, rc); … … 830 838 831 839 /* 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); 833 841 if (RT_SUCCESS(rc)) 834 842 { 835 843 aSkipAreas[cSkipAreas].uRva = (uint32_t)uValue; 836 aSkipAreas[cSkipAreas++].cb = RT_MAX(p Image->pbBits[(uint32_t)uValue], 0x50);844 aSkipAreas[cSkipAreas++].cb = RT_MAX(pbBits[(uint32_t)uValue], 0x50); 837 845 } 838 846 } … … 844 852 if (!pImage->fApiSetSchemaOnlySection1) 845 853 { 846 rc = supHardNtVpFileMemCompareSection(pThis, pImage, 0 /*uRva*/, cbHdrsFile, p Image->pbBits, -1, NULL, 0, PAGE_READONLY);854 rc = supHardNtVpFileMemCompareSection(pThis, pImage, 0 /*uRva*/, cbHdrsFile, pbBits, -1, NULL, 0, PAGE_READONLY); 847 855 if (RT_FAILURE(rc)) 848 856 return rc; … … 912 920 rc = VINF_SUCCESS; 913 921 if (uRva < uSectRva && !pImage->fApiSetSchemaOnlySection1) /* Any gap worth checking? */ 914 rc = supHardNtVpFileMemCompareSection(pThis, pImage, uRva, uSectRva - uRva, p Image->pbBits + uRva,922 rc = supHardNtVpFileMemCompareSection(pThis, pImage, uRva, uSectRva - uRva, pbBits + uRva, 915 923 i - 1, NULL, 0, fPrevProt); 916 924 if (RT_SUCCESS(rc)) 917 rc = supHardNtVpFileMemCompareSection(pThis, pImage, uSectRva, cbMap, p Image->pbBits + uSectRva,925 rc = supHardNtVpFileMemCompareSection(pThis, pImage, uSectRva, cbMap, pbBits + uSectRva, 918 926 i, aSkipAreas, cSkipAreas, fProt); 919 927 if (RT_SUCCESS(rc)) … … 963 971 */ 964 972 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); 969 977 if (RT_SUCCESS(rc)) 970 {971 978 rc = supHardNtVpVerifyImageMemoryCompare(pThis, pImage, hProcess, pThis->pErrInfo); 972 973 if (pImage->pbBits)974 {975 suplibHardenedFree(pImage->pbBits);976 pImage->pbBits = NULL;977 }978 }979 979 } 980 980 else 981 rc = supHardNtVpSetInfo2(pThis, VERR_OPEN_FAILED, " hLdrMod is NIL! Impossible!");981 rc = supHardNtVpSetInfo2(pThis, VERR_OPEN_FAILED, "pCacheEntry/hLdrMod is NIL! Impossible!"); 982 982 return rc; 983 983 } … … 1216 1216 pImage->uImageBase = (uintptr_t)pMemInfo->AllocationBase; 1217 1217 pImage->cbImage = pMemInfo->RegionSize; 1218 pImage->hFile = NULL; 1219 pImage->hLdrMod = NIL_RTLDRMOD; 1220 pImage->pNtViRdr = NULL; 1218 pImage->pCacheEntry= NULL; 1221 1219 pImage->cRegions = 1; 1222 1220 pImage->aRegions[0].uRva = 0; … … 1488 1486 } 1489 1487 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 */ 1497 DECLHIDDEN(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 */ 1521 DECLHIDDEN(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 */ 1549 static 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 */ 1588 DECLHIDDEN(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 */ 1604 static 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 1619 static 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 1695 DECLHIDDEN(int) supHardNtLdrCacheOpen(const char *pszName, PRTERRINFO pErrInfo, PSUPHNTLDRCACHEENTRY *ppEntry) 1696 { 1697 } 1698 #endif 1699 1700 1490 1701 /** 1491 1702 * Opens all the images with the IPRT loader, setting both, hFile, pNtViRdr and … … 1502 1713 PSUPHNTVPIMAGE pImage = &pThis->aImages[i]; 1503 1714 1715 #ifdef IN_RING3 1504 1716 /* 1505 * Open the image file.1717 * Try the cache first. 1506 1718 */ 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; 1532 1722 1533 1723 /* 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. 1536 1725 */ 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); 1545 1739 if (RT_FAILURE(rc)) 1546 {1547 NtClose(hFile);1548 1740 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 1566 1744 } 1567 1745 … … 1803 1981 * Clean up the state. 1804 1982 */ 1983 #ifdef IN_RING0 1805 1984 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 1814 1987 suplibHardenedFree(pThis); 1815 1988 } -
trunk/src/VBox/HostDrivers/Support/win/SUPR3HardenedMain-win.cpp
r52365 r52366 2128 2128 2129 2129 /* 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 /* 2130 2136 * If this is the middle process, wait for both parent and child to quit. 2131 2137 */ -
trunk/src/VBox/HostDrivers/Support/win/import-template-kernel32.h
r52365 r52366 13 13 SUPHARNT_IMPORT_STDCALL(GetTickCount, 0) 14 14 SUPHARNT_IMPORT_STDCALL(HeapAlloc, 12) 15 SUPHARNT_IMPORT_STDCALL(HeapCompact, 8) 15 16 SUPHARNT_IMPORT_STDCALL(HeapFree, 8) 16 17 SUPHARNT_IMPORT_STDCALL(HeapReAlloc, 16)
Note:
See TracChangeset
for help on using the changeset viewer.