Index: trunk/src/VBox/HostDrivers/Support/Makefile.kmk
===================================================================
--- trunk/src/VBox/HostDrivers/Support/Makefile.kmk	(revision 106997)
+++ trunk/src/VBox/HostDrivers/Support/Makefile.kmk	(revision 106998)
@@ -134,10 +134,10 @@
 if "$(KBUILD_TARGET)" == "win" && defined(VBOX_WITH_HARDENING)
  VBOX_SUP_GEN_CERT_MACRO = 'SUPTAENTRY const g_aSUP$(1)TAs[] =' '{' \
- 	$(if-expr "$(3)" == "",,'    SUPTAENTRY_GEN(g_abSUPBuildCert),') \
- 	$(foreach certnm,$(filter $(2),$(VBOX_SUP_WIN_CERT_NAMES)), '    SUPTAENTRY_GEN(g_abSUP$(certnm)),') \
+ 	$(if-expr "$(3)" == "",,'    SUPTAENTRY_CER(g_abSUPBuildCert),') \
+ 	$(foreach certnm,$(filter $(2),$(VBOX_SUP_WIN_CERT_NAMES)), '    SUPTAENTRY_TAF(g_abSUP$(certnm)),') \
  	'};' 'unsigned const g_cSUP$(1)TAs = RT_ELEMENTS(g_aSUP$(1)TAs);' '' ''
 else
  VBOX_SUP_GEN_CERT_MACRO = 'SUPTAENTRY const g_aSUP$(1)TAs[] =' '{' \
- 	$(foreach certnm,$(filter $(2),$(VBOX_SUP_WIN_CERT_NAMES)), '    SUPTAENTRY_GEN(g_abSUP$(certnm)),') \
+ 	$(foreach certnm,$(filter $(2),$(VBOX_SUP_WIN_CERT_NAMES)), '    SUPTAENTRY_TAF(g_abSUP$(certnm)),') \
  	'};' 'unsigned const g_cSUP$(1)TAs = RT_ELEMENTS(g_aSUP$(1)TAs);' '' ''
 endif
@@ -162,4 +162,5 @@
        	'' \
        	'#include <VBox/sup.h>' \
