检测dll卸载

Detect the unloading of DLLs

本文关键字:卸载 dll 检测      更新时间:2023-10-16

我有一个特殊的要求,相信没有别的办法,即:检测dll的卸载。我谷歌了一下就知道了一个四岁的孩子。我也选择了同样的方式解决方案:钩FreeLibrary

当代码进入MyFreeLibrary时,我将钩住的入口点以同样的方式指定模块(inline-hook)。而在MyEntryPoint,我先呼叫原入口点检查reason参数-如果值等于DLL_PROCESS_DETACH,这意味着这个DLL的清理工作是刚刚完成,它会从地址空间中被卸载。在这一点上,我有机会做我的工作。它的工作原理。

就这样吗?不幸的是,它还没有完成。一个非常重要的有一点被忽略了:依赖性。

例如,a.dll链接到b.dllc.dll。当你加载时a.dll, b.dllc.dll将首先被加载(初始化)。这是因为b.dllc.dll列在?的导入表中a.dll,它们是a.dll的依赖项。同样,当你卸载时a.dll, b.dllc.dll也可以被卸载,如果它们引用计数减少到零。我不知道具体是怎么加载器找出DLL的依赖项并卸载它们FreeLibrary的MSDN页面没有讨论这个,我很高兴我明白这个,但是我没有找到相关信息。

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

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

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

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

你已经发现这不是真的。但最简单的解决办法是什么?如果在您发现原因是DLL_PROCESS_DETACH之后,您测试hModule是否仍然有效呢?看到:

如何判断一个Windows模块句柄是否仍然有效?

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

if (moduleWasValid && !moduleStillValid)
{
    // process module unloaded
}