Index: trunk/src/VBox/HostDrivers/Support/Makefile.kmk
===================================================================
--- trunk/src/VBox/HostDrivers/Support/Makefile.kmk	(revision 52024)
+++ trunk/src/VBox/HostDrivers/Support/Makefile.kmk	(revision 52030)
@@ -137,10 +137,11 @@
 # The Ring-3 Support Library (this is linked into the IPRT dll, VBoxRT).
 #
-SUPR3_TEMPLATE      = VBOXR3NP
+SUPR3_TEMPLATE      = VBOXR3
 SUPR3_DEFS          = \
 	IN_SUP_R3 IN_RT_R3 \
 	$(if $(VBOX_WITH_SUPSVC),VBOX_WITH_SUPSVC) \
 	$(if $(VBOX_WITH_MAIN),VBOX_WITH_MAIN,) \
-	$(if $(VBOX_WITH_RAW_MODE),VBOX_WITH_RAW_MODE,)
+	$(if $(VBOX_WITH_RAW_MODE),VBOX_WITH_RAW_MODE,) \
+	VBOX_PERMIT_MORE
 SUPR3_INCS         := $(PATH_SUB_CURRENT)
 SUPR3_SOURCES       = \
@@ -183,5 +184,6 @@
 	$(if $(VBOX_WITH_RAW_MODE),VBOX_WITH_RAW_MODE,) \
 	$(if $(VBOX_WITHOUT_DEBUGGER_CHECKS),VBOX_WITHOUT_DEBUGGER_CHECKS,) \
-	$(if $(VBOX_PERMIT_VISUAL_STUDIO_PROFILING),VBOX_PERMIT_VISUAL_STUDIO_PROFILING,)
+	$(if $(VBOX_PERMIT_VISUAL_STUDIO_PROFILING),VBOX_PERMIT_VISUAL_STUDIO_PROFILING,) \
+	VBOX_PERMIT_MORE
 ifdef VBOX_WITH_VISTA_NO_SP
  SUPR3HardenedStatic_DEFS.win += VBOX_WITH_VISTA_NO_SP
@@ -535,4 +537,5 @@
   VBoxDrv_DEFS           += VBOX_PERMIT_VISUAL_STUDIO_PROFILING
  endif
+ VBoxDrv_DEFS            += VBOX_PERMIT_MORE
  #VBoxDrv_DEFS.debug      += DEBUG_DARWIN_GIP
  VBoxDrv_DEFS.darwin     := VBOX_WITH_HOST_VMX
Index: trunk/src/VBox/HostDrivers/Support/win/SUPHardenedVerify-win.h
===================================================================
--- trunk/src/VBox/HostDrivers/Support/win/SUPHardenedVerify-win.h	(revision 52024)
+++ trunk/src/VBox/HostDrivers/Support/win/SUPHardenedVerify-win.h	(revision 52030)
@@ -39,4 +39,5 @@
 DECLHIDDEN(int)      supHardenedWinVerifyProcess(HANDLE hProcess, HANDLE hThread, PRTERRINFO pErrInfo);
 
+DECLHIDDEN(bool)     supHardViIsAppPatchDir(PCRTUTF16 pwszPath, uint32_t cwcName);
 DECLHIDDEN(int)      supHardenedWinVerifyImageByHandle(HANDLE hFile, PCRTUTF16 pwszName, uint32_t fFlags, bool *pfCacheable, PRTERRINFO pErrInfo);
 DECLHIDDEN(int)      supHardenedWinVerifyImageByHandleNoName(HANDLE hFile, uint32_t fFlags, PRTERRINFO pErrInfo);
@@ -52,4 +53,6 @@
 /** Whether to allow image verification by catalog file. */
 #  define SUPHNTVI_F_ALLOW_CAT_FILE_VERIFICATION    RT_BIT(3)
+/** Resource image, could be any bitness. */
+#  define SUPHNTVI_F_RESOURCE_IMAGE                 RT_BIT(30)
 /** Raw-mode context image, always 32-bit. */
 #  define SUPHNTVI_F_RC_IMAGE                       RT_BIT(31)
