Index: trunk/src/VBox/HostDrivers/Support/win/SUPHardenedVerify-win.h
===================================================================
--- trunk/src/VBox/HostDrivers/Support/win/SUPHardenedVerify-win.h	(revision 52374)
+++ trunk/src/VBox/HostDrivers/Support/win/SUPHardenedVerify-win.h	(revision 52375)
@@ -43,4 +43,5 @@
 DECLHIDDEN(int)     supHardenedWinInitImageVerifier(PRTERRINFO pErrInfo);
 DECLHIDDEN(void)    supHardenedWinTermImageVerifier(void);
+DECLHIDDEN(void)    supR3HardenedWinVerifyCachePreload(PCRTUTF16 pwszName);
 
 typedef enum SUPHARDNTVPKIND
@@ -58,4 +59,5 @@
                                                 PCRTUTF16 pwszRight, uint32_t cwcRight, bool fCheckSlash);
 DECLHIDDEN(bool)    supHardViIsAppPatchDir(PCRTUTF16 pwszPath, uint32_t cwcName);
+
 
 /**
Index: trunk/src/VBox/HostDrivers/Support/win/SUPHardenedVerifyImage-win.cpp
===================================================================
--- trunk/src/VBox/HostDrivers/Support/win/SUPHardenedVerifyImage-win.cpp	(revision 52374)
+++ trunk/src/VBox/HostDrivers/Support/win/SUPHardenedVerifyImage-win.cpp	(revision 52375)
@@ -954,30 +954,4 @@
 
 /**
- * Checks if it's safe to call WinVerifyTrust or whether we might end up in an
- * infinite recursion.
- *
- * @returns true if ok, false if not.
- * @param   hFile               The file name.
- * @param   pwszName            The executable name.
- */
-static bool supR3HardNtViCanCallWinVerifyTrust(HANDLE hFile, PCRTUTF16 pwszName)
-{
-     /*
-      * Recursion preventions hacks:
-      *  - Don't try call WinVerifyTrust on Wintrust.dll when called from the
-      *    create section hook. CRYPT32.DLL tries to load WinTrust.DLL in some cases.
-      */
-     size_t cwcName = RTUtf16Len(pwszName);
-     if (   hFile != NULL
-         && cwcName > g_System32NtPath.UniStr.Length / sizeof(WCHAR)
-         && !memcmp(pwszName, g_System32NtPath.UniStr.Buffer, g_System32NtPath.UniStr.Length)
-         && supHardViUtf16PathIsEqual(&pwszName[g_System32NtPath.UniStr.Length / sizeof(WCHAR)], "\\wintrust.dll"))
-         return false;
-
-     return true;
-}
-
-
-/**
  * Verifies the given loader image.
  *
@@ -1079,6 +1053,5 @@
         static uint32_t volatile s_idActiveThread = UINT32_MAX;
         uint32_t const idCurrentThread = GetCurrentThreadId();
-        if (   s_idActiveThread != idCurrentThread
-            && supR3HardNtViCanCallWinVerifyTrust(pNtViRdr->hFile, pwszName) )
+        if (s_idActiveThread != idCurrentThread)
         {
             ASMAtomicCmpXchgU32(&s_idActiveThread, idCurrentThread, UINT32_MAX);
@@ -1104,6 +1077,9 @@
                 }
                 else if (RT_SUCCESS(rc))
+                {
+                    /** @todo having trouble with a 32-bit windows box when letting these calls thru */
                     rc = supR3HardNtViCallWinVerifyTrust(pNtViRdr->hFile, pwszName, pNtViRdr->fFlags, pErrInfo,
                                                          g_pfnWinVerifyTrust);
+                }
                 else
                 {
@@ -1174,5 +1150,5 @@
             supHardNtViRdrDestroy(&pNtViRdr->Core);
     }
-    SUP_DPRINTF(("supHardenedWinVerifyImageByHandle: -> %d (%ls)\n", rc, pwszName));
+    SUP_DPRINTF(("supHardenedWinVerifyImageByHandle: -> %d %s(%ls)\n", rc, pfCacheable && *pfCacheable ? "cacheable ": "", pwszName));
     return rc;
 }
@@ -1769,4 +1745,36 @@
 }
 
