The Big Picture: Shared Toolboxes

Imagine every cook in a city owning their own copy of a huge cookbook of basic skills: chopping, boiling, baking. That would waste paper. Instead, the city keeps one shared library of skills, and each cook borrows what they need.

Windows does the same. Instead of each program carrying its own code to draw a window, open a file or play a sound, that code lives in shared files called DLLs (Dynamic-Link Libraries). Programs borrow from them when they start (or later, when needed).

   notepad.exe        chrome.exe         game.exe
        \                 |                 /
         +--------+-------+--------+-------+
                  v                v
            kernel32.dll       user32.dll     <- one copy in RAM
         (files, memory...)  (windows, input)    shared by all

8.1 Dynamic Libraries

What it is: A dynamic library is a file of ready-made code (functions) that programs can use without including it. On Windows these files end in .dll. They use the same PE layout as .exe files (Section 2.3), but they have no "start here" for a user; they are toolboxes.

Why DLLs exist:

ReasonBenefit
Save memory and diskMany programs share one copy of common code (the code pages are shared, Section 4.2)
Easy updatesFix a bug in one DLL and every program using it benefits
Smaller programsThe .exe only holds its own logic
Plug-insA program can load extra features at runtime

The opposite is static linking: the library's code is copied into the program when it is built. That makes the .exe bigger and self-contained, but each program carries its own copy.

Famous DLLs found in every Windows process:

DLLWhat it offers
ntdll.dllThe lowest layer; talks to the kernel (system calls)
kernel32.dll (and kernelbase.dll)Files, memory, processes and threads
user32.dllWindows, messages, keyboard and mouse
gdi32.dllDrawing text and shapes
advapi32.dllRegistry and security functions

You may also hear the word module. A module is any file loaded into a process: the .exe itself plus every DLL. Section title "Process Modules" means this list.

8.2 DLL Loading

What it is: Loading a DLL means mapping it into the process's address space (Section 4.2) so its functions can be called. It happens in two ways:

WayWhenHow
Load-time (implicit)While the process startsThe loader reads the program's import table (8.3) and loads every DLL listed. If one is missing, the program won't start ("... was not found" error)
Run-time (explicit)Whenever the program decidesThe program calls LoadLibrary with a DLL name, then GetProcAddress to find a function by name, and FreeLibrary when finished. Used for plug-ins and optional features

Where does Windows look? If the program gives only a name like mylib.dll, Windows searches places in a set order: known system DLLs first, then the program's own folder, then system folders, and so on. A careless search can be tricked: an attacker puts a fake DLL with the same name in a folder searched earlier (DLL hijacking). Modern programs give full paths or restrict the search to avoid it.

Reference counting. Each LoadLibrary adds 1 to a counter in that process; each FreeLibrary subtracts 1. The DLL leaves the process when the counter reaches 0.

Shared RAM, private data. The first time a DLL is loaded on the PC, its code is read from disk into RAM. When a second process loads the same DLL, Windows maps the same RAM pages into it (shared). Each process gets its own private copy of the DLL's changing data (copy-on-write, Section 4.2).

DllMain. A DLL can have a small start-up routine, called when it is loaded or unloaded and when threads are created. Careless work in it can cause deadlocks, so good DLLs keep it tiny.

See the list of loaded modules of a running process:

Get-Process notepad | Select-Object -ExpandProperty Modules |
  Select-Object ModuleName, FileName
tasklist /M /FI "IMAGENAME eq notepad.exe"

8.3 Import Table

What it is: Inside every PE file is an import table: a shopping list that says "I need these functions from these DLLs". For example: "from kernel32.dll I need CreateFileW and ReadFile".

 notepad.exe's import table (simplified)

 +----------------------------------------+
 | DLL: kernel32.dll                      |
 |   - CreateFileW                        |
 |   - ReadFile                           |
 |   - ExitProcess                        |
 | DLL: user32.dll                        |
 |   - CreateWindowExW                    |
 |   - GetMessageW                        |
 +----------------------------------------+

At start-up, the loader:

  1. Reads the list.
  2. Loads each DLL (if not already loaded).
  3. Finds each function's real address in that DLL.
  4. Writes those addresses into a table in the program, called the Import Address Table (IAT).

Afterwards, whenever the program calls ReadFile, it jumps to the address stored in the IAT. That table is the "phone book" filled in at start-up. Because the loader fills it in, the program does not need to know where the DLL ended up in memory.

Some programs use delay-load: the DLL is loaded only the first time one of its functions is called. That makes start-up faster.

8.4 Exported Functions

What it is: The other side of the import table. A DLL has an export table: the list of functions it offers to others. The exports are the DLL's "front desk". Anything not exported stays private inside.

A function can be exported:

  • By name, such as CreateFileW.
  • By ordinal, a plain number in the table (less common, less readable).

When a program imports ReadFile from kernel32.dll, the loader looks in kernel32's export table, finds ReadFile, and reads its location. This is the same job GetProcAddress does for run-time loading.

Sometimes an export is a forwarder: "I don't implement this myself; look in that other DLL." Many of kernel32's functions forward to kernelbase.

Exports can also be data and not just functions, but functions are far more common.

Tools to see imports and exports: Developer tools such as dumpbin /imports (from Visual Studio) or free third-party viewers. You do not need them for this course. The Modules listing from 8.2 is enough.

8.5 Base Address and Relocation

What it is: Every PE file states a preferred base address: the spot in the address space where it would like to be loaded. If that spot is free, all the addresses written inside the file are already correct, and nothing needs fixing.

But the spot may be taken (another module is already there), or Windows may choose a different place on purpose for security (ASLR, Section 2.5). Then the module is loaded elsewhere, and any hard-coded addresses inside it are wrong by some distance. Fixing this is called relocation.

 Preferred: load at 0x10000000      Actual: loaded at 0x20000000
   code says "jump to 0x10001000"      must become "jump to 0x20001000"
   Relocation adds the difference:  +0x10000000

How it works: the file contains a relocation table, a list of all spots inside it that hold absolute addresses. The loader goes through the list and adds the difference to each one.

DetailWhy it matters
Relocation costs timePages that must be changed are no longer identical to the file, so they cannot be shared between processes and each process gets its own private copy
ASLR makes it commonThe same DLL may sit at different addresses in different processes, or after each reboot
Position-independent codeModern 64-bit code mostly uses relative addressing ("jump 200 bytes ahead") so it needs little or no relocation

For Windows system DLLs, ASLR picks a random base once per boot, and every process shares that address for the DLL, which keeps the shared RAM benefit.

You can see a module's base address in PowerShell: (Get-Process notepad).Modules | Select ModuleName, BaseAddress. Run it in two different programs: the same DLL (like kernel32.dll) is usually at the same address in both during one boot, but a different address after the next restart.

Summary

TermPlain meaning
DLLShared file of code that many programs borrow
ModuleAny file loaded into a process (the .exe and every DLL)
Load-time vs run-time loadingAt start-up from the import list vs on demand with LoadLibrary
Import table / IATShopping list of needed functions / the phone book the loader fills in
Export tableThe functions a DLL offers
Base addressWhere a module is placed in the address space
RelocationFixing hard-coded addresses when the module is not at its preferred spot
ASLRRandom placement for security
DLL hijackingTricking a program into loading a fake DLL