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 http://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



             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


                   Line numbers stripped

                   Symbols stripped

                   32 bit word machine




             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?




Comments (5)
  1. Terry Montgomery says:


    I have a question…  I am a long time FoxPro user.  

    I have a train running through my mind as I think about what you’ve described with Vista’s seemingly dynamic rebasing of system dlls at runtime…  Would any of this same concept be implemented in Server 2003?

    We currently use VFP8 for Production.  We are increasingly becoming plagued by a mysterious near unexplainable rash of Error 1104 Error Reading files.  You know, it’s not access, or we would get access denied.  In order to get this error we must have had a valid file handle at some time, however now the file handle has been rendered as invalid all of the sudden.  This seems to occur mostly when people have been talking on the phone and still on the network.  Then they click and bust.

    We were seeing some of these witn Server 2000, however we have found some contributions to NIC’s going bad, others due to timeouts and device sleeping issues.  We have implemented many KB Advices and some efforts within our code base to address the timeouts – keep alive type things…

    Since going to Server 2003 RC2 this problem has increased and it is hurting us badly…

    I’ve observed VFP’s behavior when opening files.  I get something like this from FileMon.exe (SysInternals)…

    VFP Actions:

    IRP_MJ_CREATE Options: Open Acess: All

    FASTIO_QUERY_STANDARD_INFO (Gets Length for Filesize)

    IRP_MJ_READ (0-2048)

    IRP_MJ_READ (0-4096)

    System Actions:

    IRP_MJ_READ (4096-65536)

    Back to VFP:

    FASTIO_LOCK (Excl: Yes Offset: 2147483646 Length:1)



    Note: by reading 0-32 I can tell at this point its really just getting the DBF header…

    FASTIO_READ (0-32)

    FASTIO_UNLOCK (Offset: 2147483646 Length:1)

    Then it starts to work over the FPT file and then the CDX file…

    Could there be any relation to what you are descibing between VFP, XP (Workstations), and Server 2003…

    We’re also considering any File Access Compatibility Layering changes or TCP Stack Changes that may have occurred with Server 2003.  We know something has changed between Server 2000 and Server 2003 that is having a really adverse affect on us.

    Can you please if you’ve any insights that may help us isolate this please share them with me, tmontgomery@dpath.com, thank you.

  2. You can use CreateToolhelp32Snapshot and its family of functions to enumerate the running processes on

  3. CarlWarner says:

    You didn’t mention Terminal Services in your mix.  If you had, I would say the "Error reading file" messages might be attributable to the network redirector stuff under Windows Server 2003.  But, then again, it might apply anyway.  I am no expert on network redirectors and what in the heck it really has to do with anything I might get involved in.  🙂

    You receive an "Error reading file" error message in Windows 2000 Terminal Services


    There are a few MS KB articles that also reference "redirector" specifically for Windows Server 2003 as well.

  4. Cesar Chalom says:

    Here are some of the links that I often visit regarding VFP9 SP2 and Sedna. The official Microsoft Visual…

  5. These routers have changed the way i look at things the technology has moved so far.

Comments are closed.

Skip to main content