检测DLL的卸载 [英] Detect the unloading of DLLs

查看:260
本文介绍了检测DLL的卸载的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个特殊的要求,我相信没有其他方法,
是:检测卸载DLL。我google了一下,发现了
一个四岁的SO,关于这一点。我选择了相同的
解决方案:Hook FreeLibrary

I have a special requirement, and I believe there is no other way, that is: Detect the unloading of DLLs. I googled it and found out a four-years old SO about this. I have chosen the same solution: Hook FreeLibrary.

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

When code goes into MyFreeLibrary, I will hook the entry point of the specified module in the same way (inline-hook). And in MyEntryPoint, I will call the original entry point first, then check the reason argument - if the value equals to DLL_PROCESS_DETACH, it means that the cleanup work of this DLL is just done, and it's going to be unloaded from the address space. At this point, I have the chance do my job. It works.

这是吗?不幸的是,它还没有完成。一个非常重要的
事情被忽略:dependency。

So that's it ? Unfortunately, it's not finished. A very important thing is overlooked: dependency.

例如, a.dll code> b.dll 和 c.dll 。当您加载
a.dll b.dll c.dll 将首先加载(初始化)。这个
是因为$ b $的导入表中列出了 b.dll c.dll b a.dll ,它们是 a.dll 的依赖项。类似地,当卸载
a.dll b.dll c .dll 也可以卸载,如果它们的引用
计数减少到零。我不知道
加载程序如何发现DLL的依赖项并卸载它们的细节,
FreeLibrary 没有讨论的库/ windows / desktop / ms683152%28v = vs.85%29.aspxrel =nofollow> MSDN 页这个,我很高兴的
理解这个,但我没有找到信息。

For example, a.dll links against b.dll and c.dll. When you load a.dll, b.dll and c.dll will be loaded (be initialized) first. This is because b.dll and c.dll are listed in the import table of a.dll, they are dependencies of a.dll. Similarly, when you unload a.dll, b.dll and c.dll may be also unloaded if their reference count decreased to zero. I don't know the detail about how the loader finds out the dependencies of a DLL and unload them, The MSDN page of FreeLibrary didn't talk about this, I'm glad to understand this but I did't find the information.

所以主要的问题是如何检测卸载依赖关系
的DLL模块。我想有相同的机会来完成我的工作。

So the main problem is how to detect the unloading of dependencies of a DLL module. I want to have the same chance to do my job.

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

A possible solution may be the import table, find out the dependencies of a DLL from its import table, and find out the dependencies of dependencies from their import table and so on, find out all the dependencies, hook all the entry points, I don't know, It sounds crazy, I need some advice here.

推荐答案

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

I contributed answers to the old SO question. You now write:


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

And in MyEntryPoint, I will call the original entry point first, then check the reason argument - if the value equals to DLL_PROCESS_DETACH, it means that the cleanup work of this DLL is just done, and it's going to be unloaded from the address space.

发现这不是真的。但是最简单的修复是什么?如果在找到原因是DLL_PROCESS_DETACH之后,如果hModule仍然有效,会怎么样?请参阅:

You've discovered this isn't true. But what's the simplest fix? What if after you find the reason is DLL_PROCESS_DETACH, you test if the hModule is still valid? See:

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

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

You may be able to skip hooking the DLL entry point, not check for DLL_PROCESS_DETACH and always just test if the hModule is still valid. Which makes me realize, it would be better to check if the hModule is valid before calling the original FreeLibrary, and after and test for a valid to invalid transition:

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

我希望这有帮助。

这篇关于检测DLL的卸载的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