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

Signed-off-by: Eric Pouech <eric.pouech@gmail.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Eric Pouech 2021-11-16 17:47:43 +01:00 committed by Alexandre Julliard
parent ced12a1a3a
commit 1465c7de2a
1 changed files with 38 additions and 35 deletions

View File

@ -900,7 +900,8 @@ DWORD64 WINAPI SymLoadModuleExW(HANDLE hProcess, HANDLE hFile, PCWSTR wImageNam
PMODLOAD_DATA Data, DWORD Flags) PMODLOAD_DATA Data, DWORD Flags)
{ {
struct process* pcs; struct process* pcs;
struct module* module = NULL; struct module* module = NULL;
struct module* altmodule;
TRACE("(%p %p %s %s %s %08x %p %08x)\n", TRACE("(%p %p %s %s %s %08x %p %08x)\n",
hProcess, hFile, debugstr_w(wImageName), debugstr_w(wModuleName), 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 (!(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)) if (Flags & ~(SLMFLAG_VIRTUAL))
FIXME("Unsupported Flags %08x for %s\n", Flags, debugstr_w(wImageName)); 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 */ /* this is a Wine extension to the API just to redo the synchronisation */
if (!wImageName && !hFile) return 0; if (!wImageName && !hFile) return 0;
/* check if the module is already loaded, or if it's a builtin PE module with if (Flags & SLMFLAG_VIRTUAL)
* an containing ELF module
*/
if (wImageName)
{ {
module = module_is_already_loaded(pcs, wImageName); if (!wImageName) return 0;
if (module) module = module_new(pcs, wImageName, DMT_PE, TRUE, BaseOfDll, SizeOfDll, 0, 0, IMAGE_FILE_MACHINE_UNKNOWN);
{ if (!module) return 0;
if (module->module.BaseOfImage == BaseOfDll) module->module.SymType = SymVirtual;
SetLastError(ERROR_SUCCESS); }
else /* check if it's a builtin PE module with a containing ELF module */
{ else if (wImageName && module_is_container_loaded(pcs, wImageName, BaseOfDll))
/* native allows to load the same module at different addresses {
* we don't support this for now /* force the loading of DLL as builtin */
*/ module = pe_load_builtin_module(pcs, wImageName, BaseOfDll, SizeOfDll);
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 (!module) if (!module)
{ {
@ -978,6 +956,31 @@ DWORD64 WINAPI SymLoadModuleExW(HANDLE hProcess, HANDLE hFile, PCWSTR wImageNam
module_set_module(module, wModuleName); module_set_module(module, wModuleName);
if (wImageName) if (wImageName)
lstrcpynW(module->module.ImageName, wImageName, ARRAY_SIZE(module->module.ImageName)); 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) if ((dbghelp_options & SYMOPT_DEFERRED_LOADS) == 0)
module_load_debug(module); module_load_debug(module);
return module->module.BaseOfImage; return module->module.BaseOfImage;