Index: trunk/src/VBox/HostDrivers/Support/win/SUPDrv-win.cpp
===================================================================
--- trunk/src/VBox/HostDrivers/Support/win/SUPDrv-win.cpp	(revision 52528)
+++ trunk/src/VBox/HostDrivers/Support/win/SUPDrv-win.cpp	(revision 52529)
@@ -3493,5 +3493,6 @@
         RTErrInfoInit(&ErrInfo, szErr, sizeof(szErr));
 
-        rc = supHardenedWinVerifyProcess(NtCurrentProcess(), NtCurrentThread(), SUPHARDNTVPKIND_VERIFY_ONLY, &ErrInfo);
+        rc = supHardenedWinVerifyProcess(NtCurrentProcess(), NtCurrentThread(), SUPHARDNTVPKIND_VERIFY_ONLY,
+                                         NULL /*pcFixes*/, &ErrInfo);
         if (RT_FAILURE(rc))
             RTLogWriteDebugger(szErr, strlen(szErr));
Index: trunk/src/VBox/HostDrivers/Support/win/SUPHardenedVerify-win.h
===================================================================
--- trunk/src/VBox/HostDrivers/Support/win/SUPHardenedVerify-win.h	(revision 52528)
+++ trunk/src/VBox/HostDrivers/Support/win/SUPHardenedVerify-win.h	(revision 52529)
@@ -54,5 +54,6 @@
     SUPHARDNTVPKIND_32BIT_HACK = 0x7fffffff
 } SUPHARDNTVPKIND;
-DECLHIDDEN(int)     supHardenedWinVerifyProcess(HANDLE hProcess, HANDLE hThread, SUPHARDNTVPKIND enmKind, PRTERRINFO pErrInfo);
+DECLHIDDEN(int)     supHardenedWinVerifyProcess(HANDLE hProcess, HANDLE hThread, SUPHARDNTVPKIND enmKind,
+                                                uint32_t *pcFixes, PRTERRINFO pErrInfo);
 
 DECLHIDDEN(bool)    supHardViUniStrPathStartsWithUniStr(UNICODE_STRING const *pUniStrLeft,
Index: trunk/src/VBox/HostDrivers/Support/win/SUPHardenedVerifyImage-win.cpp
===================================================================
--- trunk/src/VBox/HostDrivers/Support/win/SUPHardenedVerifyImage-win.cpp	(revision 52528)
+++ trunk/src/VBox/HostDrivers/Support/win/SUPHardenedVerifyImage-win.cpp	(revision 52529)
@@ -734,4 +734,8 @@
         if (supHardViUtf16PathIsEqual(pwsz, "apphelp.dll"))
             return uNtVer < SUP_MAKE_NT_VER_SIMPLE(6, 4) ? VINF_LDRVI_NOT_SIGNED : rc;
+#ifdef VBOX_PERMIT_VERIFIER_DLL
+        if (supHardViUtf16PathIsEqual(pwsz, "verifier.dll"))
+            return uNtVer < SUP_NT_VER_W81 ? VINF_LDRVI_NOT_SIGNED : rc;
+#endif
 #ifdef VBOX_PERMIT_MORE
         if (uNtVer >= SUP_NT_VER_W70) /* hard limit: user32.dll is unwanted prior to w7. */
Index: trunk/src/VBox/HostDrivers/Support/win/SUPHardenedVerifyProcess-win.cpp
===================================================================
--- trunk/src/VBox/HostDrivers/Support/win/SUPHardenedVerifyProcess-win.cpp	(revision 52528)
+++ trunk/src/VBox/HostDrivers/Support/win/SUPHardenedVerifyProcess-win.cpp	(revision 52529)
@@ -131,4 +131,7 @@
     /** The result. */
     int                     rcResult;
+    /** Number of fixes we've done.
+     * Only applicable in the purification modes.  */
+    uint32_t                cFixes;
     /** Number of images in aImages. */
     uint32_t                cImages;
@@ -141,4 +144,7 @@
      * more so we can get the image name of the first unwanted DLL. */
     SUPHNTVPIMAGE           aImages[1 + 6 + 1
+#ifdef VBOX_PERMIT_VERIFIER_DLL
+                                    + 1
+#endif
 #ifdef VBOX_PERMIT_MORE
                                     + 5
@@ -175,4 +181,7 @@
     "apphelp.dll",
     "apisetschema.dll",
+#ifdef VBOX_PERMIT_VERIFIER_DLL
+    "verifier.dll",
+#endif
 #ifdef VBOX_PERMIT_MORE
 # define VBOX_PERMIT_MORE_FIRST_IDX 5
@@ -351,4 +360,5 @@
             rcNt = rcNt2;
     }
+    pThis->cFixes++;
     return rcNt;
 }
@@ -1220,4 +1230,5 @@
             if (NT_SUCCESS(rcNt))
                 return VINF_OBJECT_DESTROYED;
+            pThis->cFixes++;
             SUP_DPRINTF(("supHardNtVpScanVirtualMemory: NtUnmapViewOfSection(,%p) failed: %#x\n", pMemInfo->AllocationBase, rcNt));
         }
@@ -1362,5 +1373,9 @@
     uintptr_t   cbAdvance = 0;
     uintptr_t   uPtrWhere = 0;
+#ifdef VBOX_PERMIT_VERIFIER_DLL
+    for (uint32_t i = 0; i < 10240; i++)
+#else
     for (uint32_t i = 0; i < 1024; i++)
