Index: /trunk/include/VBox/err.h
===================================================================
--- /trunk/include/VBox/err.h	(revision 52961)
+++ /trunk/include/VBox/err.h	(revision 52962)
@@ -2513,4 +2513,16 @@
 /** The image is outside the expected range. */
 #define VERR_SUP_VP_IMAGE_TOO_BIG                   (-5668)
+/** Stub process not found so it cannot be revalidated when vboxdrv is opened
+ * by the VM process. */
+#define VERR_SUP_VP_STUB_NOT_FOUND                  (-5669)
+/** Error openeing the stub process for revalidation when vboxdrv is opened by
+ *  the VM process. */
+#define VERR_SUP_VP_STUB_OPEN_ERROR                 (-5670)
+/** Stub process thread not found during revalidation upon vboxdrv opening by
+ * the VM process. */
+#define VERR_SUP_VP_STUB_THREAD_NOT_FOUND           (-5671)
+/** Error opening the stub process thread for revalidation when vboxdrv is
+ * opened by the VM process. */
+#define VERR_SUP_VP_STUB_THREAD_OPEN_ERROR          (-5672)
 
 /** @} */
Index: /trunk/src/VBox/HostDrivers/Support/SUPLibInternal.h
===================================================================
--- /trunk/src/VBox/HostDrivers/Support/SUPLibInternal.h	(revision 52961)
+++ /trunk/src/VBox/HostDrivers/Support/SUPLibInternal.h	(revision 52962)
@@ -450,5 +450,4 @@
 DECLHIDDEN(void)    supR3HardenedWinInitImportsEarly(uintptr_t uNtDllAddr);
 DECLHIDDEN(PFNRT)   supR3HardenedWinGetRealDllSymbol(const char *pszDll, const char *pszProcedure);
-DECLHIDDEN(void)    supR3HardenedWinVerifyProcess(void);
 DECLHIDDEN(void)    supR3HardenedWinEnableThreadCreation(void);
 DECLHIDDEN(void)    supR3HardenedWinResolveVerifyTrustApiAndHookThreadCreation(const char *pszProgName);
@@ -466,5 +465,6 @@
 DECLHIDDEN(void)    supR3HardenedWinCompactHeaps(void);
 DECLHIDDEN(void)    supR3HardenedMainOpenDevice(void);
-DECLHIDDEN(void)    supR3HardenedWinReportErrorToParent(int rc, const char *pszFormat, va_list va);
+DECLHIDDEN(void)    supR3HardenedWinReportErrorToParent(const char *pszWhere, SUPINITOP enmWhat, int rc,
+                                                        const char *pszFormat, va_list va);
 #endif
 
Index: /trunk/src/VBox/HostDrivers/Support/SUPR3HardenedMain.cpp
===================================================================
--- /trunk/src/VBox/HostDrivers/Support/SUPR3HardenedMain.cpp	(revision 52961)
+++ /trunk/src/VBox/HostDrivers/Support/SUPR3HardenedMain.cpp	(revision 52962)
@@ -1143,5 +1143,5 @@
     else if (   g_enmSupR3HardenedMainState < SUPR3HARDENEDMAINSTATE_WIN_IMPORTS_RESOLVED
              && g_enmSupR3HardenedMainState != SUPR3HARDENEDMAINSTATE_NOT_YET_CALLED)
-        supR3HardenedWinReportErrorToParent(rc, pszMsgFmt, va);
+        supR3HardenedWinReportErrorToParent(pszWhere, enmWhat, rc, pszMsgFmt, va);
 #endif
 
@@ -1176,5 +1176,5 @@
     if (   g_enmSupR3HardenedMainState < SUPR3HARDENEDMAINSTATE_WIN_IMPORTS_RESOLVED
         && g_enmSupR3HardenedMainState != SUPR3HARDENEDMAINSTATE_NOT_YET_CALLED)