Index: trunk/src/VBox/HostDrivers/Support/win/SUPHardenedVerifyImage-win.cpp
===================================================================
--- trunk/src/VBox/HostDrivers/Support/win/SUPHardenedVerifyImage-win.cpp	(revision 52024)
+++ trunk/src/VBox/HostDrivers/Support/win/SUPHardenedVerifyImage-win.cpp	(revision 52030)
@@ -511,4 +511,32 @@
 
 
+#ifdef VBOX_PERMIT_MORE
+/**
+ * Checks if the path goes into %windir%\apppatch\.
+ *
+ * @returns true if apppatch, false if not.
+ * @param   pwszPath        The path to examine.
+ */
+DECLHIDDEN(bool) supHardViIsAppPatchDir(PCRTUTF16 pwszPath, uint32_t cwcName)
+{
+    uint32_t cwcWinDir = (g_System32NtPath.UniStr.Length - sizeof(L"System32")) / sizeof(WCHAR);
+
+    if (cwcName <= cwcWinDir + sizeof("AppPatch"))
+        return false;
+
+    if (memcmp(pwszPath, g_System32NtPath.UniStr.Buffer, cwcWinDir * sizeof(WCHAR)))
+        return false;
+
+    if (!supHardViUtf16PathStartsWith(&pwszPath[cwcWinDir], "\\AppPatch\\"))
+        return false;
+
+    return g_uNtVerCombined >= SUP_NT_VER_VISTA;
+}
+#else
+# error should not get here..
+#endif
+
+
+
 /**
  * Checks if the unsigned DLL is fine or not.
@@ -571,6 +599,15 @@
         if (supHardViUtf16PathIsEqual(pwsz, "apphelp.dll"))
             return uNtVer < SUP_MAKE_NT_VER_SIMPLE(6, 4) ? VINF_LDRVI_NOT_SIGNED : rc;
-        if (supHardViUtf16PathIsEqual(pwsz, "sfc.dll"))
-            return uNtVer < SUP_MAKE_NT_VER_SIMPLE(6, 4) ? VINF_LDRVI_NOT_SIGNED : rc;
+#ifdef VBOX_PERMIT_MORE
+        if (uNtVer >= SUP_NT_VER_W70) /* hard limit: user32.dll is unwanted prior to w7. */
+        {
+            if (supHardViUtf16PathIsEqual(pwsz, "sfc.dll"))
+                return uNtVer < SUP_MAKE_NT_VER_SIMPLE(6, 4) ? VINF_LDRVI_NOT_SIGNED : rc;
+            if (supHardViUtf16PathIsEqual(pwsz, "sfc_os.dll"))
+                return uNtVer < SUP_MAKE_NT_VER_SIMPLE(6, 4) ? VINF_LDRVI_NOT_SIGNED : rc;
+            if (supHardViUtf16PathIsEqual(pwsz, "user32.dll"))
+                return uNtVer < SUP_NT_VER_W81 ? VINF_LDRVI_NOT_SIGNED : rc;
+        }
+#endif
 
 #ifndef IN_RING0
@@ -653,4 +690,30 @@
         return rc;
     }
+#endif
+
+#ifdef VBOX_PERMIT_MORE
+    /*
+     * AppPatch whitelist.
+     */
+    if (supHardViIsAppPatchDir(pwszName, cwcName))
+    {
+        cwcOther = g_System32NtPath.UniStr.Length / sizeof(WCHAR); /* ASSUMES System32 is called System32. */
+        pwsz = pwszName + cwcOther + 1;
+
+        if (supHardViUtf16PathIsEqual(pwsz, "acres.dll"))
+            return VINF_LDRVI_NOT_SIGNED;
+
+# ifdef RT_ARCH_AMD64
+        if (supHardViUtf16PathIsEqual(pwsz, "AppPatch64\\AcGenral.dll"))
+            return VINF_LDRVI_NOT_SIGNED;
+# elif defined(RT_ARCH_X86)
+        if (supHardViUtf16PathIsEqual(pwsz, "AcGenral.dll"))
+            return VINF_LDRVI_NOT_SIGNED;
+# endif
+
+        return rc;
+    }
+#else
+# error should not be here...
 #endif
 
