Index: /trunk/include/VBox/err.h
===================================================================
--- /trunk/include/VBox/err.h	(revision 66524)
+++ /trunk/include/VBox/err.h	(revision 66525)
@@ -2660,4 +2660,6 @@
 /** Error creating an event semaphore for used with asynchronous reads. */
 #define VERR_SUP_VP_CREATE_READ_EVT_SEM_FAILED      (-5675)
+/** Undesirable module. */
+#define VERR_SUP_VP_UNDESIRABLE_MODULE              (-5676)
 
 /** @} */
Index: /trunk/src/VBox/HostDrivers/Support/Makefile.kmk
===================================================================
--- /trunk/src/VBox/HostDrivers/Support/Makefile.kmk	(revision 66524)
+++ /trunk/src/VBox/HostDrivers/Support/Makefile.kmk	(revision 66525)
@@ -337,4 +337,5 @@
 	$(VBOX_PATH_RUNTIME_SRC)/common/string/RTStrCmp.cpp \
 	$(VBOX_PATH_RUNTIME_SRC)/common/string/RTStrCopy.cpp \
+	$(VBOX_PATH_RUNTIME_SRC)/common/string/RTStrICmpAscii.cpp \
 	$(VBOX_PATH_RUNTIME_SRC)/common/string/RTStrNCmp.cpp \
 	$(VBOX_PATH_RUNTIME_SRC)/common/string/RTStrNLen.cpp \
Index: /trunk/src/VBox/HostDrivers/Support/win/SUPHardenedVerify-win.h
===================================================================
--- /trunk/src/VBox/HostDrivers/Support/win/SUPHardenedVerify-win.h	(revision 66524)
+++ /trunk/src/VBox/HostDrivers/Support/win/SUPHardenedVerify-win.h	(revision 66525)
@@ -139,4 +139,7 @@
 /** @} */
 
+/* Array in SUPHardenedVerifyImage-win.cpp */
+extern const RTSTRTUPLE g_aSupNtViBlacklistedDlls[];
+
 /**
  * Loader cache entry.
Index: /trunk/src/VBox/HostDrivers/Support/win/SUPHardenedVerifyImage-win.cpp
===================================================================
--- /trunk/src/VBox/HostDrivers/Support/win/SUPHardenedVerifyImage-win.cpp	(revision 66524)
+++ /trunk/src/VBox/HostDrivers/Support/win/SUPHardenedVerifyImage-win.cpp	(revision 66525)
@@ -140,4 +140,14 @@
 # endif
 #endif /* IN_RING3 && !VBOX_PERMIT_MORE*/
+
+/**
+ * Blacklisted DLL names.
+ */
+const RTSTRTUPLE g_aSupNtViBlacklistedDlls[] =
+{
+    { RT_STR_TUPLE("SCROBJ.dll") },
+    { NULL, 0 } /* terminator entry */
+};
+
 
 static union
@@ -1273,4 +1283,43 @@
     RT_NOREF1(fAvoidWinVerifyTrust);
 #endif
+
+    /*
+     * Check for blacklisted DLLs, both internal name and filename.
+     */
+    if (RT_SUCCESS(rc))
+    {
+        size_t const cwcName = RTUtf16Len(pwszName);
+        char         szIntName[64];
+        int rc2 = RTLdrQueryProp(hLdrMod, RTLDRPROP_INTERNAL_NAME, szIntName, sizeof(szIntName));
+        if (RT_SUCCESS(rc2))
+        {
+            size_t const cchIntName = strlen(szIntName);
+            for (unsigned i = 0; g_aSupNtViBlacklistedDlls[i].psz != NULL; i++)
+                if (   cchIntName == g_aSupNtViBlacklistedDlls[i].cch
+                    && RTStrICmpAscii(szIntName, g_aSupNtViBlacklistedDlls[i].psz) == 0)
+                {
+                    rc = RTErrInfoSetF(pErrInfo, VERR_SUP_VP_UNDESIRABLE_MODULE,
+                                       "The image '%ls' is listed as undesirable.", pwszName);
+                    break;
+                }
+        }
+        if (RT_SUCCESS(rc))
+        {
+            for (unsigned i = 0; g_aSupNtViBlacklistedDlls[i].psz != NULL; i++)
+                if (cwcName >= g_aSupNtViBlacklistedDlls[i].cch)
+                {
+                    PCRTUTF16 pwszTmp = &pwszName[cwcName - g_aSupNtViBlacklistedDlls[i].cch];
+                    if (   (   cwcName == g_aSupNtViBlacklistedDlls[i].cch
+                            || pwszTmp[-1] == '\\'
+                            || pwszTmp[-1] == '/')
+                        && RTUtf16ICmpAscii(pwszTmp, g_aSupNtViBlacklistedDlls[i].psz) == 0)
+                    {
+                        rc = RTErrInfoSetF(pErrInfo, VERR_SUP_VP_UNDESIRABLE_MODULE,
+                                           "The image '%ls' is listed as undesirable.", pwszName);
+                        break;
+                    }
+                }
+        }
+    }
 
 #ifdef IN_SUP_HARDENED_R3
