检测DLL的卸载

时间:2015-08-29 17:02:25

标签: c++ windows dll loadlibrary

我有特殊要求,我相信别无他法, 即:检测DLL的卸载。我用Google搜索并发现了 a four-years old SO关于此事。我选择了同样的 解决方案:挂钩FreeLibrary

当代码进入MyFreeLibrary时,我将挂钩入口点 指定的模块以相同的方式(内联挂钩)。并在 MyEntryPoint,我将首先调用原始入口点 检查reason参数 - 如果值等于 DLL_PROCESS_DETACH,这意味着此DLL的清理工作是 刚刚完成,它将从地址空间中卸载。 在这一点上,我有机会完成我的工作。它有效。

这就是它?不幸的是,它还没有完成。非常重要 事情被忽视了:依赖。

例如,a.dllb.dllc.dll相关联。当你加载 a.dllb.dllc.dll将首先加载(初始化)。这个 是因为b.dllc.dll列在导入表中 a.dll,它们是a.dll的依赖项。同样,当你卸载 a.dllb.dllc.dll也可以在他们的参考时卸载 计数减少到零。我不知道有关如何的细节 loader找出DLL的依赖关系并卸载它们 FreeLibrary的{​​{3}}页面没有谈到这一点,我很高兴 明白这一点,但我找不到这些信息。

所以主要问题是如何检测依赖项的卸载 一个DLL模块。我希望有同样的机会完成我的工作。

可能的解决方案可能是导入表,找出答案 DLL从其导入表中依赖,并找出 依赖项与其导入表的依赖关系等, 找出所有的依赖关系,钩住所有的入口点,我没有 知道,这听起来很疯狂,我在这里需要一些建议。

1 个答案:

答案 0 :(得分:1)

我为旧的SO问题提供了答案。你现在写:

  

在MyEntryPoint中,我将首先调用原始入口点,然后检查reason参数 - 如果值等于DLL_PROCESS_DETACH,则表示此DLL的清理工作刚刚完成,并且将从中卸载地址空间。

你发现这不是真的。但最简单的解决办法是什么?如果你发现原因是DLL_PROCESS_DETACH后,你测试hModule是否仍然有效怎么办?参见:

How can I tell if a Windows module handle is still valid?

您可以跳过挂钩DLL入口点,不检查DLL_PROCESS_DETACH并始终只测试hModule是否仍然有效。这让我意识到,最好在调用原始FreeLibrary之前检查hModule是否有效,然后测试有效到无效的转换:

[esp+28]

我希望这会有所帮助。