The covert way to find the Reference Count of DLL - www.SecurityXploded.com

The Covert Way to find the Reference Count of DLL

About the DLL Reference Count

Reference count or load count of the DLL is the number of times the
DLL is loaded into the process. Each time the DLL is loaded (through
LoadLibrary) into the process its reference count is incremented by 1
and each time the DLL is freed (through FreeLibrary) from the process,
reference count is decremented by 1. When the reference count reaches 0, the
DLL is completely unmapped from the process.

Windows APIs does not give much information about loaded DLLs.
Windows provides Tool Help library to retrieve information about DLLs
loaded into process but it gives very basic information such as name,
handle of DLL. In order to get more information, one need to dig deeper
into the windows world.

How to find the DLL Reference Count?

Reference count for the DLL is stored in the PEB (Process
Environment Block) for that process. PEB contains the linked list of DLL
Module structures which contain complete information about that
particular DLL.

Here are the detailed steps.

1. Get address of PEB block

PEB block for any process is usually found at address 0x7ffdf000.
However there is standard way to get this address. There is undocumented
function ZwQueryInformationProcess from NTDLL.DLL which can be used to
retrieve the PROCESS_BASIC_INFORMATION. The PBI structure is shown
below.

PEB is a big structure hence I cannot dump it here. One of the
member that is interesting to us is PPEB_LDR_DATA which is pointer to
loader data structure containing linked list of loaded modules. Now from
PEB, you can get PEB_LDR_DATA structure as follows.

PEB_LDR_DATA structure contains the pointers to 3 linked lists each
of which list the modules in different order. Now its just a matter of
going through each module by following one of this linked list.

3. Retrieve load count of the DLL.

Now we will go through each of the modules by following the
InLoadOrderModuleList pointer. Information about each of these modules
is retrieved using ReadProcessMemory function. The structure LDR_MODULE
representing each module is given below.

// Go through each modules one by one in their load order.
while( ReadProcessMemory(hprocess, readAddr, &peb_ldr_module,
sizeof(peb_ldr_module), &dwSize) )
{
// Get the reference count of the DLL
loadCount = (signed short)peb_ldr_module.LoadCount;

readAddr = (void *) peb_ldr_module.InLoadOrderModuleList.Flink;
}

If load count for a
DLL is -1 then the DLL is statically linked otherwise its dynamically
loaded.

Where this will be usefull?

There are number of instances when
there is a need to know the reference count of DLL. One typical case
is when you want to free the DLL from the remote process. Many
spyware programs uses the DLL injection or similar technique to get
loaded themselves into the legitimate windows process and remain
hidden from normal user. In order to free such hidden DLLs from that
process one must know its reference count so that it can be
completely freed from that process. Unless the DLL is freed from the
process, it cannot be removed from the disk. For more information on
this, look at the RemoteDLL
project.

Reference count is also useful to determine if the DLL is statically or
dynamically loaded.