@@ -855,7 +918,8 @@
          */
         RTLDRMOD hLdrMod;
-        rc = RTLdrOpenWithReader(&pNtViRdr->Core, RTLDR_O_FOR_VALIDATION,
-                                 fFlags & SUPHNTVI_F_RC_IMAGE ? RTLDRARCH_X86_32 : RTLDRARCH_HOST,
-                                 &hLdrMod, pErrInfo);
+        RTLDRARCH enmArch = fFlags & SUPHNTVI_F_RC_IMAGE ? RTLDRARCH_X86_32 : RTLDRARCH_HOST;
+        if (fFlags & SUPHNTVI_F_RESOURCE_IMAGE)
+            enmArch = RTLDRARCH_WHATEVER;
+        rc = RTLdrOpenWithReader(&pNtViRdr->Core, RTLDR_O_FOR_VALIDATION, enmArch, &hLdrMod, pErrInfo);
         if (RT_SUCCESS(rc))
         {
Index: trunk/src/VBox/HostDrivers/Support/win/SUPHardenedVerifyProcess-win.cpp
===================================================================
--- trunk/src/VBox/HostDrivers/Support/win/SUPHardenedVerifyProcess-win.cpp	(revision 52024)
+++ trunk/src/VBox/HostDrivers/Support/win/SUPHardenedVerifyProcess-win.cpp	(revision 52030)
@@ -106,4 +106,6 @@
      * content.  The hack means that we only check if the 1st section is mapped. */
     bool            fApiSetSchemaOnlySection1;
+    /** This may be a 32-bit resource DLL. */
+    bool            f32bitResourceDll;
 } SUPHNTVPIMAGE;
 /** Pointer to image info from the virtual address space scan. */
@@ -123,4 +125,7 @@
      * more so we can get the image name of the first unwanted DLL. */
     SUPHNTVPIMAGE           aImages[1 + 6 + 1
+#ifdef VBOX_PERMIT_MORE
+                                    + 5
+#endif
 #ifdef VBOX_PERMIT_VISUAL_STUDIO_PROFILING
                                     + 16
@@ -154,5 +159,12 @@
     "apphelp.dll",
     "apisetschema.dll",
+#ifdef VBOX_PERMIT_MORE
+# define VBOX_PERMIT_MORE_FIRST_IDX 5
     "sfc.dll",
+    "sfc_os.dll",
+    "user32.dll",
+    "acres.dll",
+    "acgenral.dll",
+#endif
 #ifdef VBOX_PERMIT_VISUAL_STUDIO_PROFILING
     "psapi.dll",
@@ -409,5 +421,6 @@
                                        "%s: Unexpected e_lfanew value: %#x", pImage->pszName, offNtHdrs);
     }