-        supR3HardenedWinReportErrorToParent(VERR_INTERNAL_ERROR, pszFormat, va);
+        supR3HardenedWinReportErrorToParent(NULL, kSupInitOp_Invalid, VERR_INTERNAL_ERROR, pszFormat, va);
     else
 #endif
@@ -1781,10 +1781,4 @@
 #ifdef RT_OS_WINDOWS
         /*
-         * Windows: Verify the process (repeated by the kernel later).
-         */
-        if (!g_fSupEarlyProcessInit)
-            supR3HardenedWinVerifyProcess();
-
-        /*
          * Windows: The second respawn.  This time we make a special arrangement
          * with vboxdrv to monitor access to the new process from its inception.
@@ -1797,13 +1791,11 @@
         SUP_DPRINTF(("SUPR3HardenedMain: Final process, opening VBoxDrv...\n"));
         supR3HardenedWinFlushLoaderCache();
-#endif /* RT_OS_WINDOWS */
-
+
+#else
         /*
          * Open the vboxdrv device.
          */
-#ifdef RT_OS_WINDOWS
-        if (!g_fSupEarlyProcessInit)
-#endif
-            supR3HardenedMainOpenDevice();
+        supR3HardenedMainOpenDevice();
+#endif /* !RT_OS_WINDOWS */
     }
 
Index: /trunk/src/VBox/HostDrivers/Support/win/SUPDrv-win.cpp
===================================================================
--- /trunk/src/VBox/HostDrivers/Support/win/SUPDrv-win.cpp	(revision 52961)
+++ /trunk/src/VBox/HostDrivers/Support/win/SUPDrv-win.cpp	(revision 52962)
@@ -187,4 +187,6 @@
     /** The parent PID for VM processes, otherwise NULL. */
     HANDLE              hParentPid;
+    /** The TID of the thread opening VBoxDrv or VBoxDrvStub, NULL if not opened. */
+    HANDLE              hOpenTid;
     /** The PID of the CSRSS process associated with this process. */
     HANDLE              hCsrssPid;
@@ -200,5 +202,5 @@
         /** A process in the VmProcessUnconfirmed state will keep a weak
          * reference to the parent's protection structure so it can clean up the pChild
-         * refernece the parent has to it. */
+         * reference the parent has to it. */
         struct SUPDRVNTPROTECT *pParent;
     } u;
@@ -3401,4 +3403,5 @@
     pNtProtect->enmProcessKind               = enmProcessKind;
     pNtProtect->hParentPid                   = NULL;
+    pNtProtect->hOpenTid                     = NULL;
     pNtProtect->hCsrssPid                    = NULL;
     pNtProtect->pCsrssProcess                = NULL;
@@ -3502,4 +3505,103 @@
     RTSpinlockRelease(g_hNtProtectLock);
     return pFound;
