这似乎与我一直认为的DLL的默认行为相矛盾,即首先从本地应用程序目录加载,如果它没有从PATH环境变量加载。但是,对于像ntdll或kernel32这样的某些DLL,Windows似乎总是首先检查System32。这是预期的行为吗?它可以被覆盖吗?
(我知道压倒这将是不好的做法,但想知道它是否真的可能,对科学来说!)
答案 0 :(得分:2)
Windows中的KnownDLLs功能应该有助于加快加载常见的DLL,但它也会强制列表中的所有DLL从system32加载。
除此之外,kernel32.dll和ntdll.dll在大多数Windows版本中都得到了特殊处理,并且在CreateProcess中提前加载,因为usermode进程的真正入口点在其中一个模块中。
您可以使用.local和清单重定向来覆盖其中一些。
答案 1 :(得分:0)
经过更多的研究,我发现某些DLL如kernel32.dll或user32.dll无法正常覆盖的原因是因为它们是已知的DLL - Windows有一个常用的DLL列表,如这些会自动默认为System32版本,而不是首先检查应用程序文件夹的默认行为。
如果要解决此问题,例如要创建代理DLL,则需要在应用程序目录中包含两个文件: applicationName.exe.local 和 applicationName.exe。 manifest 其中 applicationName 是您的EXE文件的名称。
这些必须是清单文件的内容:
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity version="1.0.0.0" name="redirector" type="win32" />
<file name="kernel32.dll" />
</assembly>
assemblyIdentity标记旨在提供有关应用程序版本号和名称的信息,但我们基本上可以忽略它。重要的部分是文件标记,它指定要在本地加载的文件。将kernel32.dll
替换为您要在本地加载的DLL。
此外,Windows仅在重新启动时或在修改EXE文件时刷新.manifest文件的内容,因此您只需在某个十六进制编辑器中打开EXE文件,擦除第一个字符并将其添加回来并保存。 ..等以刷新清单文件。如果您显示文件似乎被忽略,请执行此操作。