kernel32 是否总是从 System32 加载?
Does kernel32 always load from System32?
- 将 kernel32.dll 从 System32(或 SysWOW64,如果您使用 32 位应用程序进行测试)复制到包含您的 EXE 文件的目录
- 运行 EXE文件
- Process Monitor 显示它甚至懒得先检查 kernel32.dll 的本地文件夹
这似乎与我一直认为的 DLL 的默认行为相矛盾,即首先从本地应用程序目录加载,如果不存在则从 PATH 环境变量加载。但是,对于某些 DLL,如 ntdll 或 kernel32,Windows 似乎总是首先检查 System32。这是预期的行为吗?可以覆盖吗?
(我知道覆盖这将是不好的做法,但想知道这是否真的可能,为了科学!)
经过更多研究,我发现某些 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.
等工具删除资源
Windows 中的 KnownDLLs 功能应该有助于更快地加载常见的 DLL,但它也会强制列表中的所有 DLL 从 system32 加载。
除此之外,kernel32.dll 和 ntdll.dll 在 Windows 的大多数版本中都得到了特殊处理,并且在 CreateProcess 中提前加载,因为用户模式进程的真正入口点是在其中一个模块中。
您可以使用 .local 和清单重定向来覆盖其中的一些。
- 将 kernel32.dll 从 System32(或 SysWOW64,如果您使用 32 位应用程序进行测试)复制到包含您的 EXE 文件的目录
- 运行 EXE文件
- Process Monitor 显示它甚至懒得先检查 kernel32.dll 的本地文件夹
这似乎与我一直认为的 DLL 的默认行为相矛盾,即首先从本地应用程序目录加载,如果不存在则从 PATH 环境变量加载。但是,对于某些 DLL,如 ntdll 或 kernel32,Windows 似乎总是首先检查 System32。这是预期的行为吗?可以覆盖吗?
(我知道覆盖这将是不好的做法,但想知道这是否真的可能,为了科学!)
经过更多研究,我发现某些 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. 等工具删除资源
Windows 中的 KnownDLLs 功能应该有助于更快地加载常见的 DLL,但它也会强制列表中的所有 DLL 从 system32 加载。
除此之外,kernel32.dll 和 ntdll.dll 在 Windows 的大多数版本中都得到了特殊处理,并且在 CreateProcess 中提前加载,因为用户模式进程的真正入口点是在其中一个模块中。
您可以使用 .local 和清单重定向来覆盖其中的一些。