+       	'#include <iprt/crypto/store.h>' \
                ''
 	$(foreach cert,$(VBOX_SUP_WIN_CERTS), $(NLTAB)$(VBOX_BIN2C) -ascii --append --static --no-size \
Index: trunk/src/VBox/HostDrivers/Support/win/SUPHardenedVerifyImage-win.cpp
===================================================================
--- trunk/src/VBox/HostDrivers/Support/win/SUPHardenedVerifyImage-win.cpp	(revision 106997)
+++ trunk/src/VBox/HostDrivers/Support/win/SUPHardenedVerifyImage-win.cpp	(revision 106998)
@@ -1744,48 +1744,50 @@
 
 
-static int supHardNtViCertStoreAddArray(RTCRSTORE hStore, PCSUPTAENTRY paCerts, unsigned cCerts, PRTERRINFO pErrInfo)
-{
-    for (uint32_t i = 0; i < cCerts; i++)
-    {
-        int rc = RTCrStoreCertAddEncoded(hStore, !paCerts[i].fIsCert ? RTCRCERTCTX_F_ENC_TAF_DER : RTCRCERTCTX_F_ENC_X509_DER,
-                                         paCerts[i].pch, paCerts[i].cb, pErrInfo);
-        if (RT_FAILURE(rc))
-            return rc;
-    }
-    return VINF_SUCCESS;
-}
-
-
 /**
  * Initialize a certificate table.
  *
  * @param   phStore             Where to return the store pointer.
- * @param   paCerts1            Pointer to the first certificate table.
- * @param   cCerts1             Entries in the first certificate table.
- * @param   paCerts2            Pointer to the second certificate table.
- * @param   cCerts2             Entries in the second certificate table.
- * @param   paCerts3            Pointer to the third certificate table.
- * @param   cCerts3             Entries in the third certificate table.
  * @param   pErrInfo            Where to return extended error info. Optional.
  * @param   pszErrorTag         Error tag.
- */
-static int supHardNtViCertStoreInit(PRTCRSTORE phStore,
-                                    PCSUPTAENTRY paCerts1, unsigned cCerts1,
-                                    PCSUPTAENTRY paCerts2, unsigned cCerts2,
-                                    PCSUPTAENTRY paCerts3, unsigned cCerts3,
-                                    PRTERRINFO pErrInfo, const char *pszErrorTag)
+ * @param   cTables             Number of table pairs.
+ * @param   ...                 Pairs of PCSUPTAENTRY and unsigned.
+ *
+ */
+static int supHardNtViCertStoreInit(PRTCRSTORE phStore, PRTERRINFO pErrInfo, const char *pszErrorTag, unsigned cTables, ...)
 {
     AssertReturn(*phStore == NIL_RTCRSTORE, VERR_WRONG_ORDER);
     RT_NOREF1(pszErrorTag);
 
-    int rc = RTCrStoreCreateInMem(phStore, cCerts1 + cCerts2);
+    va_list va;
+    va_start(va, cTables);
+    unsigned cTotalCerts = 0;
+    for (unsigned iTable = 0; iTable < cTables; iTable++)
+    {
+        va_arg(va, PCSUPTAENTRY);
+        cTotalCerts += va_arg(va, unsigned);
+    }
+
+    int rc = RTCrStoreCreateInMem(phStore, cTotalCerts);
     if (RT_FAILURE(rc))
         return RTErrInfoSetF(pErrInfo, rc, "RTCrStoreCreateMemoryStore failed: %Rrc", rc);
 
-    rc = supHardNtViCertStoreAddArray(*phStore, paCerts1, cCerts1, pErrInfo);
-    if (RT_SUCCESS(rc))
-        rc = supHardNtViCertStoreAddArray(*phStore, paCerts2, cCerts2, pErrInfo);
-    if (RT_SUCCESS(rc))
-        rc = supHardNtViCertStoreAddArray(*phStore, paCerts3, cCerts3, pErrInfo);
+    va_start(va, cTables);
+    for (unsigned iTable = 0; iTable < cTables; iTable++)
+    {
+        PCSUPTAENTRY const paCerts = va_arg(va, PCSUPTAENTRY);
+        unsigned     const cCerts  = va_arg(va, unsigned);
+        for (unsigned iCert = 0; iCert < cCerts; iCert++)
+        {
+            rc = RTCrStoreCertAddEncoded(*phStore, paCerts[iCert].fEnc, paCerts[iCert].pch, paCerts[iCert].cb, pErrInfo);
+            if (RT_FAILURE(rc))
+            {
+                SUP_DPRINTF(("supHardNtViCertStoreInit: %s: iTable=%u iCert=%u: fEnc=%#x cb=%#x rc=%Rrc\n",
+                             pszErrorTag, iTable, iCert, paCerts[iCert].fEnc, paCerts[iCert].cb, rc));
+                va_end(va);
+                return rc;
+            }
+        }
+    }
+    va_end(va);
     return rc;
 }
@@ -2019,39 +2021,23 @@
          */
         rc = supHardNtViCertInit(&g_BuildX509Cert, g_abSUPBuildCert, g_cbSUPBuildCert, pErrInfo, "BuildCertificate");
-        SUPTAENTRY const aBuildCerts[1] = { { g_abSUPBuildCert, g_cbSUPBuildCert, true }, };
         if (RT_SUCCESS(rc))
-            rc = supHardNtViCertStoreInit(&g_hSpecialTrustStore,
-                                          aBuildCerts, RT_ELEMENTS(aBuildCerts),
-                                          g_aSUPTrustedTAs, g_cSUPTrustedTAs,
-                                          NULL, 0,
-                                          pErrInfo, "SpecialTrustStore");
+            rc = supHardNtViCertStoreInit(&g_hSpecialTrustStore, pErrInfo, "SpecialTrustStore", 1,
+                                          g_aSUPTrustedTAs, g_cSUPTrustedTAs);
         if (RT_SUCCESS(rc))
-            rc = supHardNtViCertStoreInit(&g_hSpcRootStore, g_aSUPSpcRootTAs, g_cSUPSpcRootTAs,
-                                          NULL, 0, NULL, 0, pErrInfo, "SpcRoot");
+            rc = supHardNtViCertStoreInit(&g_hSpcRootStore, pErrInfo, "SpcRoot", 1, g_aSUPSpcRootTAs, g_cSUPSpcRootTAs);
         if (RT_SUCCESS(rc))
-            rc = supHardNtViCertStoreInit(&g_hNtKernelRootStore, g_aSUPNtKernelRootTAs, g_cSUPNtKernelRootTAs,
-                                          NULL, 0, NULL, 0, pErrInfo, "NtKernelRoot");
+            rc = supHardNtViCertStoreInit(&g_hNtKernelRootStore, pErrInfo, "NtKernelRoot", 1,
+                                          g_aSUPNtKernelRootTAs, g_cSUPNtKernelRootTAs);
         if (RT_SUCCESS(rc))
-            rc = supHardNtViCertStoreInit(&g_hSpcAndNtKernelRootStore,
+        {
+            SUPTAENTRY const aBuildCerts[] = { { g_abSUPBuildCert, g_cbSUPBuildCert, RTCRCERTCTX_F_ENC_X509_DER }, };
+            rc = supHardNtViCertStoreInit(&g_hSpcAndNtKernelRootStore, pErrInfo, "SpcAndNtKernelRoot", 4,
                                           g_aSUPSpcRootTAs, g_cSUPSpcRootTAs,
                                           g_aSUPNtKernelRootTAs, g_cSUPNtKernelRootTAs,
                                           g_aSUPTimestampTAs, g_cSUPTimestampTAs,
-                                          pErrInfo, "SpcAndNtKernelRoot");
+                                          aBuildCerts, (unsigned)RT_ELEMENTS(aBuildCerts));
+        }
         if (RT_SUCCESS(rc))
-            rc = supHardNtViCertStoreInit(&g_hSpcAndNtKernelSuppStore,
-                                          NULL, 0, NULL, 0, NULL, 0,
-                                          pErrInfo, "SpcAndNtKernelSupplemental");
-
-#if 0 /* For the time being, always trust the build certificate. It bypasses the timestamp issues of CRT and SDL. */
-        /* If the build certificate is a test singing certificate, it must be a
-           trusted root or we'll fail to validate anything. */
-        if (   RT_SUCCESS(rc)
-            && RTCrX509Name_Compare(&g_BuildX509Cert.TbsCertificate.Subject, &g_BuildX509Cert.TbsCertificate.Issuer) == 0)
-#else
-        if (RT_SUCCESS(rc))
-#endif
-            rc = RTCrStoreCertAddEncoded(g_hSpcAndNtKernelRootStore, RTCRCERTCTX_F_ENC_X509_DER,
-                                         g_abSUPBuildCert, g_cbSUPBuildCert, pErrInfo);
-
+            rc = supHardNtViCertStoreInit(&g_hSpcAndNtKernelSuppStore, pErrInfo, "SpcAndNtKernelSupplemental", 0);
         if (RT_SUCCESS(rc))
         {
Index: trunk/src/VBox/HostDrivers/Support/win/SUPR3HardenedMain-win.cpp
===================================================================
--- trunk/src/VBox/HostDrivers/Support/win/SUPR3HardenedMain-win.cpp	(revision 106997)
+++ trunk/src/VBox/HostDrivers/Support/win/SUPR3HardenedMain-win.cpp	(revision 106998)
@@ -284,5 +284,5 @@
  * A ntdll code patch.
  */
-typedef union SUPR3HARDNTPATCH
+typedef struct SUPR3HARDNTPATCH
 {
     union
@@ -3662,13 +3662,12 @@
  *                              the NTDLL instance we're patching.  (Must be +/-
  *                              2GB from the thunk code.)
- * @param   pBackup             Where to back up the original instruction bytes
- *                              at pvLdrInitThunk.
  * @param   pErrInfo            Where to return extended error information.
  *                              Optional.
  */
 static int supR3HardNtDisableThreadCreationEx(HANDLE hProcess, void *pvLdrInitThunk, void *pvNtTerminateThread,
-                                              SUPR3HARDNTPATCH *pBackup, PRTERRINFO pErrInfo)
-{
-    SUP_DPRINTF(("supR3HardNtDisableThreadCreation: pvLdrInitThunk=%p pvNtTerminateThread=%p\n", pvLdrInitThunk, pvNtTerminateThread));
+                                              PRTERRINFO pErrInfo)
+{
+    SUP_DPRINTF(("supR3HardNtDisableThreadCreation: pvLdrInitThunk=%p pvNtTerminateThread=%p g_LdrInitThunkSelfBackup.cb=%d\n",
+                 pvLdrInitThunk, pvNtTerminateThread, g_LdrInitThunkSelfBackup.cb));
     SUPR3HARDENED_ASSERT(RT_ABS((intptr_t)pvLdrInitThunk - (intptr_t)pvNtTerminateThread) < 16*_1M);
 
@@ -3677,8 +3676,14 @@
      */
     SIZE_T  cbIgnored;
-    NTSTATUS rcNt = NtReadVirtualMemory(hProcess, pvLdrInitThunk, pBackup->ab, sizeof(pBackup->ab), &cbIgnored);
-    if (!NT_SUCCESS(rcNt))
-        return RTErrInfoSetF(pErrInfo, VERR_GENERAL_FAILURE,
-                             "supR3HardNtDisableThreadCreation: NtReadVirtualMemory/LdrInitializeThunk failed: %#x", rcNt);
+    NTSTATUS rcNt;
+    if (g_LdrInitThunkSelfBackup.cb == 0)
+    {
+        rcNt = NtReadVirtualMemory(hProcess, pvLdrInitThunk, g_LdrInitThunkSelfBackup.ab,
+                                   sizeof(g_LdrInitThunkSelfBackup.ab), &cbIgnored);
+        if (!NT_SUCCESS(rcNt))
+            return RTErrInfoSetF(pErrInfo, VERR_GENERAL_FAILURE,
+                                 "supR3HardNtDisableThreadCreation: NtReadVirtualMemory/LdrInitializeThunk failed: %#x", rcNt);
+        SUP_DPRINTF(("supR3HardNtDisableThreadCreationEx: Backup=%.*Rhxs\n", sizeof(g_LdrInitThunkSelfBackup.ab), g_LdrInitThunkSelfBackup.ab));
+    }
 
     /*
@@ -3686,5 +3691,5 @@
      */
     SUPR3HARDNTPATCH Replacement;
-    memcpy(Replacement.ab, pBackup->ab, sizeof(Replacement.ab));
+    memcpy(Replacement.ab, g_LdrInitThunkSelfBackup.ab, sizeof(Replacement.ab));
 
 #ifdef RT_ARCH_AMD64
@@ -3721,5 +3726,5 @@
 # error "Unsupported arch."
 #endif
-    pBackup->cb = Replacement.cb;
+    g_LdrInitThunkSelfBackup.cb = Replacement.cb;
 
     /*
@@ -3740,5 +3745,5 @@
 
     pvProt   = pvLdrInitThunk;
-    cbProt   = pBackup->cb;
+    cbProt   = Replacement.cb;
     rcNt = NtProtectVirtualMemory(hProcess, &pvProt, &cbProt, fOldProt, &fOldProt);
     if (!NT_SUCCESS(rcNt))
@@ -3757,17 +3762,14 @@
  * @param   pvLdrInitThunk      The address of the LdrInitializeThunk code to
  *                              override.
- * @param   pBackup             Where to back up the original instruction bytes
- *                              at pvLdrInitThunk.
  * @param   pErrInfo            Where to return extended error information.
  *                              Optional.
  */
-static int supR3HardNtEnableThreadCreationEx(HANDLE hProcess, void *pvLdrInitThunk, SUPR3HARDNTPATCH const *pBackup,
-                                             PRTERRINFO pErrInfo)
+static int supR3HardNtEnableThreadCreationEx(HANDLE hProcess, void *pvLdrInitThunk, PRTERRINFO pErrInfo)
 {
     SUP_DPRINTF(("supR3HardNtEnableThreadCreationEx:\n"));
-    SUPR3HARDENED_ASSERT(pBackup->cb > 4);
+    SUPR3HARDENED_ASSERT(g_LdrInitThunkSelfBackup.cb > 4);
 
     PVOID  pvProt   = pvLdrInitThunk;
-    SIZE_T cbProt   = pBackup->cb;
+    SIZE_T cbProt   = g_LdrInitThunkSelfBackup.cb;
     ULONG  fOldProt = 0;
     NTSTATUS rcNt = NtProtectVirtualMemory(hProcess, &pvProt, &cbProt, PAGE_EXECUTE_READWRITE, &fOldProt);
@@ -3777,5 +3779,5 @@
 
     SIZE_T cbIgnored;
-    rcNt = NtWriteVirtualMemory(hProcess, pvLdrInitThunk, pBackup->ab, pBackup->cb, &cbIgnored);
+    rcNt = NtWriteVirtualMemory(hProcess, pvLdrInitThunk, g_LdrInitThunkSelfBackup.ab, g_LdrInitThunkSelfBackup.cb, &cbIgnored);
     if (!NT_SUCCESS(rcNt))
         return RTErrInfoSetF(pErrInfo, VERR_GENERAL_FAILURE,
@@ -3784,5 +3786,5 @@
 
     pvProt   = pvLdrInitThunk;
-    cbProt   = pBackup->cb;
+    cbProt   = g_LdrInitThunkSelfBackup.cb;
     rcNt = NtProtectVirtualMemory(hProcess, &pvProt, &cbProt, fOldProt, &fOldProt);
     if (!NT_SUCCESS(rcNt))
@@ -3813,5 +3815,4 @@
                                                 (void *)(uintptr_t)&LdrInitializeThunk,
                                                 (void *)(uintptr_t)s_pfnNtTerminateThread,
-                                                &g_LdrInitThunkSelfBackup,
                                                 NULL /* pErrInfo*/);
     g_fSupInitThunkSelfPatched = RT_SUCCESS(rc);
@@ -3828,5 +3829,4 @@
         int rc = supR3HardNtEnableThreadCreationEx(NtCurrentProcess(),
                                                    (void *)(uintptr_t)&LdrInitializeThunk,
-                                                   &g_LdrInitThunkSelfBackup,
                                                    RTErrInfoInitStatic(&g_ErrInfoStatic));
         if (RT_FAILURE(rc))
