Detect the unloading of DLLs

微笑、不失礼 提交于 2019-12-11 00:25:30

问题


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.

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.

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

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.

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.

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.


回答1:


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

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.

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:

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

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
}

I hope this helps.



来源:https://stackoverflow.com/questions/32288601/detect-the-unloading-of-dlls

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!