-    PIMAGE_NT_HEADERS pNtHdrs = (PIMAGE_NT_HEADERS)&pThis->abFile[offNtHdrs];
+    PIMAGE_NT_HEADERS   pNtHdrs   = (PIMAGE_NT_HEADERS)&pThis->abFile[offNtHdrs];
+    PIMAGE_NT_HEADERS32 pNtHdrs32 = (PIMAGE_NT_HEADERS32)pNtHdrs;
     if (pNtHdrs->Signature != IMAGE_NT_SIGNATURE)
         return supHardNtVpSetInfo2(pThis, VERR_SUP_VP_BAD_IMAGE_SIGNATURE,
@@ -418,5 +431,5 @@
      */
 #ifdef RT_ARCH_AMD64
-    if (pNtHdrs->FileHeader.Machine != IMAGE_FILE_MACHINE_AMD64)
+    if (pNtHdrs->FileHeader.Machine != IMAGE_FILE_MACHINE_AMD64 && !pImage->f32bitResourceDll)
 #else
     if (pNtHdrs->FileHeader.Machine != IMAGE_FILE_MACHINE_I386)
@@ -424,16 +437,19 @@
         return supHardNtVpSetInfo2(pThis, VERR_SUP_VP_UNEXPECTED_IMAGE_MACHINE,
                                    "%s: Unexpected machine: %#x", pImage->pszName, pNtHdrs->FileHeader.Machine);
-
-    if (pNtHdrs->FileHeader.SizeOfOptionalHeader != sizeof(pNtHdrs->OptionalHeader))
+    bool const fIs32Bit = pNtHdrs->FileHeader.Machine == IMAGE_FILE_MACHINE_I386;
+
+    if (pNtHdrs->FileHeader.SizeOfOptionalHeader != (fIs32Bit ? sizeof(IMAGE_OPTIONAL_HEADER32) : sizeof(IMAGE_OPTIONAL_HEADER64)))
         return supHardNtVpSetInfo2(pThis, VERR_SUP_VP_BAD_OPTIONAL_HEADER,
                                    "%s: Unexpected optional header size: %#x",
                                    pImage->pszName, pNtHdrs->FileHeader.SizeOfOptionalHeader);
 
-    if (pNtHdrs->OptionalHeader.Magic != RT_CONCAT3(IMAGE_NT_OPTIONAL_HDR,ARCH_BITS,_MAGIC))
+    if (pNtHdrs->OptionalHeader.Magic != (fIs32Bit ? IMAGE_NT_OPTIONAL_HDR32_MAGIC : IMAGE_NT_OPTIONAL_HDR64_MAGIC))
         return supHardNtVpSetInfo2(pThis, VERR_SUP_VP_BAD_OPTIONAL_HEADER,
                                    "%s: Unexpected optional header magic: %#x", pImage->pszName, pNtHdrs->OptionalHeader.Magic);
-    if (pNtHdrs->OptionalHeader.NumberOfRvaAndSizes != IMAGE_NUMBEROF_DIRECTORY_ENTRIES)
+
+    uint32_t cDirs = (fIs32Bit ? pNtHdrs32->OptionalHeader.NumberOfRvaAndSizes : pNtHdrs->OptionalHeader.NumberOfRvaAndSizes);
+    if (cDirs != IMAGE_NUMBEROF_DIRECTORY_ENTRIES)
         return supHardNtVpSetInfo2(pThis, VERR_SUP_VP_BAD_OPTIONAL_HEADER,
-                                   "%s: Unexpected data dirs: %#x", pImage->pszName, pNtHdrs->OptionalHeader.NumberOfRvaAndSizes);
+                                   "%s: Unexpected data dirs: %#x", pImage->pszName, cDirs);
 
     /*
@@ -444,12 +460,13 @@
         return supHardNtVpSetInfo2(pThis, VERR_SUP_VP_TOO_MANY_SECTIONS,
                                    "%s: Too many section headers: %#x", pImage->pszName, cSections);
-    suplibHardenedMemCopy(pThis->aSecHdrs, pNtHdrs + 1, cSections * sizeof(IMAGE_SECTION_HEADER));
-
-    uintptr_t const uImageBase = pNtHdrs->OptionalHeader.ImageBase;
+    suplibHardenedMemCopy(pThis->aSecHdrs, (fIs32Bit ? (void *)(pNtHdrs32 + 1) : (void *)(pNtHdrs + 1)),
+                          cSections * sizeof(IMAGE_SECTION_HEADER));
+
+    uintptr_t const uImageBase = fIs32Bit ? pNtHdrs32->OptionalHeader.ImageBase : pNtHdrs->OptionalHeader.ImageBase;
     if (uImageBase & PAGE_OFFSET_MASK)
         return supHardNtVpSetInfo2(pThis, VERR_SUP_VP_BAD_IMAGE_BASE,
                                    "%s: Invalid image base: %p", pImage->pszName, uImageBase);
 
-    uint32_t  const cbImage    = pNtHdrs->OptionalHeader.SizeOfImage;
+    uint32_t  const cbImage    = fIs32Bit ? pNtHdrs32->OptionalHeader.SizeOfImage : pNtHdrs->OptionalHeader.SizeOfImage;
     if (RT_ALIGN_32(pImage->cbImage, PAGE_SIZE) != RT_ALIGN_32(cbImage, PAGE_SIZE) && !pImage->fApiSetSchemaOnlySection1)
         return supHardNtVpSetInfo2(pThis, VERR_SUP_VP_BAD_IMAGE_SIZE,
@@ -457,5 +474,5 @@
                                    pImage->pszName, cbImage, pImage->cbImage);
 
-    uint32_t const cbSectAlign = pNtHdrs->OptionalHeader.SectionAlignment;
+    uint32_t const cbSectAlign = fIs32Bit ? pNtHdrs32->OptionalHeader.SectionAlignment : pNtHdrs->OptionalHeader.SectionAlignment;
     if (   !RT_IS_POWER_OF_TWO(cbSectAlign)
         || cbSectAlign < PAGE_SIZE
@@ -464,5 +481,5 @@
                                    "%s: Unexpected SectionAlignment value: %#x", pImage->pszName, cbSectAlign);
 
-    uint32_t const cbFileAlign = pNtHdrs->OptionalHeader.FileAlignment;
+    uint32_t const cbFileAlign = fIs32Bit ? pNtHdrs32->OptionalHeader.FileAlignment : pNtHdrs->OptionalHeader.FileAlignment;
     if (!RT_IS_POWER_OF_TWO(cbFileAlign) || cbFileAlign < 512 || cbFileAlign > PAGE_SIZE || cbFileAlign > cbSectAlign)
         return supHardNtVpSetInfo2(pThis, VERR_SUP_VP_BAD_FILE_ALIGNMENT_VALUE,
@@ -470,6 +487,7 @@
                                    pImage->pszName, cbFileAlign, cbSectAlign);
 
-    uint32_t  const cbHeaders  = pNtHdrs->OptionalHeader.SizeOfHeaders;
-    uint32_t  const cbMinHdrs  = offNtHdrs + sizeof(*pNtHdrs) + sizeof(IMAGE_SECTION_HEADER) * cSections;
+    uint32_t  const cbHeaders  = fIs32Bit ? pNtHdrs32->OptionalHeader.SizeOfHeaders : pNtHdrs->OptionalHeader.SizeOfHeaders;
+    uint32_t  const cbMinHdrs  = offNtHdrs + (fIs32Bit ? sizeof(*pNtHdrs32) : sizeof(*pNtHdrs) )
+                               + sizeof(IMAGE_SECTION_HEADER) * cSections;
     if (cbHeaders < cbMinHdrs)
         return supHardNtVpSetInfo2(pThis, VERR_SUP_VP_BAD_SIZE_OF_HEADERS,
@@ -494,5 +512,10 @@
                                        "%s: Error reading image header from memory: %#x", pImage->pszName, rcNt);
         if (uImageBase != pImage->uImageBase)
-            pNtHdrs->OptionalHeader.ImageBase = pImage->uImageBase;
+        {
+            if (fIs32Bit)
+                pNtHdrs32->OptionalHeader.ImageBase = (uint32_t)pImage->uImageBase;
+            else
+                pNtHdrs->OptionalHeader.ImageBase = pImage->uImageBase;
+        }
 
         rc = supHardNtVpFileMemCompare(pThis, pThis->abFile, pThis->abMemory, cbHeaders, pImage, 0 /*uRva*/);