+
+/**
+ * Loads a module in the system32 directory.
+ *
+ * @returns Module handle on success. Won't return on faliure.
+ * @param   pszName             The name of the DLL to load.
+ */
+DECLHIDDEN(HMODULE) supR3HardenedWinLoadSystem32Dll(const char *pszName)
+{
+    WCHAR wszName[200+60];
+    UINT cwcDir = GetSystemWindowsDirectoryW(wszName, RT_ELEMENTS(wszName) - 60);
+    memcpy(&wszName[cwcDir], RT_STR_TUPLE(L"\\System32\\"));
+    RTUtf16CopyAscii(&wszName[cwcDir + sizeof("\\System32\\") - 1], RT_ELEMENTS(wszName) - cwcDir, pszName);
+
+    DWORD fFlags = 0;
+    if (g_uNtVerCombined >= SUP_MAKE_NT_VER_SIMPLE(6, 0))
+       fFlags = LOAD_LIBRARY_SEARCH_SYSTEM32;
+    HMODULE hMod = LoadLibraryExW(wszName, NULL, fFlags);
+    if (   hMod == NULL
+        && fFlags
+        && g_uNtVerCombined < SUP_MAKE_NT_VER_SIMPLE(6, 2)
+        && GetLastError() == ERROR_INVALID_PARAMETER)
+    {
+        fFlags = 0;
+        hMod = LoadLibraryExW(wszName, NULL, fFlags);
+    }
+    if (hMod == NULL)
+        supR3HardenedFatal("Error loading '%s': %u [%ls]", pszName, GetLastError(), wszName);
+    return hMod;
+}
+
+
 /**
  * Called by supR3HardenedWinResolveVerifyTrustApiAndHookThreadCreation to
@@ -1774,10 +1782,6 @@
  *
  * These certificates permits us to correctly validate third party DLLs.
- *
- * @param   fLoadLibraryFlags       The LoadLibraryExW flags that the caller
- *                                  found to work.  Avoids us having to retry on
- *                                  ERROR_INVALID_PARAMETER.
- */
-static void supR3HardenedWinRetrieveTrustedRootCAs(DWORD fLoadLibraryFlags)
+ */
+static void supR3HardenedWinRetrieveTrustedRootCAs(void)
 {
     uint32_t cAdded = 0;
@@ -1786,7 +1790,5 @@
      * Load crypt32.dll and resolve the APIs we need.
      */
-    HMODULE hCrypt32 = LoadLibraryExW(L"\\\\.\\GLOBALROOT\\SystemRoot\\System32\\crypt32.dll", NULL, fLoadLibraryFlags);
-    if (!hCrypt32)
-        supR3HardenedFatal("Error loading 'crypt32.dll': %u", GetLastError());
+    HMODULE hCrypt32 = supR3HardenedWinLoadSystem32Dll("crypt32.dll");
 
 #define RESOLVE_CRYPT32_API(a_Name, a_pfnType) \
@@ -1885,19 +1887,5 @@
      * Resolve it.
      */
-    DWORD fFlags = 0;
-    if (g_uNtVerCombined >= SUP_MAKE_NT_VER_SIMPLE(6, 0))
-       fFlags = LOAD_LIBRARY_SEARCH_SYSTEM32;
-    HMODULE hWintrust = LoadLibraryExW(L"\\\\.\\GLOBALROOT\\SystemRoot\\System32\\Wintrust.dll", NULL, fFlags);
-    if (   hWintrust == NULL
-        && fFlags
-        && g_uNtVerCombined < SUP_MAKE_NT_VER_SIMPLE(6, 2)
-        && GetLastError() == ERROR_INVALID_PARAMETER)
-    {
-        fFlags = 0;
-        hWintrust = LoadLibraryExW(L"\\\\.\\GLOBALROOT\\SystemRoot\\System32\\Wintrust.dll", NULL, fFlags);
-    }
-    if (hWintrust == NULL)
-        supR3HardenedFatal("Error loading 'Wintrust.dll': %u", GetLastError());
-
+    HMODULE hWintrust = supR3HardenedWinLoadSystem32Dll("Wintrust.dll");
 #define RESOLVE_CRYPT_API(a_Name, a_pfnType, a_uMinWinVer) \
     do { \
@@ -1943,8 +1931,62 @@
     SUP_DPRINTF(("g_pfnWinVerifyTrust=%p\n", pfnWinVerifyTrust));
 
+# ifdef IN_SUP_HARDENED_R3
+    /*
+     * Load some problematic DLLs into the verifier cache to prevent
+     * recursion trouble.
+     */
+    supR3HardenedWinVerifyCachePreload(L"\\SystemRoot\\System32\\crypt32.dll");
+    supR3HardenedWinVerifyCachePreload(L"\\SystemRoot\\System32\\Wintrust.dll");
+# endif
+
     /*
      * Now, get trusted root CAs so we can verify a broader scope of signatures.
      */
-    supR3HardenedWinRetrieveTrustedRootCAs(fFlags);
+    supR3HardenedWinRetrieveTrustedRootCAs();
+
+# ifdef IN_SUP_HARDENED_R3
+    /*
+     * Do some verify cache preloading.  The MS Visual C++ CRT DLLs works
+     * around recursion issues with WinVerifyTrust on 32-bit windows 7.
+     */
+    SUP_DPRINTF(("preloading part 2...\n"));
+#  if 0 /* Seeing if this helps with the later Win7/32 issue... apparently not :-/ */
+    supR3HardenedWinVerifyCachePreload(L"\\SystemRoot\\System32\\cfgmgr32.dll");
+    supR3HardenedWinVerifyCachePreload(L"\\SystemRoot\\System32\\devobj.dll");
+    supR3HardenedWinVerifyCachePreload(L"\\SystemRoot\\System32\\setupapi.dll");
+    supR3HardenedWinLoadSystem32Dll("setupapi.dll");
+    supR3HardenedWinVerifyCachePreload(L"\\SystemRoot\\System32\\rsaenh.dll");
+    supR3HardenedWinLoadSystem32Dll("rsaenh.dll");
+#  endif
+
+    WCHAR wszPath[260+16];
+    supR3HardenedWinVerifyCachePreload(L"\\SystemRoot\\System32\\apphelp.dll");
+    memcpy(wszPath, g_SupLibHardenedExeNtPath.UniStr.Buffer, g_SupLibHardenedExeNtPath.UniStr.Length);
+    static char const *s_apszAppDlls[] =
+    {
+        NULL,
+        "VBoxRT.dll",
+#  if _MSC_VER < 1600
+        "msvcr90.dll",  "msvcp90.dll",
+#  elif _MSC_VER < 1700
+        "msvcr100.dll", "msvcp100.dll",
+#  elif _MSC_VER < 1800
+        "msvcr110.dll", "msvcp110.dll",
+#  elif _MSC_VER < 1900
+        "msvcr120.dll", "msvcp120.dll",
+#  elif _MSC_VER < 1900
+        "msvcr130.dll", "msvcp130.dll",
+#  else
+#   error "Unsupported compiler version."
+#  endif
+    };
+    s_apszAppDlls[0] = pszProgName;
+    for (uint32_t i = 0; i < RT_ELEMENTS(s_apszAppDlls); i++)
+    {
+        RTUtf16CopyAscii(&wszPath[g_offSupLibHardenedExeNtName], 300 - g_offSupLibHardenedExeNtName, s_apszAppDlls[i]);
+        supR3HardenedWinVerifyCachePreload(wszPath);
+    }
+    SUP_DPRINTF(("preloading part 2 - done.\n"));
+# endif
 }
 
Index: trunk/src/VBox/HostDrivers/Support/win/SUPR3HardenedMain-win.cpp
===================================================================
--- trunk/src/VBox/HostDrivers/Support/win/SUPR3HardenedMain-win.cpp	(revision 52374)
+++ trunk/src/VBox/HostDrivers/Support/win/SUPR3HardenedMain-win.cpp	(revision 52375)
@@ -381,12 +381,15 @@
  *                              here instead of being handled by the caller to
  *                              save code duplication.
- */
-static void supR3HardenedWinVerifyCacheInsert(PCUNICODE_STRING pUniStr, HANDLE hFile, int rc, bool fCacheable)
+ * @param   fForceCacheable     Overrides the main state and @a fCacheable.
+ */
+static void supR3HardenedWinVerifyCacheInsert(PCUNICODE_STRING pUniStr, HANDLE hFile, int rc, bool fCacheable,
+                                              bool fForceCacheable)
 {
     /*
      * Don't cache anything until we've got the WinVerifyTrust API up and running.
      */
-    if (   g_enmSupR3HardenedMainState >= SUPR3HARDENEDMAINSTATE_VERIFY_TRUST_READY
-        && fCacheable)
+    if (   (   g_enmSupR3HardenedMainState >= SUPR3HARDENEDMAINSTATE_VERIFY_TRUST_READY
+            && fCacheable)
+        || fForceCacheable)
     {
         /*
@@ -414,5 +417,9 @@
             {
                 if (ASMAtomicCmpXchgPtr(ppEntry, pEntry, NULL))
+                {
+                    SUP_DPRINTF(("supR3HardenedWinVerifyCacheInsert: %ls\n", pUniStr->Buffer));
                     return;
+                }
+
                 PVERIFIERCACHEENTRY pOther = *ppEntry;
                 if (!pOther)
@@ -618,4 +625,284 @@
 
 
+static NTSTATUS supR3HardenedScreenImage(HANDLE hFile, bool fImage, PULONG pfAccess, PULONG pfProtect, bool *pfCallRealApi,
+                                         bool fForceCacheable)
+{
+    *pfCallRealApi = false;
+
+    /*
+     * Query the name of the file, making sure to zero terminator the
+     * string. (2nd half of buffer is used for error info, see below.)
+     */
+    union
+    {
+        UNICODE_STRING UniStr;
+        uint8_t abBuffer[sizeof(UNICODE_STRING) + 2048 * sizeof(WCHAR)];
+    } uBuf;
+    RT_ZERO(uBuf);
+    ULONG cbNameBuf;
+    NTSTATUS rcNt = NtQueryObject(hFile, ObjectNameInformation, &uBuf, sizeof(uBuf) - sizeof(WCHAR) - 128, &cbNameBuf);
+    if (!NT_SUCCESS(rcNt))
+    {
+        supR3HardenedError(VINF_SUCCESS, false, "NtCreateSection: NtQueryObject -> %#x (fImage=%d fProtect=%#x fAccess=%#x)\n",
+                           fImage, *pfProtect, *pfAccess);
+        return rcNt;
+    }
+
+    if (supR3HardenedWinIsPossible8dot3Path(uBuf.UniStr.Buffer))
+    {
+        uBuf.UniStr.MaximumLength = sizeof(uBuf) - 128;
+        supR3HardenedWinFix8dot3Path(hFile, &uBuf.UniStr);
+    }
+
+    /*
+     * Check the cache.
+     */
+    PVERIFIERCACHEENTRY pCacheHit = supR3HardenedWinVerifyCacheLookup(&uBuf.UniStr, hFile);
+    if (pCacheHit)
+    {
+        SUP_DPRINTF(("NtCreateSection: cache hit (%Rrc) on %ls\n", pCacheHit->rc, pCacheHit->wszPath));
+        if (RT_SUCCESS(pCacheHit->rc))
+        {
+            *pfCallRealApi = true;
+            return STATUS_SUCCESS;
+        }
+        supR3HardenedError(VINF_SUCCESS, false, "NtCreateSection: cached rc=%Rrc fImage=%d fProtect=%#x fAccess=%#x %ls\n",
+                           pCacheHit->rc, fImage, *pfProtect, *pfAccess, uBuf.UniStr.Buffer);
+        return STATUS_TRUST_FAILURE;
+    }
+
+    /*
+     * On XP the loader might hand us handles with just FILE_EXECUTE and
+     * SYNCHRONIZE, the means reading will fail later on.  Also, we need
+     * READ_CONTROL access to check the file ownership later on, and non
+     * of the OS versions seems be giving us that.  So, in effect we
+     * more or less always reopen the file here.
+     */
+    HANDLE hMyFile = NULL;
+    rcNt = NtDuplicateObject(NtCurrentProcess(), hFile, NtCurrentProcess(),
+                             &hMyFile,
+                             FILE_READ_DATA | READ_CONTROL | SYNCHRONIZE,
+                             0 /* Handle attributes*/, 0 /* Options */);
+    if (!NT_SUCCESS(rcNt))
+    {
+        if (rcNt == STATUS_ACCESS_DENIED)
+        {
+            IO_STATUS_BLOCK     Ios   = RTNT_IO_STATUS_BLOCK_INITIALIZER;
+            OBJECT_ATTRIBUTES   ObjAttr;
+            InitializeObjectAttributes(&ObjAttr, &uBuf.UniStr, OBJ_CASE_INSENSITIVE, NULL /*hRootDir*/, NULL /*pSecDesc*/);
+
+            rcNt = NtCreateFile(&hMyFile,
+                                FILE_READ_DATA | READ_CONTROL | SYNCHRONIZE,
+                                &ObjAttr,
+                                &Ios,
+                                NULL /* Allocation Size*/,
+                                FILE_ATTRIBUTE_NORMAL,
+                                FILE_SHARE_READ,
+                                FILE_OPEN,
+                                FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
+                                NULL /*EaBuffer*/,
+                                0 /*EaLength*/);
+            if (NT_SUCCESS(rcNt))
+                rcNt = Ios.Status;
+            if (!NT_SUCCESS(rcNt))
+            {
+                supR3HardenedError(VINF_SUCCESS, false,
+                                   "NtCreateSection: Failed to duplicate and open the file: rcNt=%#x hFile=%p %ls\n",
+                                   rcNt, hFile, uBuf.UniStr.Buffer);
+                return rcNt;
+            }
+
+            /* Check that we've got the same file. */
+            LARGE_INTEGER idMyFile, idInFile;
+            bool fMyValid = supR3HardenedWinVerifyCacheGetIndexNumber(hMyFile, &idMyFile);
+            bool fInValid = supR3HardenedWinVerifyCacheGetIndexNumber(hFile, &idInFile);
+            if (   fMyValid
+                && (   fMyValid != fInValid
+                    || idMyFile.QuadPart != idInFile.QuadPart))
+            {
+                supR3HardenedError(VINF_SUCCESS, false,
+                                   "NtCreateSection: Re-opened has different ID that input: %#llx vx %#llx (%ls)\n",
+                                   rcNt, idMyFile.QuadPart, idInFile.QuadPart, uBuf.UniStr.Buffer);
+                NtClose(hMyFile);
+                return STATUS_TRUST_FAILURE;
+            }
+        }
+        else
+        {
+            SUP_DPRINTF(("supR3HardenedMonitor_NtCreateSection: NtDuplicateObject -> %#x\n", rcNt));
+#ifdef DEBUG
+
+            supR3HardenedError(VINF_SUCCESS, false, "supR3HardenedMonitor_NtCreateSection: NtDuplicateObject(,%#x,) failed: %#x\n", hFile, rcNt);
+#endif
+            hMyFile = hFile;
+        }
+    }
+
+    /*
+     * Special Kludge for Windows XP and W2K3 and their stupid attempts
+     * at mapping a hidden XML file called c:\Windows\WindowsShell.Manifest
+     * with executable access.  The image bit isn't set, fortunately.
+     */
+    if (   !fImage
+        && uBuf.UniStr.Length > g_System32NtPath.UniStr.Length - sizeof(L"System32") + sizeof(WCHAR)
+        && memcmp(uBuf.UniStr.Buffer, g_System32NtPath.UniStr.Buffer,
+                  g_System32NtPath.UniStr.Length - sizeof(L"System32") + sizeof(WCHAR)) == 0)
+    {
+        PRTUTF16 pwszName = &uBuf.UniStr.Buffer[(g_System32NtPath.UniStr.Length - sizeof(L"System32") + sizeof(WCHAR)) / sizeof(WCHAR)];
+        if (RTUtf16ICmpAscii(pwszName, "WindowsShell.Manifest") == 0)
+        {
+            /*
+             * Drop all executable access to the mapping and let it continue.
+             */
+            SUP_DPRINTF(("supR3HardenedMonitor_NtCreateSection: Applying the drop-exec-kludge for '%ls'\n", uBuf.UniStr.Buffer));
+            if (*pfAccess & SECTION_MAP_EXECUTE)
+                *pfAccess = (*pfAccess & ~SECTION_MAP_EXECUTE) | SECTION_MAP_READ;
+            if (*pfProtect & PAGE_EXECUTE)
+                *pfProtect = (*pfProtect & ~PAGE_EXECUTE) | PAGE_READONLY;
+            *pfProtect = (*pfProtect & ~UINT32_C(0xf0)) | ((*pfProtect & UINT32_C(0xe0)) >> 4);
+            if (hMyFile != hFile)
+                NtClose(hMyFile);
+            *pfCallRealApi = true;
+            return STATUS_SUCCESS;
+        }
+    }
+
+    /*
+     * Check the path.  We don't allow DLLs to be loaded from just anywhere:
+     *      1. System32      - normal code or cat signing, owner TrustedInstaller.
+     *      2. WinSxS        - normal code or cat signing, owner TrustedInstaller.
+     *      3. VirtualBox    - kernel code signing and integrity checks.
+     *      4. AppPatchDir   - normal code or cat signing, owner TrustedInstaller.
+     *      5. Program Files - normal code or cat signing, owner TrustedInstaller.
+     *      6. Common Files  - normal code or cat signing, owner TrustedInstaller.
+     *      7. x86 variations of 4 & 5 - ditto.
+     */
+    bool fSystem32 = false;
+    Assert(g_SupLibHardenedExeNtPath.UniStr.Buffer[g_offSupLibHardenedExeNtName - 1] == '\\');
+    uint32_t fFlags = 0;
+    if (supHardViUniStrPathStartsWithUniStr(&uBuf.UniStr, &g_System32NtPath.UniStr, true /*fCheckSlash*/))
+    {
+        fSystem32 = true;
+        fFlags |= SUPHNTVI_F_ALLOW_CAT_FILE_VERIFICATION | SUPHNTVI_F_TRUSTED_INSTALLER_OWNER;
+    }
+    else if (supHardViUniStrPathStartsWithUniStr(&uBuf.UniStr, &g_WinSxSNtPath.UniStr, true /*fCheckSlash*/))
+        fFlags |= SUPHNTVI_F_ALLOW_CAT_FILE_VERIFICATION | SUPHNTVI_F_TRUSTED_INSTALLER_OWNER;
+    else if (supHardViUtf16PathStartsWithEx(uBuf.UniStr.Buffer, uBuf.UniStr.Length / sizeof(WCHAR),
+                                            g_SupLibHardenedExeNtPath.UniStr.Buffer,
+                                            g_offSupLibHardenedExeNtName, false /*fCheckSlash*/))
+        fFlags |= SUPHNTVI_F_REQUIRE_KERNEL_CODE_SIGNING | SUPHNTVI_F_REQUIRE_SIGNATURE_ENFORCEMENT;
+#ifdef VBOX_PERMIT_MORE
+    else if (supHardViIsAppPatchDir(uBuf.UniStr.Buffer, uBuf.UniStr.Length / sizeof(WCHAR)))
+        fFlags |= SUPHNTVI_F_ALLOW_CAT_FILE_VERIFICATION | SUPHNTVI_F_TRUSTED_INSTALLER_OWNER;
+    else if (supHardViUniStrPathStartsWithUniStr(&uBuf.UniStr, &g_ProgramFilesNtPath.UniStr, true /*fCheckSlash*/))
+        fFlags |= SUPHNTVI_F_ALLOW_CAT_FILE_VERIFICATION | SUPHNTVI_F_TRUSTED_INSTALLER_OWNER;
+    else if (supHardViUniStrPathStartsWithUniStr(&uBuf.UniStr, &g_CommonFilesNtPath.UniStr, true /*fCheckSlash*/))
+        fFlags |= SUPHNTVI_F_ALLOW_CAT_FILE_VERIFICATION | SUPHNTVI_F_TRUSTED_INSTALLER_OWNER;
+# ifdef RT_ARCH_AMD64
+    else if (supHardViUniStrPathStartsWithUniStr(&uBuf.UniStr, &g_ProgramFilesX86NtPath.UniStr, true /*fCheckSlash*/))
+        fFlags |= SUPHNTVI_F_ALLOW_CAT_FILE_VERIFICATION | SUPHNTVI_F_TRUSTED_INSTALLER_OWNER;
+    else if (supHardViUniStrPathStartsWithUniStr(&uBuf.UniStr, &g_CommonFilesX86NtPath.UniStr, true /*fCheckSlash*/))
+        fFlags |= SUPHNTVI_F_ALLOW_CAT_FILE_VERIFICATION | SUPHNTVI_F_TRUSTED_INSTALLER_OWNER;
+# endif
+#endif
+#ifdef VBOX_PERMIT_VISUAL_STUDIO_PROFILING
+    /* Hack to allow profiling our code with Visual Studio. */
+    else if (   uBuf.UniStr.Length > sizeof(L"\\SamplingRuntime.dll")
+             && memcmp(uBuf.UniStr.Buffer + (uBuf.UniStr.Length - sizeof(L"\\SamplingRuntime.dll") + sizeof(WCHAR)) / sizeof(WCHAR),
+                       L"\\SamplingRuntime.dll", sizeof(L"\\SamplingRuntime.dll") - sizeof(WCHAR)) == 0 )
+    {
+        if (hMyFile != hFile)
+            NtClose(hMyFile);
+        *pfCallRealApi = true;
+        return STATUS_SUCCESS;
+    }
+#endif
+    else
+    {
+        supR3HardenedError(VINF_SUCCESS, false,
+                           "supR3HardenedMonitor_NtCreateSection: Not a trusted location: '%ls' (fImage=%d fProtect=%#x fAccess=%#x)",
+                            uBuf.UniStr.Buffer, fImage, *pfAccess, *pfProtect);
+        if (hMyFile != hFile)
+            NtClose(hMyFile);
+        return STATUS_TRUST_FAILURE;
+    }
+
+    /*
+     * Do the verification. For better error message we borrow what's
+     * left of the path buffer for an RTERRINFO buffer.
+     */
+    RTERRINFO ErrInfo;
+    RTErrInfoInit(&ErrInfo, (char *)&uBuf.abBuffer[cbNameBuf], sizeof(uBuf) - cbNameBuf);
+
+    bool fCacheable = true;
+    int rc = supHardenedWinVerifyImageByHandle(hMyFile, uBuf.UniStr.Buffer, fFlags, &fCacheable, &ErrInfo);
+    if (RT_FAILURE(rc))
+    {
+        supR3HardenedError(VINF_SUCCESS, false,
+                           "supR3HardenedMonitor_NtCreateSection: rc=%Rrc fImage=%d fProtect=%#x fAccess=%#x %ls: %s\n",
+                           rc, fImage, *pfAccess, *pfProtect, uBuf.UniStr.Buffer, ErrInfo.pszMsg);
+        if (hMyFile != hFile)
+            NtClose(hMyFile);
+        return STATUS_TRUST_FAILURE;
+    }
+    if (hMyFile != hFile)
+        supR3HardenedWinVerifyCacheInsert(&uBuf.UniStr, hMyFile, rc, fCacheable, fForceCacheable);
+
+    *pfCallRealApi = true;
+    return STATUS_SUCCESS;
+}
+
+
+/**
+ * Preloads a file into the verify cache if possible.
+ *
+ * This is used to avoid known cyclic LoadLibrary issues with WinVerifyTrust.
+ *
+ * @param   pwszName            The name of the DLL to verify.
+ */
+DECLHIDDEN(void) supR3HardenedWinVerifyCachePreload(PCRTUTF16 pwszName)
+{
+    HANDLE              hFile = RTNT_INVALID_HANDLE_VALUE;
+    IO_STATUS_BLOCK     Ios   = RTNT_IO_STATUS_BLOCK_INITIALIZER;
+
+    UNICODE_STRING      UniStr;
+    UniStr.Buffer = (PWCHAR)pwszName;
+    UniStr.Length = (USHORT)(RTUtf16Len(pwszName) * sizeof(WCHAR));
+    UniStr.MaximumLength = UniStr.Length + sizeof(WCHAR);
+
+    OBJECT_ATTRIBUTES   ObjAttr;
+    InitializeObjectAttributes(&ObjAttr, &UniStr, OBJ_CASE_INSENSITIVE, NULL /*hRootDir*/, NULL /*pSecDesc*/);
+
+    NTSTATUS rcNt = NtCreateFile(&hFile,
+                                 FILE_READ_DATA | READ_CONTROL | SYNCHRONIZE,
+                                 &ObjAttr,
+                                 &Ios,
+                                 NULL /* Allocation Size*/,
+                                 FILE_ATTRIBUTE_NORMAL,
+                                 FILE_SHARE_READ,
+                                 FILE_OPEN,
+                                 FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
+                                 NULL /*EaBuffer*/,
+                                 0 /*EaLength*/);
+    if (NT_SUCCESS(rcNt))
+        rcNt = Ios.Status;
+    if (!NT_SUCCESS(rcNt))
+    {
+        SUP_DPRINTF(("supR3HardenedWinPreScreenImage: Error %#x opening '%ls'.\n", rcNt, pwszName));
+        return;
+    }
+
+    ULONG fAccess = 0;
+    ULONG fProtect = 0;
+    bool  fCallRealApi;
+    //SUP_DPRINTF(("supR3HardenedWinVerifyCachePreload: scanning %ls\n", pwszName));
+    supR3HardenedScreenImage(hFile, false, &fAccess, &fProtect, &fCallRealApi, true /* fForceCacheable */);
+    //SUP_DPRINTF(("supR3HardenedWinVerifyCachePreload: done %ls\n", pwszName));
+
+    NtClose(hFile);
+}
+
+
+
 /**
  * Hook that monitors NtCreateSection calls.
@@ -643,219 +930,13 @@
         if (fImage || fExecMap || fExecProt)
         {
-            /*
-             * Query the name of the file, making sure to zero terminator the
-             * string. (2nd half of buffer is used for error info, see below.)
-             */
-            union
-            {
-                UNICODE_STRING UniStr;
-                uint8_t abBuffer[sizeof(UNICODE_STRING) + 2048 * sizeof(WCHAR)];
-            } uBuf;
-            RT_ZERO(uBuf);
-            ULONG cbNameBuf;
-            NTSTATUS rcNt = NtQueryObject(hFile, ObjectNameInformation, &uBuf, sizeof(uBuf) - sizeof(WCHAR) - 128, &cbNameBuf);
+            bool fCallRealApi;
+            //SUP_DPRINTF(("supR3HardenedMonitor_NtCreateSection: 1\n"));
+            NTSTATUS rcNt = supR3HardenedScreenImage(hFile, fImage, &fAccess, &fProtect, &fCallRealApi, false /*fForceCacheable*/);
+            //SUP_DPRINTF(("supR3HardenedMonitor_NtCreateSection: 2 rcNt=%#x fCallRealApi=%#x\n", rcNt, fCallRealApi));
             if (!NT_SUCCESS(rcNt))
-            {
-                supR3HardenedError(VINF_SUCCESS, false,
-                                   "NtCreateSection: NtQueryObject -> %#x (fImage=%d fExecMap=%d fExecProt=%d)\n",
-                                   fImage, fExecMap, fExecProt);
                 return rcNt;
-            }
-
-            if (supR3HardenedWinIsPossible8dot3Path(uBuf.UniStr.Buffer))
-            {
-                uBuf.UniStr.MaximumLength = sizeof(uBuf) - 128;
-                supR3HardenedWinFix8dot3Path(hFile, &uBuf.UniStr);
-            }
-
-            /*
-             * Check the cache.
-             */
-            PVERIFIERCACHEENTRY pCacheHit = supR3HardenedWinVerifyCacheLookup(&uBuf.UniStr, hFile);
-            if (pCacheHit)
-            {
-                SUP_DPRINTF(("NtCreateSection: cache hit (%Rrc) on %ls\n", pCacheHit->rc, pCacheHit->wszPath));
-                if (RT_SUCCESS(pCacheHit->rc))
-                    return g_pfnNtCreateSectionReal(phSection, fAccess, pObjAttribs, pcbSection, fProtect, fAttribs, hFile);
-                supR3HardenedError(VINF_SUCCESS, false,
-                                   "NtCreateSection: cached rc=%Rrc fImage=%d fExecMap=%d fExecProt=%d %ls\n",
-                                   pCacheHit->rc, fImage, fExecMap, fExecProt, uBuf.UniStr.Buffer);
+            Assert(fCallRealApi);
+            if (!fCallRealApi)
                 return STATUS_TRUST_FAILURE;
-            }
-
-            /*
-             * On XP the loader might hand us handles with just FILE_EXECUTE and
-             * SYNCHRONIZE, the means reading will fail later on.  Also, we need
-             * READ_CONTROL access to check the file ownership later on, and non
-             * of the OS versions seems be giving us that.  So, in effect we
-             * more or less always reopen the file here.
-             */
-            HANDLE hMyFile = NULL;
-            rcNt = NtDuplicateObject(NtCurrentProcess(), hFile, NtCurrentProcess(),
-                                     &hMyFile,
-                                     FILE_READ_DATA | READ_CONTROL | SYNCHRONIZE,
-                                     0 /* Handle attributes*/, 0 /* Options */);
-            if (!NT_SUCCESS(rcNt))
-            {
-                if (rcNt == STATUS_ACCESS_DENIED)
-                {
-                    IO_STATUS_BLOCK     Ios   = RTNT_IO_STATUS_BLOCK_INITIALIZER;
-                    OBJECT_ATTRIBUTES   ObjAttr;
-                    InitializeObjectAttributes(&ObjAttr, &uBuf.UniStr, OBJ_CASE_INSENSITIVE, NULL /*hRootDir*/, NULL /*pSecDesc*/);
-
-                    rcNt = NtCreateFile(&hMyFile,
-                                        FILE_READ_DATA | READ_CONTROL | SYNCHRONIZE,
-                                        &ObjAttr,
-                                        &Ios,
-                                        NULL /* Allocation Size*/,
-                                        FILE_ATTRIBUTE_NORMAL,
-                                        FILE_SHARE_READ,
-                                        FILE_OPEN,
-                                        FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
-                                        NULL /*EaBuffer*/,
-                                        0 /*EaLength*/);
-                    if (NT_SUCCESS(rcNt))
-                        rcNt = Ios.Status;
-                    if (!NT_SUCCESS(rcNt))
-                    {
-                        supR3HardenedError(VINF_SUCCESS, false,
-                                           "NtCreateSection: Failed to duplicate and open the file: rcNt=%#x hFile=%p %ls\n",
-                                           rcNt, hFile, uBuf.UniStr.Buffer);
-                        return rcNt;
-                    }
-
-                    /* Check that we've got the same file. */
-                    LARGE_INTEGER idMyFile, idInFile;
-                    bool fMyValid = supR3HardenedWinVerifyCacheGetIndexNumber(hMyFile, &idMyFile);
-                    bool fInValid = supR3HardenedWinVerifyCacheGetIndexNumber(hFile, &idInFile);
-                    if (   fMyValid
-                        && (   fMyValid != fInValid
-                            || idMyFile.QuadPart != idInFile.QuadPart))
-                    {
-                        supR3HardenedError(VINF_SUCCESS, false,
-                                           "NtCreateSection: Re-opened has different ID that input: %#llx vx %#llx (%ls)\n",
-                                           rcNt, idMyFile.QuadPart, idInFile.QuadPart, uBuf.UniStr.Buffer);
-                        NtClose(hMyFile);
-                        return STATUS_TRUST_FAILURE;
-                    }
-                }
-                else
-                {
-                    SUP_DPRINTF(("supR3HardenedMonitor_NtCreateSection: NtDuplicateObject -> %#x\n", rcNt));
-#ifdef DEBUG
-
-                    supR3HardenedError(VINF_SUCCESS, false, "supR3HardenedMonitor_NtCreateSection: NtDuplicateObject(,%#x,) failed: %#x\n", hFile, rcNt);
-#endif
-                    hMyFile = hFile;
-                }
-            }
-
-            /*
-             * Special Kludge for Windows XP and W2K3 and their stupid attempts
-             * at mapping a hidden XML file called c:\Windows\WindowsShell.Manifest
-             * with executable access.  The image bit isn't set, fortunately.
-             */
-            if (   !fImage
-                && uBuf.UniStr.Length > g_System32NtPath.UniStr.Length - sizeof(L"System32") + sizeof(WCHAR)
-                && memcmp(uBuf.UniStr.Buffer, g_System32NtPath.UniStr.Buffer,
-                          g_System32NtPath.UniStr.Length - sizeof(L"System32") + sizeof(WCHAR)) == 0)
-            {
-                PRTUTF16 pwszName = &uBuf.UniStr.Buffer[(g_System32NtPath.UniStr.Length - sizeof(L"System32") + sizeof(WCHAR)) / sizeof(WCHAR)];
-                if (RTUtf16ICmpAscii(pwszName, "WindowsShell.Manifest") == 0)
-                {
-                    /*
-                     * Drop all executable access to the mapping and let it continue.
-                     */
-                    SUP_DPRINTF(("supR3HardenedMonitor_NtCreateSection: Applying the drop-exec-kludge for '%ls'\n", uBuf.UniStr.Buffer));
-                    if (fAccess & SECTION_MAP_EXECUTE)
-                        fAccess = (fAccess & ~SECTION_MAP_EXECUTE) | SECTION_MAP_READ;
-                    if (fProtect & PAGE_EXECUTE)
-                        fProtect = (fProtect & ~PAGE_EXECUTE) | PAGE_READONLY;
-                    fProtect = (fProtect & ~UINT32_C(0xf0)) | ((fProtect & UINT32_C(0xe0)) >> 4);
-                    if (hMyFile != hFile)
-                        NtClose(hMyFile);
-                    return g_pfnNtCreateSectionReal(phSection, fAccess, pObjAttribs, pcbSection, fProtect, fAttribs, hFile);
-                }
-            }
-
-            /*
-             * Check the path.  We don't allow DLLs to be loaded from just anywhere:
-             *      1. System32      - normal code or cat signing, owner TrustedInstaller.
-             *      2. WinSxS        - normal code or cat signing, owner TrustedInstaller.
-             *      3. VirtualBox    - kernel code signing and integrity checks.
-             *      4. AppPatchDir   - normal code or cat signing, owner TrustedInstaller.
-             *      5. Program Files - normal code or cat signing, owner TrustedInstaller.
-             *      6. Common Files  - normal code or cat signing, owner TrustedInstaller.
-             *      7. x86 variations of 4 & 5 - ditto.
-             */
-            bool fSystem32 = false;
-            Assert(g_SupLibHardenedExeNtPath.UniStr.Buffer[g_offSupLibHardenedExeNtName - 1] == '\\');
-            uint32_t fFlags = 0;
-            if (supHardViUniStrPathStartsWithUniStr(&uBuf.UniStr, &g_System32NtPath.UniStr, true /*fCheckSlash*/))
-            {
-                fSystem32 = true;
-                fFlags |= SUPHNTVI_F_ALLOW_CAT_FILE_VERIFICATION | SUPHNTVI_F_TRUSTED_INSTALLER_OWNER;
-            }
-            else if (supHardViUniStrPathStartsWithUniStr(&uBuf.UniStr, &g_WinSxSNtPath.UniStr, true /*fCheckSlash*/))
-                fFlags |= SUPHNTVI_F_ALLOW_CAT_FILE_VERIFICATION | SUPHNTVI_F_TRUSTED_INSTALLER_OWNER;
-            else if (supHardViUtf16PathStartsWithEx(uBuf.UniStr.Buffer, uBuf.UniStr.Length / sizeof(WCHAR),
-                                                    g_SupLibHardenedExeNtPath.UniStr.Buffer,
-                                                    g_offSupLibHardenedExeNtName, false /*fCheckSlash*/))
-                fFlags |= SUPHNTVI_F_REQUIRE_KERNEL_CODE_SIGNING | SUPHNTVI_F_REQUIRE_SIGNATURE_ENFORCEMENT;
-#ifdef VBOX_PERMIT_MORE
-            else if (supHardViIsAppPatchDir(uBuf.UniStr.Buffer, uBuf.UniStr.Length / sizeof(WCHAR)))
-                fFlags |= SUPHNTVI_F_ALLOW_CAT_FILE_VERIFICATION | SUPHNTVI_F_TRUSTED_INSTALLER_OWNER;
-            else if (supHardViUniStrPathStartsWithUniStr(&uBuf.UniStr, &g_ProgramFilesNtPath.UniStr, true /*fCheckSlash*/))
-                fFlags |= SUPHNTVI_F_ALLOW_CAT_FILE_VERIFICATION | SUPHNTVI_F_TRUSTED_INSTALLER_OWNER;
-            else if (supHardViUniStrPathStartsWithUniStr(&uBuf.UniStr, &g_CommonFilesNtPath.UniStr, true /*fCheckSlash*/))
-                fFlags |= SUPHNTVI_F_ALLOW_CAT_FILE_VERIFICATION | SUPHNTVI_F_TRUSTED_INSTALLER_OWNER;
-# ifdef RT_ARCH_AMD64
-            else if (supHardViUniStrPathStartsWithUniStr(&uBuf.UniStr, &g_ProgramFilesX86NtPath.UniStr, true /*fCheckSlash*/))
-                fFlags |= SUPHNTVI_F_ALLOW_CAT_FILE_VERIFICATION | SUPHNTVI_F_TRUSTED_INSTALLER_OWNER;
-            else if (supHardViUniStrPathStartsWithUniStr(&uBuf.UniStr, &g_CommonFilesX86NtPath.UniStr, true /*fCheckSlash*/))
-                fFlags |= SUPHNTVI_F_ALLOW_CAT_FILE_VERIFICATION | SUPHNTVI_F_TRUSTED_INSTALLER_OWNER;
-# endif
-#endif
-#ifdef VBOX_PERMIT_VISUAL_STUDIO_PROFILING
-            /* Hack to allow profiling our code with Visual Studio. */
-            else if (   uBuf.UniStr.Length > sizeof(L"\\SamplingRuntime.dll")
-                     && memcmp(uBuf.UniStr.Buffer + (uBuf.UniStr.Length - sizeof(L"\\SamplingRuntime.dll") + sizeof(WCHAR)) / sizeof(WCHAR),
-                               L"\\SamplingRuntime.dll", sizeof(L"\\SamplingRuntime.dll") - sizeof(WCHAR)) == 0 )
-            {
-                if (hMyFile != hFile)
-                    NtClose(hMyFile);
-                return g_pfnNtCreateSectionReal(phSection, fAccess, pObjAttribs, pcbSection, fProtect, fAttribs, hFile);
-            }
-#endif
-            else
-            {
-                supR3HardenedError(VINF_SUCCESS, false,
-                                   "supR3HardenedMonitor_NtCreateSection: Not a trusted location: '%ls' (fImage=%d fExecMap=%d fExecProt=%d)",
-                                    uBuf.UniStr.Buffer, fImage, fExecMap, fExecProt);
-                if (hMyFile != hFile)
-                    NtClose(hMyFile);
-                return STATUS_TRUST_FAILURE;
-            }
-
-            /*
-             * Do the verification. For better error message we borrow what's
-             * left of the path buffer for an RTERRINFO buffer.
-             */
-            RTERRINFO ErrInfo;
-            RTErrInfoInit(&ErrInfo, (char *)&uBuf.abBuffer[cbNameBuf], sizeof(uBuf) - cbNameBuf);
-
-            bool fCacheable = true;
-            int rc = supHardenedWinVerifyImageByHandle(hMyFile, uBuf.UniStr.Buffer, fFlags, &fCacheable, &ErrInfo);
-            if (RT_FAILURE(rc))
-            {
-                supR3HardenedError(VINF_SUCCESS, false,
-                                   "supR3HardenedMonitor_NtCreateSection: rc=%Rrc fImage=%d fExecMap=%d fExecProt=%d %ls: %s\n",
-                                   rc, fImage, fExecMap, fExecProt, uBuf.UniStr.Buffer, ErrInfo.pszMsg);
-                if (hMyFile != hFile)
-                    NtClose(hMyFile);
-                return STATUS_TRUST_FAILURE;
-            }
-            if (hMyFile != hFile)
-                supR3HardenedWinVerifyCacheInsert(&uBuf.UniStr, hMyFile, rc, fCacheable);
         }
     }
Index: trunk/src/VBox/HostDrivers/Support/win/SUPR3HardenedMainImports-win.cpp
===================================================================
--- trunk/src/VBox/HostDrivers/Support/win/SUPR3HardenedMainImports-win.cpp	(revision 52374)
+++ trunk/src/VBox/HostDrivers/Support/win/SUPR3HardenedMainImports-win.cpp	(revision 52375)
@@ -597,4 +597,8 @@
                                 "%ls: supHardNtLdrCacheOpen failed: %Rrc '%s'.", g_aSupNtImpDlls[iDll].pwszName, rc);
         }
+
+#if 0 /* Win7/32 ntdll!LdrpDebugFlags. */
+    *(uint8_t *)&g_aSupNtImpDlls[0].pbImageBase[0xdd770] = 0x3;
+#endif
 }
 
