Call LoadLibrary from DllMain

MSDN says:

It should not call the LoadLibrary or LoadLibraryEx function (or the function that calls these functions), because it can create dependency loops in the loading order of the DLL. This can cause the DLL to be used before the system executes its initialization code.

I tried calling LoadLibrary from DllMain and nothing happened.

The only problem I see is that the loaded DLL will use the functions in my DLL before the rest of my DllMain will execute.

Why shouldn't I call LoadLibrary in DllMain?

EDIT:

Well, I realized that I should not call LoadLibrary in DllMain just because I have to believe MSDN, like other believers (I saw some wrong things, but I have to forget about them too).
And because something can happen in new versions of Windows (although nothing has changed in the last ten years).

But can anyone show code that will reproduce something bad that happens when LoadLibrary is called in DllMain? In any existing Windows OS?
Not only a call to one initialization function of the same name inside another, but LoadLibrary in DllMain?

+1
source share
5 answers

Your argument for continuing this seems to be to rephrase:

Microsoft says don't do this, but mine It seems like one test case is working, so I donโ€™t understand why no one should do this.

You work with the big assumption: you assume that the underlying implementation of the Windows boot loader will never change. What if the bootloader is changed in "Windows 8" so that your code no longer works correctly? Microsoft is now blamed for this, and they must include another compatibility hack to get around the code that they told you not to write in the first place.

Follow the recommendations. They are not so simple to complicate your life, they are there to guarantee that your code will work just as well in the Windows of the future as it is now.

+12
source

There are simple and even not so simple circumstances in which the LoadLibrary call from DllMain is completely safe. But the design is that DllMain hopes not to change the list of loaded modules.

Although storing the loader lock does indeed limit what can be done in DllMain, this indirectly applies only to the LoadLibrary rule. The corresponding purpose of blocking the bootloader is serialized access to the list of loaded modules. Although NTDLL runs on this list in one thread, owning a bootloader lock ensures that the list is not changed by NTDLL code that runs in another thread. However, locking the bootloader is a critical section. It does nothing to stop the same thread from re-acquiring the bootloader lock and changing the list.

It would not matter if NTDLL completely retained itself while working on the list. However, NTDLL provides for the use of other code in this work, as in the initialization of a recently loaded DLL. Each time NTDLL gets called out while working on a list, there is a choice for design. In general, there are two options. One of them is to stabilize the list and release the bootloader lock, call outside, then get the bootloader lock and resume work on the list, as if from scratch, because an external call could change it. Another is to lock the bootloader and trust the called code not to do anything that modifies the list. Thus, LoadLibrary becomes unavailable in DllMain.

Not that the bootloader lock did anything to stop DllMain from calling LoadLibrary, or even that the bootloader lock itself makes such a call unsafe. Instead, while retaining the loader lock, NTDLL trusts DllMain not to call LoadLibrary.

For comparison, consider the DllMain rule that you do not expect synchronization objects. Here, locking the bootloader plays a direct role in making it unsafe. Waiting for a synchronization object in DllMain establishes the ability to lock. All that is needed is that another thread already contains the object that you expect, and then this other thread calls any function that will wait for the loader to lock (for example, LoadLibrary, as well as functions such as the seemingly harmless GetModuleHandle )

Desiring to stretch or break DllMain rules can be mischievous or even stupid. However, I must point out that Microsoft is at least partly to blame for asking people how strong or significant these rules are. In the end, some of them were not always documented clearly and decisively, and when I last watched, they were still not documented in all situations where they are definitely needed. (The exception I have in mind is that, at least until Visual Studio 2005, MFC programmers writing DLLs were asked to put their initialization code in CWinApp :: InitInstance, but they were not told that this code obeys DllMain rules.)

In addition, it would be a little rich for any Microsoft to speak as if the DllMain rules should be followed without any questions. There are examples where Microsoft programmers break the rules and continue even after breaking the rules, which caused serious problems with the real world.

+12
source

As stated in http://msdn.microsoft.com/en-us/library/ms682583%28VS.85%29.aspx :

Themes in DllMain contain a bootloader lock, so no additional DLL files can be dynamically loaded or initialized.

Greetings

+8
source

I was working on a case that might require the use of LoadLibrary in DllMain, so I found this discussion when researching. Update about this from my experience today.

Reading this can be really scary http://blogs.msdn.com/b/oleglv/archive/2003/10/28/56142.aspx . There are not only various locks, but also the order in which the libraries were passed to the linker. Fact that one bi

Now I tried this with vc9 under win7. That is how it is. Depending on the order in which libs are passed to the linker using LoadLibrary, it works or not. However, the same with vc11 under win8 works correctly, not paying attention to the order of links. Application Verifier does not blame it.

I do not urge to use it in this way right now and everywhere :) But just FYI, if it will be the same with win10 and beyond - this can be of great utility. In any case, it seems that the bootloader mechanism under win8 has undergone some notable changes.

Thanks.

+3
source

Very late, but still,

If you download other libraries in stream 1 (T1), DllMain will call these other DllMain libraries; which in itself is normal, but they say that their DLLMain creates a thread (T2) and expects events to complete T2.

Now, if T2 loads the library while it is being processed, the loader will not be able to obtain a lock, since T1 has already received it. Since T2 is suspended on LoaderLock, it will never signal that a T1 event is waiting.

Which will lead to a dead end.

Such a scenario could be more likely, I think that there is a widespread opinion that we cannot be sure which code will be executed in other libraries, so do not do this.

0
source

Source: https://habr.com/ru/post/1274766/


All Articles