Index: /trunk/src/VBox/HostDrivers/Support/win/SUPR3HardenedMain-win.cpp
===================================================================
--- /trunk/src/VBox/HostDrivers/Support/win/SUPR3HardenedMain-win.cpp	(revision 66524)
+++ /trunk/src/VBox/HostDrivers/Support/win/SUPR3HardenedMain-win.cpp	(revision 66525)
@@ -1638,4 +1638,26 @@
 
 /**
+ * Helper for supR3HardenedMonitor_LdrLoadDll that compares the name part of the
+ * input path against a ASCII name string of a given length.
+ *
+ * @returns true if the name part matches
+ * @param   pPath               The LdrLoadDll input path.
+ * @param   pszName             The name to try match it with.
+ * @param   cchName             The name length.
+ */
+static bool supR3HardenedIsFilenameMatchDll(PUNICODE_STRING pPath, const char *pszName, size_t cchName)
+{
+    if (pPath->Length < cchName * 2)
+        return false;
+    PCRTUTF16 pwszTmp = &pPath->Buffer[pPath->Length / sizeof(RTUTF16) - cchName];
+    if (   pPath->Length != cchName
+        && pwszTmp[-1] != '\\'
+        && pwszTmp[-1] != '/')
+        return false;
+    return RTUtf16ICmpAscii(pwszTmp, pszName) == 0;
+}
+
+
+/**
  * Hooks that intercepts LdrLoadDll calls.
  *
@@ -1714,20 +1736,11 @@
             { RT_STR_TUPLE("PGHook.dll") },
         };
-
         for (unsigned i = 0; i < RT_ELEMENTS(s_aUnwantedEarlyDlls); i++)
-        {
-            if (pName->Length < s_aUnwantedEarlyDlls[i].cch * 2)
-                continue;
-            PCRTUTF16 pwszTmp = &pName->Buffer[pName->Length / sizeof(RTUTF16) - s_aUnwantedEarlyDlls[i].cch];
-            if (   pName->Length != s_aUnwantedEarlyDlls[i].cch * 2
-                && pwszTmp[-1] != '\\'
-                && pwszTmp[-1] != '/')
-                continue;
-            if (RTUtf16ICmpAscii(pwszTmp, s_aUnwantedEarlyDlls[i].psz) != 0)
-                continue;
-            SUP_DPRINTF(("supR3HardenedMonitor_LdrLoadDll: Refusing to load '%.*ls' as it is expected to create undesirable threads that will upset our respawn checks (returning STATUS_TOO_MANY_THREADS)\n",
-                         pName->Length / sizeof(RTUTF16), pName->Buffer));
-            return STATUS_TOO_MANY_THREADS;
-        }
+            if (supR3HardenedIsFilenameMatchDll(pName, s_aUnwantedEarlyDlls[i].psz, s_aUnwantedEarlyDlls[i].cch))
+            {
+                SUP_DPRINTF(("supR3HardenedMonitor_LdrLoadDll: Refusing to load '%.*ls' as it is expected to create undesirable threads that will upset our respawn checks (returning STATUS_TOO_MANY_THREADS)\n",
+                             pName->Length / sizeof(RTUTF16), pName->Buffer));
+                return STATUS_TOO_MANY_THREADS;
+            }
     }
 
@@ -1909,4 +1922,18 @@
         pName = &ResolvedName;
     }
+
+#ifndef IN_SUP_R3_STATIC
+    /*
+     * Reject blacklisted DLLs based on input name.
+     */
+    for (unsigned i = 0; g_aSupNtViBlacklistedDlls[i].psz != NULL; i++)
+        if (supR3HardenedIsFilenameMatchDll(pName, g_aSupNtViBlacklistedDlls[i].psz, g_aSupNtViBlacklistedDlls[i].cch))
+        {
+            SUP_DPRINTF(("supR3HardenedMonitor_LdrLoadDll: Refusing to load blacklisted DLL: '%.*ls'\n",
+                         pName->Length / sizeof(RTUTF16), pName->Buffer));
+            RtlRestoreLastWin32Error(dwSavedLastError);
+            return STATUS_TOO_MANY_THREADS;
+        }
+#endif
 
     bool fQuiet = false;
