今天用IceSword研究DLL的注入时遇到一个奇怪问题。
当我调用LoadLibrary时,不知道什么原因(后来发现,可能是手痒了,多按了几下),用FreeLibrary,都释放不了DLL。
后来经过我多次试验,发现以下规律:
当我多次调用LoadLibrary时,然后再调用FreeLibrary,最后用IceSword查看了目标进程的模块,发现注入的DLL未Unload!!!
但多次调用FreeLibrary时,DLL能Unload!!最后试验得出,LoadLibrary 与 FreeLibrary调用的次数要相等,才能Unload。
Oh,my god!!! 虽然解决了问题,但不知道根本原因啊!不甘心!为了查出真凶,不得不去查了一下全是英文的MSND。
后来去查了MSDN,发现
以下是MSDN的说明:
The system maintains a per-process reference count for each loaded module. A module that was loaded at process initialization due to load-time dynamic linking has a reference count of one. The reference count for a module is incremented each time the module is loaded by a call to LoadLibrary. The reference count is also incremented by a call to LoadLibraryEx unless the module is being loaded for the first time and is being loaded as a data or image file.
The reference count is decremented each time the FreeLibrary or FreeLibraryAndExitThread function is called for the module. When a module's reference count reaches zero or the process terminates, the system unloads the module from the address space of the process. Before unloading a library module, the system enables the module to detach from the process by calling the module's DllMain function, if it has one, with the DLL_PROCESS_DETACH value. Doing so gives the library module an opportunity to clean up resources allocated on behalf of the current process. After the entry-point function returns, the library module is removed from the address space of the current process.
简要的说就是每调用一次LoadLibrary内部计数会加1,每调用一次FreeLibrary内部计数减1,当内部计数为0时释放DLL。
by:pDaren