SoFunction
Updated on 2025-03-07

C# Detailed explanation of questions about LoadLibrary

Questions about LoadLibrary

The function of the LoadLibrary function in the Win32 API is to load a library file (usually a dll file) and then return a HMODULE handle. You can use two of these handles to call the export function in the dll. Everything seems to be that simple. Let’s consider it more in-depth and ask a few questions.

Use Process Explorer to see the dll loaded by the process, and of course you can also see the dll loaded by using the LoadLibrary function. After a dll is loaded by a process, the dll is manifested as occupied (cannot be changed or deleted). Then the question is, how does LoadLibrary occupy a dll file? Is it opened with the CreateFile function? We are not in a hurry to answer this question. Further, we found that in the handle list of the Process Explorer process [1], there is no handle related to the loaded dll. This problem is in conflict with the previous problem. Since the dll is occupied, why is there no handle related to the occupied dll file?

Don't worry, we will answer the two questions raised above below. But before answering, let’s lay the foundation for knowledge first. We all know that the most direct and easiest way to occupy a file in Windows is to call the CreateFile API function to open the file. Readers can try to write a demo Use CreateFile to open a file. After opening the file, you can see the handle to the loaded file using Process Explorer (note the process integrity level problem in Vista and Win7). Specific reason: CreateFile will create a kernel object, which is related to the opened file. Process Explorer can view the kernel object, and of course you can see the file handle that was opened just now.

With the above knowledge preparation, we can start to answer the second question above. Why does the handle not have the problem of being occupied with the dll file after the dll is loaded? If you read the documentation about Windows kernel objects carefully, you will find that Windows kernel objects are expressed using the HANDLE type in encoding, including files, pipelines, oil tanks, events, etc., and are closed by the CloseHandle function. LoadLibrary returns an HMODULE, which is released by FreeLibrary, which is not a kernel object, and the handle list of Process Explorer will only display the kernel object handle. So this explains the second question above.

Since LoadLibrary does not create a kernel object (object expressed by HANDLE) to occupy the dll file, how does it occupy the file? But it is absolutely certain that it is not opened with CreateFile. If you use CreateFile to open the file, you should be able to see it in the Process Explorer list. To explain this problem, we can try writing a program and debugging it into LoadLibray [2] to see how it occupies the dll file. After gradual and in-depth debugging, it was found that LoadLibrary ultimately called the Windows DDK (Windows Driver Develop Kit) function ZwOpenFile to implement the file occupied. The specific function call stack information is as follows:

       !_ZwOpenFile@24()  + 0xa bytes 

      !_LdrpFindOrMapDll@24()  + 0x2c36 bytes

      !_LdrpLoadDll@24()  + 0x145 bytes    

      !_LdrLoadDll@16()  + 0x74 bytes

      !_LoadLibraryExW@12()  + 0x120 bytes  

      !_LoadLibraryW@4()  + 0x11 bytes      

      !wmain(int argc, wchar_t * * argv)  Line 16 + 0xd bytes       C++

      !__tmainCRTStartup()  Line 552 + 0x19 bytes C

      !wmainCRTStartup()  Line 371 C

      !@BaseThreadInitThunk@12()  + 0x12 bytes

      !___RtlUserThreadStart@8()  + 0x27 bytes  

      !__RtlUserThreadStart@8()  + 0x1b bytes    

ZwOpenFile is a Windows DDK function, which is different from user-state functions such as CreateFile. This function opens a file and occupies it, but does not create a kernel object. So this explains why after loading a dll with the LoadLibrary function, the corresponding dll cannot be seen in the handle list of Process Explorer, and the dll is occupied. In short, it is to use the open file function to open a file, but this function is different from CreateFile and will not create a kernel object handle.

[1] The handle list of the process explorer is: View à Lower Pane View à Handles

[2] Regarding how to debug the method to enter the Windows API, you can check out another article of my article: Debugging the Windows API

This is the article about this detailed explanation of C# LoadLibrary. For more questions about C# LoadLibrary, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!