Hybrid DLL Loading

Source: Internet
Author: User

By Scott Currie
Microsoft Corporation

March 2003

Abstract:Compile with Visual C ++. NET and Visual C ++. NET 2003ProgramApplications that create and use a hybrid DLL (a combination of native and Microsoft intermediate language (msil) DLL) may experience deadlocks during loading in some cases. This article describes the problem in detail and describes the next version of Visual C ++. net compiler program and Common Language Runtime (runtime) in the expected solution, and provide the use of visual C ++. NET 2002 and Visual C ++.. NET 2003 tool group. All developers who use the Visual C ++. Net compiler option to build a DLL should read thisArticle. (6 pages in total)

Directory

Introduction
Hybrid DLL
Dllmain restrictions
Managed program code and dllmain
Common Language Runtime loader and dllmain
Long-term solution suggestions
Prepare with existing tools
Conclusion

Introduction

This article describes in detail the problem of loading hybrid DLL. If you use a hybrid DLL in Visual C ++. NET 2002 or visual C ++. NET 2003, the problem may be affected. This white paper illustrates the managed ProgramCode/Machine code model, and describes under what circumstances the hybrid DLL is generated. In addition to the limitation of dllmain, this article describes the rules for the entry point of a DLL to a valid job, and also shows that the managed program code executed within dimain may violate the dimain restriction. This article also discusses the current mixed DLL LoadingAlgorithmThe new hybrid DLL loading algorithm is described. It is expected that the next version of the Compilation Program and runtime will be released, and the loading problem will be corrected. Finally, this white paper provides information about how to use visual c ++. NET 2002 and Visual C ++. NET 2003 tools to solve the problem.

HybridDLL

Before exploring the technical reasons behind the mixed DLL loading problem, you must first understand the mixed DLL and the conditions under which they are generated. This is important. Visual c ++. Net compilers can generate both machine code (such as x86 machine commands) and managed program code (msil ). The compiled program or user can decide which type of program code to generate on each function. That is to say, a single DLL or EXE can simultaneously contain some machine code and some managed program code.

Native images, whether it is DLL or EXE, refer to images that all functions are implemented using machine code. This is the only image type that can be generated by the visual C ++ compiler before visual c ++. net. Native images are still the most common image types for C ++ users. They are loaded by the OS loader and executed directly on the hardware through some OS operations. Native Images continue to be operated in a fixed manner. The information in this article does not apply to native images.

A pure msil image, whether it is a DLL or EXE, refers to an image in which all functions are implemented using msil. Visual C #. NET and Visual Basic. Net compilers can only generate pure msil images. Furthermore, in some cases, using Visual C ++. Net to compile programs may produce pure msil images. For how to use visual c ++. for more information about how to create a pure image, see Visual Studio. in the NET 2003 file, "producing verifiable components with managed extensions for C ++ 」. The pure msil image is loaded by the Common Language Runtime loader and executed on top of the runtime. Pure msil images are not affected by mixed DLL loading. The information in this article is not applicable to pure msil images.

A hybrid image, whether it is a DLL or EXE, indicates that at least one function is a machine code and at least one function is an image made in msil. When you use the common language runtime compiler option in Visual C ++. NET 2002 and Visual C ++. NET 2003 for compilation, a hybrid image is usually generated. Since the OS does not understand the management program code, and the runtime does not understand the machine code, the OS and runtime must work together to load and execute a hybrid image. This type of interoperability may cause some complex situations and is also the source of mixed DLL loading problems.

Note:Although there are some restrictions on mixed EXE, they are not affected by the mixed DLL loading problem. This document does not apply to mixed exe. This document applies only to hybrid DLL.

DllmainRestrictions

The dllmain entry point function is designed to perform simple initialization and termination. Operations other than simple initialization and termination may result in dead ends and loop dependencies. This restriction is caused by the locking mechanism applied to the OS loader when dimain enters the vertex function execution. This mechanism ensures that the program code in the DLL cannot be executed before the DLL initialization. Moreover, the OS loader lock can avoid multiple threads or processes trying to load the DLL at the same time, because this action may damage the global data structure used during the loading process. To help users prevent problems with their dimain function, the msdn link library records feasible and unfeasible operations performed securely within the DLL entry point. For more information, see dllmain ).

The following operations are considered to be safe within the dimain function:

· Initialize static and global projects.

· Call the function in kernel32.dll. This job is absolutely safe because kernel32.dll must be loaded when dimain is called.

· Create synchronization objects, such as important segments and mutex. For more information, see synchronization objects ).

· Access thread area (TLS ).