@@ -508,5 +531,5 @@
      */
     pImage->fImageCharecteristics = pNtHdrs->FileHeader.Characteristics;
-    pImage->fDllCharecteristics   = pNtHdrs->OptionalHeader.DllCharacteristics;
+    pImage->fDllCharecteristics   = fIs32Bit ? pNtHdrs32->OptionalHeader.DllCharacteristics : pNtHdrs->OptionalHeader.DllCharacteristics;
 
     /*
@@ -641,7 +664,8 @@
      * disk content.
      */
-    int rc = supHardenedWinVerifyImageByHandle(hFile, pImage->Name.UniStr.Buffer,
-                                               pImage->fDll ? 0 : SUPHNTVI_F_REQUIRE_BUILD_CERT,
-                                               NULL /*pfCacheable*/, pThis->pErrInfo);
+    uint32_t fFlags = pImage->fDll ? 0 : SUPHNTVI_F_REQUIRE_BUILD_CERT;
+    if (pImage->f32bitResourceDll)
+        fFlags |= SUPHNTVI_F_RESOURCE_IMAGE;
+    int rc = supHardenedWinVerifyImageByHandle(hFile, pImage->Name.UniStr.Buffer, fFlags, NULL /*pfCacheable*/, pThis->pErrInfo);
     if (RT_SUCCESS(rc))
         rc = supHardNtVpVerifyImageCompareMemory(pThis, pImage, hProcess, hFile, pThis->pErrInfo);
