我需要可靠地重定向应用程序查找特定 DLL。使用 app.exe.local 方法不起作用,因为如果应用程序具有清单(嵌入或单独的文件),则忽略本地文件。所以我试图通过将 DLL 定义为清单中的私有程序集来进行 DLL 重定向。
我有一个测试应用程序 LoadDll.exe,它只是调用
LoadLibrary("C:\\EmptyDll.dll");
LoadDll.exe 具有清单(作为单独的文件,LoadDll.exe.manifest)
<?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.1"
processorArchitecture="x86"
name="LoadDll"
type="win32"
/>
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="EmptyDll"
version="1.0.0.1"
processorArchitecture="x86"
/>
</dependentAssembly>
</dependency>
</assembly>
包含 LoadDll.exe(不是 c:\)的应用程序文件夹包含带有嵌入式清单的 EmptyDll.dll。
<?xml version='1.0' encoding='UTF-8' standalone='yes'?>
<assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'>
<assemblyIdentity
type="win32"
name="EmptyDll"
version="1.0.0.1"
processorArchitecture="x86"
/>
</assembly>
但是,LoadDll.exe 继续加载 C:\EmptyDll.dll,而不是应用程序文件夹中的 EmptyDll.dll。
如果您破坏任何一个清单(例如更改 EmptyDll.dll 清单标识中的版本号),LoadDll.exe 不会加载,因此清单文件正在被 Windows 读取和处理,但只是被忽略。
有人有什么想法吗?
谢谢!
托比
原文由 WearyMonkey 发布,翻译遵循 CC BY-SA 4.0 许可协议
因此,使用清单使用绝对路径将调用重定向到
LoadLibrary
似乎是不可能的。在玩了很多清单之后,似乎一旦你通过了所有糟糕的文档清单,实际上是非常简单的。
基本上,当加载可执行文件时,Windows 会收集所有使用标识和依赖项元素链接的相关清单。然后对于清单文件中包含的每个文件元素,它会在激活上下文中添加一个条目:
现在,当调用加载库时,它会在激活上下文映射中搜索与加载库的路径参数匹配的键,然后使用该键的值调用
Loadlibrary
。So if my application
c:\foo\foo.exe
has a dependency on the manifest inc:\foo\baa\baa.manifest
, andbaa.manifest
contains a file element<file name="empty.dll"/>
, then the activation context将有映射:"empty.dll" -> "c:\foo\baa\empty.dll"
所以对
LoadLibrary("empty.dll")
的任何调用都将被重定向到LoadLibrary("C:\foo\baa\empty.dll")
。但是,
LoadLibrary("c:\anotherpath\empty.dll")
不会被重定向!现在证明我的观点是简单的清单文件和激活上下文是多么愚蠢。如果 baa.manifest 的文件元素是
<file name="c:\anotherpath\empty.dll"/>
并且您进行了LoadLibrary("C:\anotherpath\empty.dll")
调用,则 LoadLibrary 调用将被重定向到LoadLibrary("C:\foo\baa\C:\anotherpath\empty.dll")
路径错误,是的,路径错误。 ..文件元素确实有一个名为“loadFrom”的未记录属性,它的功能听起来很像,并且似乎完美地解决了这个问题。使用 loadFrom,我能够重定向绝对路径 loadlibrary 调用,但它似乎以奇怪的方式搞砸了可执行文件中的其他依赖项。如果有人更了解“loadFrom”的工作原理,我会非常感兴趣。
那么我最终是如何解决我的问题的呢?通过使用 Ethical Hacker 中描述的极其严厉的 DLL 木马方法。基本上,您创建了一个虚拟 kernel32.dll,它将所有调用重定向到原始 kenerl32.dll,LoadLibrary 调用除外,您可以在其中放置自己的重定向逻辑。然后在应用程序清单中,放置一个将 kernel32.dll 重定向到虚拟对象的文件元素。乐趣。
所有这些都描述了我在 Windows Xp Sp2 上的实验。为了获得更多乐趣,我相信清单在几乎每个版本的 Windows 上的行为都不同。