Index: trunk/src/VBox/HostDrivers/Support/win/SUPDrv-win.cpp
===================================================================
--- trunk/src/VBox/HostDrivers/Support/win/SUPDrv-win.cpp	(revision 75049)
+++ trunk/src/VBox/HostDrivers/Support/win/SUPDrv-win.cpp	(revision 75282)
@@ -2083,4 +2083,5 @@
 }
 
+
 void VBOXCALL   supdrvOSLdrNotifyUnloaded(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage)
 {
@@ -2088,13 +2089,15 @@
 }
 
-/*
- * Note! Similar code in rtR0DbgKrnlNtParseModule.
- */
-int  VBOXCALL   supdrvOSLdrValidatePointer(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, void *pv,
-                                           const uint8_t *pbImageBits, const char *pszSymbol)
-{
-#if 1
-    RT_NOREF(pDevExt, pbImageBits);
+
+/**
+ * Common worker for supdrvOSLdrQuerySymbol and supdrvOSLdrValidatePointer.
+ *
+ * @note    Similar code in rtR0DbgKrnlNtParseModule.
+ */
+static int supdrvOSLdrValidatePointerOrQuerySymbol(PSUPDRVLDRIMAGE pImage, void *pv, const char *pszSymbol,
+                                                   size_t cchSymbol, void **ppvSymbol)
+{
     AssertReturn(pImage->pvNtSectionObj, VERR_INVALID_STATE);
+    Assert(pszSymbol || !ppvSymbol);
 
     /*
@@ -2104,5 +2107,5 @@
     uint32_t const  cbMapping      = pImage->cbImageBits;
     uint32_t const  uRvaToValidate = (uint32_t)((uintptr_t)pv - (uintptr_t)pbMapping);
-    AssertReturn(uRvaToValidate < cbMapping, VERR_INTERNAL_ERROR_3);
+    AssertReturn(uRvaToValidate < cbMapping || ppvSymbol, VERR_INTERNAL_ERROR_3);
 
     uint32_t const  offNtHdrs = *(uint16_t *)pbMapping == IMAGE_DOS_SIGNATURE
@@ -2128,5 +2131,5 @@
     {
         SUPR0Printf("SUPDrv: No exports in %s!\n", pImage->szName);
-        return VERR_NOT_FOUND;
+        return ppvSymbol ? VERR_SYMBOL_NOT_FOUND : VERR_NOT_FOUND;
     }
     AssertReturn(   ExpDir.Size >= sizeof(IMAGE_EXPORT_DIRECTORY)
@@ -2143,5 +2146,5 @@
     {
         SUPR0Printf("SUPDrv: No exports in %s!\n", pImage->szName);
-        return VERR_NOT_FOUND;
+        return ppvSymbol ? VERR_SYMBOL_NOT_FOUND : VERR_NOT_FOUND;
     }
 
@@ -2170,22 +2173,25 @@
      */
     uint32_t iExportOrdinal = UINT32_MAX;
-    for (uint32_t i = 0; i < cExports; i++)
-        if (paoffExports[i] == uRvaToValidate)
-        {
-            iExportOrdinal = i;
-            break;
-        }
-    if (iExportOrdinal == UINT32_MAX)
-    {
-        SUPR0Printf("SUPDrv: No export with rva %#x (%s) in %s!\n", uRvaToValidate, pszSymbol, pImage->szName);
-        return VERR_NOT_FOUND;
-    }
-
-    /*
-     * Can we validate the symbol name too?  If so, just do a linear search.
-     */
-    if (pszSymbol && RT_C_IS_UPPER(*pszSymbol))
-    {
-        size_t const cchSymbol  = strlen(pszSymbol);
+    if (!ppvSymbol)
+    {
+        for (uint32_t i = 0; i < cExports; i++)
+            if (paoffExports[i] == uRvaToValidate)
+            {
+                iExportOrdinal = i;
+                break;
+            }
+        if (iExportOrdinal == UINT32_MAX)
+        {
+            SUPR0Printf("SUPDrv: No export with rva %#x (%s) in %s!\n", uRvaToValidate, pszSymbol, pImage->szName);
+            return VERR_NOT_FOUND;
+        }
+    }
+
+    /*
+     * Can we validate the symbol name too or should we find a name?
+     * If so, just do a linear search.
+     */
+    if (pszSymbol && (RT_C_IS_UPPER(*pszSymbol) || ppvSymbol))
+    {
         for (uint32_t i = 0; i < cNamedExports; i++)
         {
@@ -2193,5 +2199,5 @@
             AssertReturn(offName < cbMapping, VERR_BAD_EXE_FORMAT);
             uint32_t const     cchMaxName = cbMapping - offName;
-            const char * const pszName    = (const char *)&pbImageBits[offName];
+            const char * const pszName    = (const char *)&pbMapping[offName];
             const char * const pszEnd     = (const char *)memchr(pszName, '\0', cchMaxName);
             AssertReturn(pszEnd, VERR_BAD_EXE_FORMAT);
@@ -2200,20 +2206,45 @@
                 && memcmp(pszName, pszSymbol, cchSymbol) == 0)
             {
-                if (pau16NameOrdinals[i] == iExportOrdinal)
+                if (ppvSymbol)
+                {
+                    iExportOrdinal = pau16NameOrdinals[i];
+                    if (   iExportOrdinal < cExports
+                        && paoffExports[iExportOrdinal] < cbMapping)
+                    {
+                        *ppvSymbol = (void *)(paoffExports[iExportOrdinal] + pbMapping);
+                        return VINF_SUCCESS;
+                    }
+                }
+                else if (pau16NameOrdinals[i] == iExportOrdinal)
                     return VINF_SUCCESS;
-                SUPR0Printf("SUPDrv: Different exports found for %s and rva %#x in %s: %#x vs %#x\n",
-                            pszSymbol, uRvaToValidate, pImage->szName, pau16NameOrdinals[i], iExportOrdinal);
+                else
+                    SUPR0Printf("SUPDrv: Different exports found for %s and rva %#x in %s: %#x vs %#x\n",
+                                pszSymbol, uRvaToValidate, pImage->szName, pau16NameOrdinals[i], iExportOrdinal);
                 return VERR_LDR_BAD_FIXUP;
             }
         }
-        SUPR0Printf("SUPDrv: No export named %s (%#x) in %s!\n", pszSymbol, uRvaToValidate, pImage->szName);
+        if (!ppvSymbol)
+            SUPR0Printf("SUPDrv: No export named %s (%#x) in %s!\n", pszSymbol, uRvaToValidate, pImage->szName);
         return VERR_SYMBOL_NOT_FOUND;
     }
     return VINF_SUCCESS;
-
-#else
-    NOREF(pDevExt); NOREF(pImage); NOREF(pv); NOREF(pbImageBits); NOREF(pszSymbol);
-    return VERR_NOT_SUPPORTED;
-#endif
+}
+
+
+int  VBOXCALL   supdrvOSLdrValidatePointer(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, void *pv,
+                                           const uint8_t *pbImageBits, const char *pszSymbol)
+{
+    RT_NOREF(pDevExt, pbImageBits);
+    return supdrvOSLdrValidatePointerOrQuerySymbol(pImage, pv, pszSymbol, pszSymbol ? strlen(pszSymbol) : 0, NULL);
+}
+
+
+int  VBOXCALL   supdrvOSLdrQuerySymbol(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage,
+                                       const char *pszSymbol, size_t cchSymbol, void **ppvSymbol)
+{
+    RT_NOREF(pDevExt);
+    AssertReturn(ppvSymbol, VERR_INVALID_PARAMETER);
+    AssertReturn(pszSymbol, VERR_INVALID_PARAMETER);
+    return supdrvOSLdrValidatePointerOrQuerySymbol(pImage, NULL, pszSymbol, cchSymbol, ppvSymbol);
 }
 