+}
+
+
+/**
+ * Validates a few facts about the stub process when the VM process opens
+ * vboxdrv.
+ *
+ * This makes sure the stub process is still around and that it has neither
+ * debugger nor extra threads in it.
+ *
+ * @returns VBox status code.
+ * @param   pNtProtect          The unconfirmed VM process currently trying to
+ *                              open vboxdrv.
+ * @param   pErrInfo            Additional error information.
+ */
+static int supdrvNtProtectVerifyStubForVmProcess(PSUPDRVNTPROTECT pNtProtect, PRTERRINFO pErrInfo)
+{
+    /*
+     * Grab a reference to the parent stub process.
+     */
+    SUPDRVNTPROTECTKIND enmStub = kSupDrvNtProtectKind_Invalid;
+    PSUPDRVNTPROTECT    pNtStub = NULL;
+    RTSpinlockAcquire(g_hNtProtectLock);
+    if (pNtProtect->enmProcessKind == kSupDrvNtProtectKind_VmProcessUnconfirmed)
+    {
+        pNtStub = pNtProtect->u.pParent; /* weak reference. */
+        if (pNtStub)
+        {
+            enmStub = pNtStub->enmProcessKind;
+            if (enmStub == kSupDrvNtProtectKind_StubParent)
+            {
+                uint32_t cRefs = ASMAtomicIncU32(&pNtStub->cRefs);
+                Assert(cRefs > 0 && cRefs < 1024);
+            }
+            else
+                pNtStub = NULL;
+        }
+    }
+    RTSpinlockRelease(g_hNtProtectLock);
+
+    /*
+     * We require the stub process to be present.
+     */
+    if (!pNtStub)
+        return RTErrInfoSetF(pErrInfo, VERR_SUP_VP_STUB_NOT_FOUND, "Missing stub process (enmStub=%d).", enmStub);
+
+    /*
+     * Open the parent process and thread so we can check for debuggers and unwanted threads.
+     */
+    int rc;
+    PEPROCESS pStubProcess;
+    NTSTATUS rcNt = PsLookupProcessByProcessId(pNtStub->AvlCore.Key, &pStubProcess);
+    if (NT_SUCCESS(rcNt))
+    {
+        HANDLE hStubProcess;
+        rcNt = ObOpenObjectByPointer(pStubProcess, OBJ_KERNEL_HANDLE, NULL /*PassedAccessState*/,
+                                     0 /*DesiredAccess*/, *PsProcessType, KernelMode, &hStubProcess);
+        if (NT_SUCCESS(rcNt))
+        {
+            PETHREAD pStubThread;
+            rcNt = PsLookupThreadByThreadId(pNtStub->hOpenTid, &pStubThread);
+            if (NT_SUCCESS(rcNt))
+            {
+                HANDLE hStubThread;
+                rcNt = ObOpenObjectByPointer(pStubThread, OBJ_KERNEL_HANDLE, NULL /*PassedAccessState*/,
+                                             0 /*DesiredAccess*/, *PsThreadType, KernelMode, &hStubThread);
+                if (NT_SUCCESS(rcNt))
+                {
+                    /*
+                     * Do some simple sanity checking.
+                     */
+                    rc = supHardNtVpDebugger(hStubProcess, pErrInfo);
+                    if (RT_SUCCESS(rc))
+                        rc = supHardNtVpThread(hStubProcess, hStubThread, pErrInfo);
+
+                    /* Clean up. */
+                    rcNt = NtClose(hStubThread); AssertMsg(NT_SUCCESS(rcNt), ("%#x\n", rcNt));
+                }
+                else
+                    rc = RTErrInfoSetF(pErrInfo, VERR_SUP_VP_STUB_THREAD_OPEN_ERROR,
+                                       "Error opening stub thread %p (tid %p, pid %p): %#x",
+                                       pStubThread, pNtStub->hOpenTid, pNtStub->AvlCore.Key, rcNt);
+            }
+            else
+                rc = RTErrInfoSetF(pErrInfo, VERR_SUP_VP_STUB_THREAD_NOT_FOUND,
+                                   "Failed to locate thread %p in %p: %#x", pNtStub->hOpenTid, pNtStub->AvlCore.Key, rcNt);
+            rcNt = NtClose(hStubProcess); AssertMsg(NT_SUCCESS(rcNt), ("%#x\n", rcNt));
+        }
+        else
+            rc = RTErrInfoSetF(pErrInfo, VERR_SUP_VP_STUB_OPEN_ERROR,
+                               "Error opening stub process %p (pid %p): %#x", pStubProcess, pNtStub->AvlCore.Key, rcNt);
+        ObDereferenceObject(pStubProcess);
+    }
+    else
+        rc = RTErrInfoSetF(pErrInfo, VERR_SUP_VP_STUB_NOT_FOUND,
+                           "Failed to locate stub process %p: %#x", pNtStub->AvlCore.Key, rcNt);
+
+    supdrvNtProtectRelease(pNtStub);
+    return rc;
 }
 
