Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
132 views
in Technique[技术] by (71.8m points)

c++ - DLL redirection using manifests

I need to reliably redirect an applications look up of a specific DLL. Using the app.exe.local approach does not work because local files are ignored if the application has a manifest (embedded or separate file). So I am trying to do DLL redirection by defining the DLL as a private assembly in the manifests.

I have a test application, LoadDll.exe which simply calls

LoadLibrary("C:\EmptyDll.dll");

The LoadDll.exe has the manifest (as a separate file, 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>

The Application folder containing LoadDll.exe (NOT c:) contains the EmptyDll.dll with the embedded manifest.

<?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>

However, LoadDll.exe goes ahead and loads C:EmptyDll.dll, and not the EmptyDll.dll in the application folder.

If you break either manifest (e.g. change the version number in the EmptyDll.dll manifest identity), LoadDll.exe does not load, so the manifest files are being read and processed by windows, but just ignored.

Anyone got any ideas?

Thanks!

Toby

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

So it seems its impossible to redirect calls to LoadLibrary with absolute paths using manifests.

After a lot of playing around with manifests, it seems that once you get past all the bad documentation manifests are actually stupidly simple.

Basically when the executable is loaded windows collects all the related manifests that are linked using the identity and dependency elements. Then for each file element contained in the manifest files, it adds an entry into the activation context:

'name attribute of file element' -> 'absolute path of manifest file' + 'name attribute of file element'

Now when a load library call is made, it searches the activation context map for a key that matches the path argument of load library, and then does the loadlibrary with the value for that key.

So if my application c:foofoo.exe has a dependency to the manifest in c:fooaaaa.manifest, and baa.manifest contains a file element <file name="empty.dll"/>, then the activation context will have a mapping: "empty.dll" -> "c:fooaaempty.dll"

So any calls to LoadLibrary("empty.dll") will be redirected to LoadLibrary("C:fooaaempty.dll").

However, LoadLibrary("c:anotherpathempty.dll") Will not be redirected!

Now to prove my point of how stupidly simple manifest files and activation contexts are. If the file element of baa.manifest was <file name="c:anotherpathempty.dll"/> and you made a LoadLibrary("C:anotherpathempty.dll") call, the LoadLibrary call will be redirected to LoadLibrary("C:fooaaC:anotherpathempty.dll"), yes, a malformed path...

The file element does have an undocumented attribute called "loadFrom", which does what it sounds like, and seems like its perfect to solve this problem. Using loadFrom, I was able to redirect an absolute path loadlibrary call, but it seemed to screw up other dependencies in the executable in weird ways. If someone knows more about how "loadFrom" works I would be very interested.

So how did I solve my problem in the end? By using an incredibly heavy handed approach of DLL Trojaning described at Ethical Hacker. Basically you create a dummy kernel32.dll that redirects all calls to the original kenerl32.dll, except for the LoadLibrary calls, in which you place your own redirection logic. Then in the applications manifest, you place a file element that redirects the kernel32.dll to your dummy. Fun.

All this describes my experiments on Windows Xp Sp2. For extra fun I'm led to believe manifests behave differently on almost every version of Windows.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...