kernel32是否始终从System32加载?

时间:2017-03-30 16:51:56

标签: windows dll windows-10 kernel32

  • 将kernel32.dll从System32(如果您正在使用32位应用程序进行测试,则为SysWOW64)复制到包含EXE文件的目录
  • 运行EXE文件
  • 进程监视器显示它甚至不用费心去检查kernel32.dll的本地文件夹

这似乎与我一直认为的DLL的默认行为相矛盾,即首先从本地应用程序目录加载,如果它没有从PATH环境变量加载。但是,对于像ntdll或kernel32这样的某些DLL,Windows似乎总是首先检查System32。这是预期的行为吗?它可以被覆盖吗?

(我知道压倒这将是不好的做法,但想知道它是否真的可能,对科学来说!)

2 个答案:

答案 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文件,擦除第一个字符并将其添加回来并保存。 ..等以刷新清单文件。如果您显示文件似乎被忽略,请执行此操作。

  • 在Windows 2000及更低版本中,添加.local文件就足够了 说服它加载本地版本的kernel32.dll。
  • 在Windows XP及更高版本中,您需要使用.manifest文件。
  • 应用程序可以嵌入.manifest文件 它。在这种情况下,您可以使用Stud_PE等工具删除资源。