所以看来不可能将呼叫重定向到LoadLibrary
使用清单的绝对路径。
经过多次使用清单后,似乎一旦你克服了所有糟糕的文档清单,实际上就变得非常简单了。
基本上,当加载可执行文件时,Windows 会收集使用标识和依赖元素链接的所有相关清单。然后,对于清单文件中包含的每个文件元素,它会在激活上下文中添加一个条目:
'name attribute of file element' -> 'absolute path of manifest file' + 'name attribute of file element'
现在,当进行加载库调用时,它会在激活上下文映射中搜索与加载库的路径参数匹配的键,然后调用Loadlibrary
以及该键的值。
所以如果我的应用程序c:\foo\foo.exe
依赖于清单c:\foo\baa\baa.manifest
, and baa.manifest
包含一个文件元素<file name="empty.dll"/>
,那么激活上下文将具有映射:"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")
,是的,一条畸形的路径......
file 元素确实有一个名为“loadFrom”的未记录属性,它的作用正如听起来的那样,并且似乎非常适合解决这个问题。使用 loadFrom,我能够重定向绝对路径 loadlibrary 调用,但它似乎以奇怪的方式搞砸了可执行文件中的其他依赖项。如果有人了解更多有关“loadFrom”如何工作的信息,我会非常感兴趣。
那么我的问题最后是怎么解决的呢?通过使用令人难以置信的 DLL 特洛伊木马方法,描述于道德黑客。基本上,您创建一个虚拟 kernel32.dll,它将所有调用重定向到原始 kenerl32.dll,但 LoadLibrary 调用除外,您可以在其中放置自己的重定向逻辑。然后在应用程序清单中,放置一个文件元素,将 kernel32.dll 重定向到您的虚拟文件。乐趣。
这一切描述了我在Windows Xp Sp2上的实验。为了获得额外的乐趣,我相信清单在几乎每个版本的 Windows 上都有不同的行为。