In most cases, the following operations are considered unsafe in the dimain function:

· Direct or indirect callLoadlibrary,LoadLibraryExOrFreelibraryFunction.

· Call logon function.

· Call the call form that is located outside of kernel32.dll.

· Communicate with other threads or processes.

The system does not force the rules using the dilmain function. On the contrary, the OS will attempt to detect dead ends or correlation loops, and terminate the process in violation of rules and in case of problems. Generally, the OS does not detect dead ends, but the process stops responding.

ManagedProgram code andDllmain

It is absolutely insecure to execute the manged program code in dimain. This indicates that dimain is not safe in msil implementation, and dimain calls to msil operations directly or indirectly are not safe. If the managed program code is executed within dimain, it is very likely that the program will be terminated.

In several cases, runtime must perform operations not permitted by dimain to ensure correct semantics. The following two chapters provide specific examples of these situations.

Access type not loaded

The managed program code does not need to explicitly load modules or components. Runtime is under private control. Every time a type is accessed, runtime checks to see if the components containing this type have been loaded and executed.Appdomain. If it has been loaded, the type is used as specified. If not loaded, the runtime will automatically callLoadlibrary. Once the component is loaded and initialized, The expected type can be used. In most cases, this automated link library loading operation provides great convenience. However, when the managed program code is executed in dimain, the automatic Link Library Loading Function may violate the dimain rule.

Garbage Collection

Runtime provides a garbage collection mechanism to eliminate the hassle of manual memory management by programmers. Priority garbage collection may cause a dead end when a hybrid DLL is loaded in many cases. For example, when the thread locked by the storage OS loader is in the GC mode first, triggering garbage collection will suspend the thread. If any other thread is executed in cooperative mode and tries to accept the OS loader lock, it will lead to a dead end. In addition, the garbage collection itinerary will also attempt to get the OS loader lock in some cases, for example, when the garbage collection itinerary is set up on the page to write-monitor protection, or monitor the OS Memory loading. If it is executed during dimain, it will certainly lead to a dead end. There are other cases of multi-processor systems that contain multi-garbage collection travel threads, as well as dead ends during dimain. Generally, garbage collection is not safe during dimain or when the storage OS loader is locked.

Common Language RuntimeLoader andDllmain

Unfortunately, in the current implementation, the above conditions may sometimes occur within dimain when the hybrid DLL is loaded. In order to force the management program code and machine code to be executed together, the hybrid image loading algorithm creates a situation where/NoentryYou can run insecure operations on the DLL entry point when the OS loader is locked. Furthermore, even if the DLL has/NoentryOption link. Common Language Runtime 1.0 and 1.1 may also be closed. And/NoentryOption-linked DLL in the next version of the runtime should not be closed.

