DLL Image base addresses are the same in XP, different on Vista

When you start a program on your Windows XP computer, a process is created and several DLLs (Dynamic Link Libraries) are loaded into the process.

Some DLLs are “system” DLLs, such as Kernel32.dll, GDI32.dll, User32.dll.

These DLLs are loaded early in the process start time, because they provide basic operating system functionality, such as input/output, graphics, memory functions.

Each process has a 4 Gigabyte (2 ^ 32) address space, and DLLs are loaded into this address space starting at a particular base address, with a range extending to the size required for that DLL.

If the same DLL is loaded into multiple processes, and it has the same base address, then the entire DLL loaded range is the same for each of these processes and so each process can share the same physical mapping (see Global Descriptor Table)

However, if the DLL is loaded at different base addresses in some processes than others, then the DLL code needs to be modified (rebased) before it is used by the process. This means the same physical memory can not be used, and thus more physical memory (or paged memory) needs to be used.

These DLL code modifications consist of fixups for jumps within the code. For example, there might be a jump instruction embedded in the DLL code. If it’s a relative jump (i.e. jump 10 bytes back), then it doesn’t have to be patched. If it’s an absolute jump (jump to 0x12345678) then it needs to be patched. See also https://en.wikipedia.org/wiki/Import_Address_Table

When you create a DLL, there is a default base address that is in the DLL header. You can examine this default base address for any DLL:

On WinXP SP2, Start->Visual Studio 2005->Visual Studio Tools->Visual Studio command prompt

D:\>link /dump /headers c:\windows\system32\kernel32.dll | more

Dump of file c:\windows\system32\kernel32.dll

PE signature found

File Type: DLL

FILE HEADER VALUES

             14C machine (x86)

               4 number of sections

        46239BD5 time date stamp Mon Apr 16 08:52:53 2007

               0 file pointer to symbol table

               0 number of symbols

              E0 size of optional header

            210E characteristics

                   Executable

                   Line numbers stripped

                   Symbols stripped

                   32 bit word machine

                   DLL

OPTIONAL HEADER VALUES

    10B magic # (PE32)

            7.10 linker version

           82200 size of code

           70000 size of initialized data

               0 size of uninitialized data

            B5AE entry point (7C80B5AE)

            1000 base of code

          7F000 base of data

        7C800000 image base (7C800000 to 7C8F4FFF)

            1000 section alignment

             200 file alignment

            5.01 operating system version

            5.01 image version

            4.00 subsystem version

          0 Win32 version

           F5000 size of image

             400 size of headers

           F9293 checksum

               3 subsystem (Windows CUI)

               0 DLL characteristics

           40000 size of stack reserve

            1000 size of stack commit

          100000 size of heap reserve

            1000 size of heap commit

               0 loader flags

D:\>link /dump /exports c:\windows\system32\kernel32.dll | find /i "createfile"

         80 4F 00001A24 CreateFileA

         81 50 0000945C CreateFileMappingA

         82 51 0000938E CreateFileMappingW

         83 52 00010760 CreateFileW

        569 238 00064F4D LZCreateFileW

The image base for Kernel32.dll is 0x7c800000

The address of CreateFileW is the sum of the image base (0x7c800000) and the relative address 10760 : 0x7c810760. As you can see from the CreateFile documentation, this API is used to create or open a file. (It also shows that this API is implemented in kernel32.dll.)

A virus writer can depend on this address (0x7c810760) being the same for every Windows XP SP2 machine. Thus a virus can just call code at that address to create or open a file on your machine.

Vista varies the starting address of the system DLLs so that CreateFile will be mapped to a different image base address each time the machine is rebooted, causing virus writers grief.

We’ll talk about how to find the number of modules that are rebased on your system next time.

See also:

Find all statically linked libraries required before your process can start

How to log application API calls using import module addresses

What external code does your EXE depend on?