@@ -3698,4 +3800,6 @@
         rc = supHardenedWinVerifyProcess(NtCurrentProcess(), NtCurrentThread(), SUPHARDNTVPKIND_VERIFY_ONLY,
                                          NULL /*pcFixes*/, &ErrInfo);
+        if (RT_SUCCESS(rc) && pNtProtect->enmProcessKind >= kSupDrvNtProtectKind_VmProcessUnconfirmed)
+            rc = supdrvNtProtectVerifyStubForVmProcess(pNtProtect, &ErrInfo);
         if (RT_FAILURE(rc))
             RTLogWriteDebugger(szErr, strlen(szErr));
@@ -3705,10 +3809,13 @@
      * Upgrade and return.
      */
+    HANDLE hOpenTid = PsGetCurrentThreadId();
     RTSpinlockAcquire(g_hNtProtectLock);
 
     /* Stub process verficiation is pretty much straight forward. */
     if (pNtProtect->enmProcessKind == kSupDrvNtProtectKind_StubUnverified)
+    {
         pNtProtect->enmProcessKind = RT_SUCCESS(rc) ? kSupDrvNtProtectKind_StubSpawning : kSupDrvNtProtectKind_StubDead;
-
+        pNtProtect->hOpenTid       = hOpenTid;
+    }
     /* The VM process verification is a little bit more complicated
        because we need to drop the parent process reference as well. */
@@ -3726,5 +3833,8 @@
 
         if (RT_SUCCESS(rc))
+        {
             pNtProtect->enmProcessKind = kSupDrvNtProtectKind_VmProcessConfirmed;
+            pNtProtect->hOpenTid       = hOpenTid;
+        }
         else
             pNtProtect->enmProcessKind = kSupDrvNtProtectKind_VmProcessDead;
Index: /trunk/src/VBox/HostDrivers/Support/win/SUPHardenedVerifyProcess-win.cpp
===================================================================
--- /trunk/src/VBox/HostDrivers/Support/win/SUPHardenedVerifyProcess-win.cpp	(revision 52961)
+++ /trunk/src/VBox/HostDrivers/Support/win/SUPHardenedVerifyProcess-win.cpp	(revision 52962)
@@ -953,9 +953,12 @@
             }
 