When you use visual c ++. Net to compile a DLL/CLRRather/Noentry), Will certainly generate the unmanaged dimain entry point. This entry point generated by the compiled program calls the runtime startup code, which loads mscoree. dll and mscorwks. dll. If C Runtime is used (this is a common case), the runtime starts the program code and then calls dllmaincrtstartup. Dllmaincrtstartup initializes the user program code, CRT static project, and global project. After that, dllmaincrtstartup will call the dllmain provided by the user, if so. In hybrid DLL, The dimain provided by the user is usually compiled into msil, which means that the managed program code will be executed when the loader is locked, this causes the possibility of a close as described in the "Access unloaded type" and "Garbage Collection" sections in this article. Even if the user-provided dllmain is implemented using machine code (for example, it is surrounded by # pragma unmanaged in the original file), the managed program code is still determined to be executed in this process, because some of the stub and thunk called during program loading are implemented in the management program code.

Therefore, because the loader operates in the Common Language Runtime 1.0 and 1.1 versions, even though it rarely appears in practice, it may always be accompanied by a hybrid DLL. Worst of all, hybrid DLL that can be operated on most systems are executed during system load and image signing (because security features require more management program code to be executed during component loading), when the system installs the interception program, or the runtime behavior changes due to the service pack or the new version, it is particularly likely to begin to die. All in all, this is a serious problem that must be addressed by all mixed DLL.

In addition, the implementation of the common language runtime loaders 1.0 and 1.1 may also be suspended/NoentryThe same applies when the linker option is specified, for example, when Unmanaged DLL export or unmanaged vtable fixups (vtfixups) is part of a hybrid DLL. These problems should be corrected in the next runtime version, but there is no way to completely remove visual c ++. NET 2002 or visual C ++. NET 2003 Common Language Runtime 1.0 and 1.1 are related to unmanaged export and unmanaged vtfixups. These specific close risks will no longer occur when the same image is executed in the next runtime version. Therefore, Microsoft recommends that you remove unmanaged export and unmanaged vtfixups from the image unless a dead end occurs.

Also note that the component is used. NET Component signing technology will execute a large number of program code, so when signing a hybrid DLL, the probability of all the above cases will also increase.

Long-term solution suggestions

Unfortunately, Microsoft cannot be fully in Visual C ++ because of the range and depth of changes required by the common language runtime, CRT, Visual C ++ compiler and the linker.. NET 2003. Fixing this issue in Visual C ++. NET 2003 may cause instability of other core management functions. Therefore, Visual C ++ groups use visual c ++ for the majority. NET 2002 and Visual C ++. NET 2003 to build a hybrid DLL, develop a solution to solve this problem, and can be executed in the next version of the common language runtime, but the program designer needs to change part of the program code. Next section describes how to handle all the mixed DLL Loading Problems and implement the Visual C ++ in the next version.. Net (Visual Studio. NET 2003) and the next version of Common Language Runtime (after version 1.1) solutions.

In particular, when a new loading time event has been added to the common language runtime, a signal can be sent when a module loads an application domain. This new event is similar to the native dll_process_attach event. When a module is loaded, the common language runtime checks whether the module has a. cctor method in the global scope. Global. cctor is the managed module initialization expression C. This initialization expression is after the native dimain (in other words, outside the loader lock ), but it is executed before any management program code is executed or the management data is accessed from this module. The semantics of the module. cctor is very similar to those of the category. cctors and is defined in ecma c # and common language infrastructure standards.

The goal of this solution is to separate managed and native initialization, so that the core native part that must be executed under the OS loader lock is indeed executed here. The management initialization and non-core native initialization are performed before the module initialization expression and the loader is locked, but before the module is used. Please note that the module. cctor will be taken to the ECMA Committee for Standardization, even if visual c ++ is likely to be the only Microsoft language that later supports Visual Studio. NET 2003.

In addition to providing the managed module initialization expression mechanism to fix the loader lock problem of newly compiled images, this solution also provides some check tools, it is used to prevent unsafe images that may be created using legacy tools during Common Language Runtime execution. The next version of Common Language Runtime will be able to immediately terminate the DLL that tries to execute the managed program code within the lock of the OS loader. This mode can replace non-decisive and insecure behavior by providing sufficient information to correct the decisive failure of the problem. If the application developers use visual c ++. the net 2003 tool cannot handle this problem, or it cannot obtain the next version of the compilation program. There will be a full-process compatibility mode that can be used to allow unsafe mixed DLL execution. Both compatibility and insecure termination modes can be enabled through the xml configuration file of the application. In addition, applications that need to execute insecure hybrid dll can also use the xml configuration file of the application to specify the runtime version (for example, Version 1.1) to be executed on the application ).

Prepare with existing tools

Microsoft has prepared a knowledge base file, which describes the steps required to ensure that the hybrid DLL created using the Visual C ++. NET 2003 tool group can be securely executed with the corrected runtime. This knowledge base file is accessible to http://support.microsoft.com /? Id = 814472. Simply put, this solution needs to be used by the program designer./NoentryAnd manually initialize the DLL when appropriate. The Helper function is provided to simplify manual initialization. Note that the Knowledge Base File describes how to use Visual Studio.. NET 2002 and Visual Studio. NET 2003 tool to build a hybrid DLL steps, and this in the next version of the Common Language Runtime should also be safe to execute. Even if you fully abide by these instructions on the common language runtime in versions 1.0 and 1.1, there is still a small chance of a close. Further kb files will be released at the launch of the product, which will describe solutions to other possible cases. For more information, see the Knowledge Base File.

Conclusion

the Visual C ++ and common language runtime team made engineering choices for mixed (managed and native) DLL loading and initialization when deciding to re-face this problem. Based on factors related to mixed DLL loading, these options negatively affect the reliability of mixed DLL. This article discusses the core technical points that constitute the hybrid DLL loading problem. The Visual C ++. NET 2003 product has confirmed and documented the appropriate solution to this loading problem. This solution improves the security of the hybrid DLL in the Common Language Runtime versions 1.0 and 1.1. Furthermore, this solution ensures full security of the hybrid DLL in the next Common Language Runtime (for example, there is no risk of final knot ). If you cannot use the Visual C ++. NET 2002 and Visual C ++. NET 2003 tool groups to implement the recommended solution, the application may fail in the next version of common language runtime. The next version of Visual C ++. NET and Common Language Runtime is expected to contain a complete correction file for this issue, and in general, no user program code changes are required.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.