There’s only three weeks to go till Launch Day. Today, we’re going to talk about the Dynamic Link Library (DLL) Loader and Address Space Load Randomization. In Windows Vista and Windows Server 2008, when talking about process and thread creation, it is important to understand the role of the DLL Loader. The user-mode DLL Loader is invoked every time a process or thread is created to complete the following tasks related to the DLL’s required by the process or thread as needed:
- Determine appropriate DLL load order and resolve dependencies
- Load all required DLLs
- Unload DLLs when they are no longer needed
Starting with Windows Vista, there were several improvements made to the DLL Loader that provide benefits such as improved process creation time and fewer reboots as a result of system DLL servicing. Let’s look at each of these in turn beginning with the improved process creation time. When you think about process creation, a significant portion of the creation time is spent resolving DLL dependencies and processing DLL imports. Improvements to import processing algorithms have reduced processing time significantly. For some applications that are heavily dependent on DLL’s, the end-to-end process creation time may be improved by as much as ten percent.
You’re all probably familiar with the fact that in earlier versions of Windows, if you had to update a system DLL, you had to reboot the system. This was because there was no mechanism in place to identify which system service had loaded the DLL in question. Thus, in order for the file update to occur, you had to reboot the entire system to ensure that the older version of the DLL was completely unloaded and the updated DLL was loaded in its place. With Windows Server 2008, the enhanced loader management allows the system to maintain a complete list of services that have loaded a particular DLL. If that DLL is updated, the system can identify and restart the specific services that use that DLL as opposed to rebooting the entire system. Downtime is decreased and overall system uptime is increased – with the added benefit of the system being updated. However, it is important to note that this does not apply to all system DLL’s. System DLL’s such as NTDLL.DLL and Kernel32.DLL will still require a reboot when they are updated.
Now let’s take a look at Address Space Load Randomization, aka ASLR. In earlier versions of Windows, common system components were loaded at fixed locations. This meant that malware authors could use buffer overruns to try to attack a system because they knew which system functions were at specific addresses. ASLR makes it impossible for malware to know where an API is loaded because system DLL’s and executables are loaded at a different location each time the system boots. Early on in the boot process, the Memory Manager picks a random DLL load address from one of 256 64KB-aligned addresses in the 16MB region at the top of the user-mode address space. As DLL’s with the new dynamic-relocation flag in their image header are loaded into a process, the Memory Manager puts them in to memory starting at the image-load bias address and working its way down. Any executables with the dynamic-relocation flag set also load at a random 64KB-aligned point within 16MB of the base load address stored in their image header.
As an example, compare these two instances of notepad.exe on the same system in different boot sessions:
As you can see, the base address for notepad.exe has changed from one reboot session to the next. If you look at some of the other ASLR-enabled DLL files you can see that their addresses have also changed.
One thing that is extremely important to note with regards to ASLR is that the feature only works if the dynamic-relocation flag is set. All Windows Vista and Windows Server 2008 DLL’s and executables have this flag set. However, if this process were to be applied across the board, then legacy applications could break since there may be an assumption within that application code that the developers made regarding where their application loads. With Visual Studio 2005 SP1, there is support for setting this flag so that developers can take full advantage of ASLR. Another key point to remember is that randomizing DLL Load addresses to one of 256 locations does not make it impossible for malware to guess the correct location of a particular API. It does however severely hamper the speed at which a network worm can propagate and prevents malware that only gets one chance at infecting a system from working reliably. Also, the ASLR relocation strategy has an additional benefit in that address spaces are more tightly packed than on previous versions of Windows. This results in larger regions of free memory being available for contiguous memory allocations, thereby reducing the number of page tables that the Memory Manager allocates to keep track of address-space layout.
And with that, Day Six comes to a close. Tomorrow we will go over some aspects of Memory Management, Dynamic Kernel Addressing, Memory Priorities, and some important changes to I/O Processing. Until next time …