-            /* The section bits, only child purification verifies all bits . */
-            if (   pThis->enmKind == SUPHARDNTVPKIND_CHILD_PURIFICATION
-                || (   (pThis->aSecHdrs[i].Characteristics & (IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_CNT_CODE))
+            /* The section bits. Child purification verifies all, normal
+               verification verifies all except where the executable is
+               concerned (due to opening vboxdrv during early process init). */
+            if (   (   (pThis->aSecHdrs[i].Characteristics & (IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_CNT_CODE))
                     && !(pThis->aSecHdrs[i].Characteristics & IMAGE_SCN_MEM_WRITE))
-                || (pThis->aSecHdrs[i].Characteristics & (IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE)) == IMAGE_SCN_MEM_READ)
+                || (pThis->aSecHdrs[i].Characteristics & (IMAGE_SCN_MEM_READ | IMAGE_SCN_MEM_WRITE)) == IMAGE_SCN_MEM_READ
+                || (pThis->enmKind == SUPHARDNTVPKIND_VERIFY_ONLY && pImage->fDll)
+                || pThis->enmKind == SUPHARDNTVPKIND_CHILD_PURIFICATION)
             {
                 rc = VINF_SUCCESS;
Index: /trunk/src/VBox/HostDrivers/Support/win/SUPR3HardenedMain-win.cpp
===================================================================
--- /trunk/src/VBox/HostDrivers/Support/win/SUPR3HardenedMain-win.cpp	(revision 52961)
+++ /trunk/src/VBox/HostDrivers/Support/win/SUPR3HardenedMain-win.cpp	(revision 52962)
@@ -189,4 +189,9 @@
     /** The last status. */
     int32_t         rc;
+    /** The init operation the error relates to if message, kSupInitOp_Invalid if
+     *  not message. */
+    SUPINITOP       enmWhat;
+    /** Where if message. */
+    char            szWhere[80];
     /** Error message / path name string space. */
     char            szErrorMsg[4096];
@@ -2785,18 +2790,4 @@
 
 /**
- * Verifies the process integrity.
- */
-DECLHIDDEN(void) supR3HardenedWinVerifyProcess(void)
-{
-    RTErrInfoInitStatic(&g_ErrInfoStatic);
-    int rc = supHardenedWinVerifyProcess(NtCurrentProcess(), NtCurrentThread(),
-                                         SUPHARDNTVPKIND_VERIFY_ONLY, NULL /*pcFixes*/, &g_ErrInfoStatic.Core);
-    if (RT_FAILURE(rc))
-        supR3HardenedFatalMsg("supR3HardenedWinVerifyProcess", kSupInitOp_Integrity, rc,
-                              "Failed to verify process integrity: %s", g_ErrInfoStatic.szMsg);
-}
-
-
-/**
  * Gets the SID of the user associated with the process.
  *
@@ -3903,5 +3894,14 @@
     /* An error occurred, report it. */
     ChildProcParams.szErrorMsg[sizeof(ChildProcParams.szErrorMsg) - 1] = '\0';
-    supR3HardenedFatalMsg("supR3HardenedWinCheckChild", kSupInitOp_Misc, ChildProcParams.rc, "%s", ChildProcParams.szErrorMsg);
+    ChildProcParams.szWhere[sizeof(ChildProcParams.szWhere) - 1] = '\0';
+    SUP_DPRINTF(("supR3HardenedWinCheckChild: rc=%d enmWhat=%d %s: %s\n",
+                 ChildProcParams.rc, ChildProcParams.enmWhat, ChildProcParams.szWhere, ChildProcParams.szErrorMsg));
+
+    if (ChildProcParams.enmWhat == kSupInitOp_Invalid)
+        supR3HardenedFatalMsg("supR3HardenedWinCheckChild", kSupInitOp_Misc, ChildProcParams.rc,
+                              "%s", ChildProcParams.szErrorMsg);
+    else
+        supR3HardenedFatalMsg(ChildProcParams.szWhere, ChildProcParams.enmWhat, ChildProcParams.rc,
+                              "%s", ChildProcParams.szErrorMsg);
 }
 
@@ -5545,12 +5545,22 @@
  * Reports an error to the parent process via the process parameter structure.
  *
+ * @param   pszWhere            Where this error occured, if fatal message. NULL
+ *                              if not message.
+ * @param   enmWhat             Which init operation went wrong if fatal
+ *                              message. kSupInitOp_Invalid if not message.
  * @param   rc                  The status code to report.
  * @param   pszFormat           The format string.
  * @param   va                  The format arguments.
  */
-DECLHIDDEN(void) supR3HardenedWinReportErrorToParent(int rc, const char *pszFormat, va_list va)
-{
+DECLHIDDEN(void) supR3HardenedWinReportErrorToParent(const char *pszWhere, SUPINITOP enmWhat, int rc,
+                                                     const char *pszFormat, va_list va)
+{
+    if (pszWhere)
+        RTStrCopy(g_ProcParams.szWhere, sizeof(g_ProcParams.szWhere), pszWhere);
+    else
+        g_ProcParams.szWhere[0] = '\0';
     RTStrPrintfV(g_ProcParams.szErrorMsg, sizeof(g_ProcParams.szErrorMsg), pszFormat, va);
-    g_ProcParams.rc = RT_SUCCESS(rc) ? VERR_INTERNAL_ERROR_2 : rc;
+    g_ProcParams.enmWhat = enmWhat;
+    g_ProcParams.rc      = RT_SUCCESS(rc) ? VERR_INTERNAL_ERROR_2 : rc;
 
     NTSTATUS rcNt = NtSetEvent(g_ProcParams.hEvtParent, NULL);
