Eric Pouech : dbghelp: Detect collision by looking at module's base address in SymLoadModuleEx().

Alexandre Julliard julliard at winehq.org
Tue Nov 16 16:32:28 CST 2021


Module: wine
Branch: master
Commit: 1465c7de2a533ea6bda9b939c54f969dac29f2bb
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=1465c7de2a533ea6bda9b939c54f969dac29f2bb

Author: Eric Pouech <eric.pouech at gmail.com>
Date:   Tue Nov 16 17:47:43 2021 +0100

dbghelp: Detect collision by looking at module's base address in SymLoadModuleEx().

Signed-off-by: Eric Pouech <eric.pouech at gmail.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/dbghelp/module.c | 73 +++++++++++++++++++++++++++------------------------
 1 file changed, 38 insertions(+), 35 deletions(-)

diff --git a/dlls/dbghelp/module.c b/dlls/dbghelp/module.c
index 5c439dd1d3c..64d4e3113d5 100644
--- a/dlls/dbghelp/module.c
+++ b/dlls/dbghelp/module.c
@@ -900,7 +900,8 @@ DWORD64 WINAPI  SymLoadModuleExW(HANDLE hProcess, HANDLE hFile, PCWSTR wImageNam
                                  PMODLOAD_DATA Data, DWORD Flags)
 {
     struct process*     pcs;
-    struct module*	module = NULL;
+    struct module*      module = NULL;
+    struct module*      altmodule;
 
     TRACE("(%p %p %s %s %s %08x %p %08x)\n",
           hProcess, hFile, debugstr_w(wImageName), debugstr_w(wModuleName),
@@ -912,16 +913,6 @@ DWORD64 WINAPI  SymLoadModuleExW(HANDLE hProcess, HANDLE hFile, PCWSTR wImageNam
 
     if (!(pcs = process_find_by_handle(hProcess))) return 0;
 
-    if (Flags & SLMFLAG_VIRTUAL)
-    {
-        if (!wImageName) return 0;
-        module = module_new(pcs, wImageName, DMT_PE, TRUE, BaseOfDll, SizeOfDll, 0, 0, IMAGE_FILE_MACHINE_UNKNOWN);
-        if (!module) return 0;
-        if (wModuleName) module_set_module(module, wModuleName);
-        module->module.SymType = SymVirtual;
-
-        return module->module.BaseOfImage;
-    }
     if (Flags & ~(SLMFLAG_VIRTUAL))
         FIXME("Unsupported Flags %08x for %s\n", Flags, debugstr_w(wImageName));
 
@@ -930,31 +921,18 @@ DWORD64 WINAPI  SymLoadModuleExW(HANDLE hProcess, HANDLE hFile, PCWSTR wImageNam
     /* this is a Wine extension to the API just to redo the synchronisation */
     if (!wImageName && !hFile) return 0;
 
-    /* check if the module is already loaded, or if it's a builtin PE module with
-     * an containing ELF module
-     */
-    if (wImageName)
+    if (Flags & SLMFLAG_VIRTUAL)
     {
-        module = module_is_already_loaded(pcs, wImageName);
-        if (module)
-        {
-            if (module->module.BaseOfImage == BaseOfDll)
-                SetLastError(ERROR_SUCCESS);
-            else
-            {
-                /* native allows to load the same module at different addresses
-                 * we don't support this for now
-                 */
-                SetLastError(ERROR_INVALID_PARAMETER);
-                FIXME("Reloading %s at different base address isn't supported\n", debugstr_w(module->modulename));
-            }
-            return 0;
-        }
-        if (!module && module_is_container_loaded(pcs, wImageName, BaseOfDll))
-        {
-            /* force the loading of DLL as builtin */
-            module = pe_load_builtin_module(pcs, wImageName, BaseOfDll, SizeOfDll);
-        }
+        if (!wImageName) return 0;
+        module = module_new(pcs, wImageName, DMT_PE, TRUE, BaseOfDll, SizeOfDll, 0, 0, IMAGE_FILE_MACHINE_UNKNOWN);
+        if (!module) return 0;
+        module->module.SymType = SymVirtual;
+    }
+    /* check if it's a builtin PE module with a containing ELF module */
+    else if (wImageName && module_is_container_loaded(pcs, wImageName, BaseOfDll))
+    {
+        /* force the loading of DLL as builtin */
+        module = pe_load_builtin_module(pcs, wImageName, BaseOfDll, SizeOfDll);
     }
     if (!module)
     {
@@ -978,6 +956,31 @@ DWORD64 WINAPI  SymLoadModuleExW(HANDLE hProcess, HANDLE hFile, PCWSTR wImageNam
         module_set_module(module, wModuleName);
     if (wImageName)
         lstrcpynW(module->module.ImageName, wImageName, ARRAY_SIZE(module->module.ImageName));
+
+    for (altmodule = pcs->lmodules; altmodule; altmodule = altmodule->next)
+    {
+        if (altmodule != module && altmodule->type == module->type &&
+            module->module.BaseOfImage >= altmodule->module.BaseOfImage &&
+            module->module.BaseOfImage < altmodule->module.BaseOfImage + altmodule->module.ImageSize)
+            break;
+    }
+    if (altmodule)
+    {
+        /* we have a conflict as the new module cannot be found by its base address
+         * we need to get rid of one on the two modules
+         */
+        /* loading same module at same address... don't change anything */
+        if (module->module.BaseOfImage == altmodule->module.BaseOfImage)
+        {
+            module_remove(pcs, module);
+            SetLastError(ERROR_SUCCESS);
+            return 0;
+        }
+        module_remove(pcs, module);
+        SetLastError(ERROR_INVALID_PARAMETER);
+        return 0;
+    }
+
     if ((dbghelp_options & SYMOPT_DEFERRED_LOADS) == 0)
         module_load_debug(module);
     return module->module.BaseOfImage;




More information about the wine-cvs mailing list