@@ -831,12 +855,23 @@
 #ifndef VBOX_PERMIT_VISUAL_STUDIO_PROFILING
             /* The directory name must match the one we've got for System32. */
-            if (   cwcDirName * sizeof(WCHAR) != g_System32NtPath.UniStr.Length
-                || suplibHardenedMemComp(pImage->Name.UniStr.Buffer,
-                                         g_System32NtPath.UniStr.Buffer,
-                                         cwcDirName * sizeof(WCHAR)))
+            if (   (   cwcDirName * sizeof(WCHAR) != g_System32NtPath.UniStr.Length
+                    || suplibHardenedMemComp(pImage->Name.UniStr.Buffer,
+                                            g_System32NtPath.UniStr.Buffer,
+                                            cwcDirName * sizeof(WCHAR)) )
+# ifdef VBOX_PERMIT_MORE
+                && (   pImage->pszName[0] != 'a'
+                    || pImage->pszName[1] != 'c'
+                    || !supHardViIsAppPatchDir(pImage->Name.UniStr.Buffer, pImage->Name.UniStr.Length / sizeof(WCHAR)) )
+# endif
+                )
                 return supHardNtVpSetInfo2(pThis, VERR_SUP_VP_NON_SYSTEM32_DLL,
                                            "Expected %ls to be loaded from %ls.",
                                            pImage->Name.UniStr.Buffer, g_System32NtPath.UniStr.Buffer);
-#endif
+# ifdef VBOX_PERMIT_MORE
+            if (g_uNtVerCombined < SUP_NT_VER_W70 && i >= VBOX_PERMIT_MORE_FIRST_IDX)
+                pImage->pszName = NULL; /* hard limit: user32.dll is unwanted prior to w7. */
+# endif
+
+#endif /* VBOX_PERMIT_VISUAL_STUDIO_PROFILING */
             break;
         }
@@ -1232,4 +1267,8 @@
         else if (suplibHardenedStrCmp(pThis->aImages[i].pszName, "apisetschema.dll") == 0)
             iApiSetSchema = i;
+#ifdef VBOX_PERMIT_MORE
+        else if (suplibHardenedStrCmp(pThis->aImages[i].pszName, "acres.dll") == 0)
+            pThis->aImages[i].f32bitResourceDll = true;
+#endif
     if (iNtDll == UINT32_MAX)
         return supHardNtVpSetInfo2(pThis, VERR_SUP_VP_NO_NTDLL_MAPPING,
Index: trunk/src/VBox/HostDrivers/Support/win/SUPR3HardenedMain-win.cpp
===================================================================
--- trunk/src/VBox/HostDrivers/Support/win/SUPR3HardenedMain-win.cpp	(revision 52024)
+++ trunk/src/VBox/HostDrivers/Support/win/SUPR3HardenedMain-win.cpp	(revision 52030)
@@ -624,4 +624,8 @@
                                g_offSupLibHardenedExeNtName * sizeof(WCHAR)) == 0)
                 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;
+#endif
 #ifdef VBOX_PERMIT_VISUAL_STUDIO_PROFILING
             /* Hack to allow profiling our code with Visual Studio. */
