DLL文件加载两次通过清单的DLL重定向 [英] DLL file loaded twice with DLL redirection through manifest
问题描述
我在。
bp kernel32!ActivateActCtx
。现在找到罪魁祸首
- 找到导致DLL加载的最简单的方法是使用< a href =http://technet.microsoft.com/en-us/sysinternals/bb896645 =nofollow>进程监视器。您可以观察包含
python25的
或详细资料 dll (用于COM查找)。双击一个条目实际上将显示一个堆栈跟踪(您需要首先设置符号搜索路径,同时设置MS的PDB服务器)。python25.dll - 有时,从上面获得的堆栈跟踪可能是从一个新线程产生的。为此,你需要WinDBG。这可以是另一个话题,但足以说你可以
sxe ld python25
,并看看其他线程正在做什么(!findstack MyExeModuleName
或〜* k
)。
现实世界解决方案
使用 LoadLibraryW ://codefromthe70s.org/mhook22.aspxrel =nofollow> Mhook 或 EasyHook 。你可以完全用你的自定义逻辑替换该调用。你可以在午饭之前完成这个,找到生活的意义。
I'm including python.h
in my Visual C++ DLL file project which causes an implicit linking with python25.dll
. However, I want to load a specific python25.dll
(several can be present on the computer), so I created a very simple manifest file named test.manifest:
<?xml version='1.0' encoding='UTF-8' standalone='yes'?>
<assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'>
<file name="python25.dll" />
</assembly>
And I'm merging it with the automatically embedded manifest file generated by Visual Studio thanks to:
Configuration Properties -> Manifest Tool -> Input and Output -> Additional Manifest Files
-->$(ProjectDir)\src\test.manifest
python25.dll
is now loaded twice: the one requested by the manifest, and the one that Windows should find through its search order.
Why is that happening and how can I just load the DLL file pointed by the manifest?
After exhaustive battle with WinSxS and DLL redirection, here's my advice for you:
Some background
Various things can cause a DLL to be loaded under Windows:
- Explicit linking (
LoadLibrary
) -- the loader uses the current activation context of the runningexe
. This is intuitive. - Implicit linking ("load time linkage", the "auto" ones) -- the loader uses the default activation context of the depending DLL. If
A.exe
depends onB.dll
depends onC.dll
(all implicit linkage), the loader will useB.dll
's activation context when loadingC.dll
. IIRC, it means if B'sDllMain
loadsC.dll
, it can be usingB.dll
's activation context -- most of the time it means the system-wide default activation context. So you get your python DLL from%SystemRoot%
. - COM (
CoCreateInstance
) -- this is the nasty one. Extremely subtle. It turns out the loader can look up the full path of a DLL from registry using COM (underHKCR\CLSID
).LoadLibrary
will not do any searching if user gives it full path, so the activation context can't affect the DLL resolution. Those can be redirected with thecomClass
element and friends, see reference. - Even though you have the correct manifest, sometimes someone can still change the activation context at run time using the Activation Context API. If this is the case, there is usually not much you can do about it (see the ultimate solution below), this is just here for completeness. If you want to find out who is messing with the activation context, WinDbg
bp kernel32!ActivateActCtx
.
Now on to finding the culprit
- The easiest way to find out what causes a DLL to load is to use Process Monitor. You can watch for "Path containing
python25.dll
" or "Detail containingpython25.dll
" (for COM lookups). Double clicking an entry will actually show you a stack trace (you need to set the symbol search paths first, also set MS's PDB server). This should be enough for most of your needs. - Sometimes the stack trace obtained from above could be spawned from a new thread. For this purpose you need WinDBG. That can be another topic, but suffice to say you can
sxe ld python25
and look at what other threads are doing (!findstack MyExeModuleName
or~*k
) that causes a DLL to load.
Real world solution
Instead of fiddling with this WinSxS thing, try hooking LoadLibraryW
using Mhook or EasyHook. You can just totally replace that call with your custom logic. You can finish this before lunch and find the meaning of life again.
这篇关于DLL文件加载两次通过清单的DLL重定向的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!