+#endif
     {
         SIZE_T                      cbActual = 0;
@@ -1511,4 +1526,5 @@
                                         "Unknown executable memory type %#x at %p/%p LB %#zx",
                                         MemInfo.Type, MemInfo.AllocationBase, MemInfo.BaseAddress, MemInfo.RegionSize);
+                pThis->cFixes++;
             }
             else
@@ -2057,7 +2073,13 @@
  * @param   enmKind             The kind of process verification to perform.
  * @param   pErrInfo            Pointer to error info structure. Optional.
- */
-DECLHIDDEN(int) supHardenedWinVerifyProcess(HANDLE hProcess, HANDLE hThread, SUPHARDNTVPKIND enmKind, PRTERRINFO pErrInfo)
-{
+ * @param   pcFixes             Where to return the number of fixes made during
+ *                              purification.  Optional.
+ */
+DECLHIDDEN(int) supHardenedWinVerifyProcess(HANDLE hProcess, HANDLE hThread, SUPHARDNTVPKIND enmKind,
+                                            uint32_t *pcFixes, PRTERRINFO pErrInfo)
+{
+    if (pcFixes)
+        *pcFixes = 0;
+
     /*
      * Some basic checks regarding threads and debuggers. We don't need
@@ -2095,4 +2117,7 @@
                 rc = supHardNtVpCheckDlls(pThis, hProcess);
 
+            if (pcFixes)
+                *pcFixes = pThis->cFixes;
+
             /*
              * Clean up the state.
Index: trunk/src/VBox/HostDrivers/Support/win/SUPR3HardenedMain-win.cpp
===================================================================
--- trunk/src/VBox/HostDrivers/Support/win/SUPR3HardenedMain-win.cpp	(revision 52528)
+++ trunk/src/VBox/HostDrivers/Support/win/SUPR3HardenedMain-win.cpp	(revision 52529)
@@ -2414,5 +2414,5 @@
     RTErrInfoInitStatic(&g_ErrInfoStatic);
     int rc = supHardenedWinVerifyProcess(NtCurrentProcess(), NtCurrentThread(),
-                                         SUPHARDNTVPKIND_VERIFY_ONLY, &g_ErrInfoStatic.Core);
+                                         SUPHARDNTVPKIND_VERIFY_ONLY, NULL /*pcFixes*/, &g_ErrInfoStatic.Core);
     if (RT_FAILURE(rc))
         supR3HardenedFatalMsg("supR3HardenedWinVerifyProcess", kSupInitOp_Integrity, rc,
@@ -3376,5 +3376,5 @@
         rc = supR3HardNtPuChSanitizePeb(&This);
     if (RT_SUCCESS(rc))
-        rc = supHardenedWinVerifyProcess(hProcess, hThread, SUPHARDNTVPKIND_CHILD_PURIFICATION, pErrInfo);
+        rc = supHardenedWinVerifyProcess(hProcess, hThread, SUPHARDNTVPKIND_CHILD_PURIFICATION, NULL /*pcFixes*/, pErrInfo);
 
     return rc;
@@ -3928,20 +3928,33 @@
          * We have to resort to kludge doing yield and sleep fudging for a
          * number of milliseconds and schedulings before we can hope that avast
-         * and similar products have done what they need to do.  Pretty fragile...
+         * and similar products have done what they need to do.  If we do any
+         * fixes, we wait for a while again and redo it until we're clean.
+         *
+         * This is unfortunately kind of fragile.
          */
-        uint32_t    cSleeps = 0;
-        DWORD       dwStart = GetTickCount();
+        uint32_t iLoop = 0;
+        uint32_t cFixes;
         do
         {
-            NtYieldExecution();
-            LARGE_INTEGER Time;
-            Time.QuadPart = -8000000 / 100; /* 8ms in 100ns units, relative time. */
-            NtDelayExecution(FALSE, &Time);
-            cSleeps++;
-        } while (   GetTickCount() - dwStart <= 80
-                 || cSleeps < 8);
-        SUP_DPRINTF(("supR3HardenedWinInit: Startup delay kludge #2: %u ms, %u sleeps\n", GetTickCount() - dwStart, cSleeps));
-
-        supHardenedWinVerifyProcess(NtCurrentProcess(), NtCurrentThread(), SUPHARDNTVPKIND_SELF_PURIFICATION, NULL);
+            uint32_t    cSleeps = 0;
+            DWORD       dwStart = GetTickCount();
+            do
+            {
+                NtYieldExecution();
+                LARGE_INTEGER Time;
+                Time.QuadPart = -8000000 / 100; /* 8ms in 100ns units, relative time. */
+                NtDelayExecution(FALSE, &Time);
+                cSleeps++;
+            } while (   GetTickCount() - dwStart <= 80
+                     || cSleeps < 8);
+            SUP_DPRINTF(("supR3HardenedWinInit: Startup delay kludge #2/%u: %u ms, %u sleeps\n",
+                         iLoop, GetTickCount() - dwStart, cSleeps));
+
+            cFixes = 0;
+            rc = supHardenedWinVerifyProcess(NtCurrentProcess(), NtCurrentThread(), SUPHARDNTVPKIND_SELF_PURIFICATION,
+                                             &cFixes, NULL /*pErrInfo*/);
+        } while (   RT_SUCCESS(rc)
+                 && cFixes > 0
+                 && ++iLoop < 8);
 
         /*
