Level 4 · Chapter 6

The VAD tree

Windows' own map of 'which region of this address space belongs to what purpose' — and why forensic tools rely on it.

Memory management described a process's virtual address space in the abstract. This chapter is about the actual data structure the Memory Manager uses to track what's inside it: the VAD tree.

A map of purpose, not just a map of pages

A VAD (Virtual Address Descriptor) is a node describing one contiguous range of a process's virtual address space — its start and end addresses, its protection (read/write/execute, and combinations), and what kind of memory it represents: a mapped image (an EXE or DLL, per The PE format), a memory-mapped file, a private heap allocation, a thread's stack, and more. The Memory Manager organizes these as a balanced binary tree, keyed by address range, specifically so that given an arbitrary address (say, the target of a page fault, or an address a debugger is inspecting), it can find the relevant VAD in logarithmic time rather than scanning a flat list.

This is a genuinely higher-level structure than a page table: a page table answers "what physical page backs this specific virtual page, right now." A VAD answers a different, more semantically useful question: "what is this range of addresses, conceptually, and what should happen when something touches it" — the actual physical backing for any given page within that range is a separate, lower-level concern the Memory Manager resolves during page fault handling.

Why this distinction matters practically

The VAD tree is exactly what lets the Memory Manager treat a loaded DLL's code section differently from a heap allocation differently from a memory-mapped file, even though all three are, in the end, just ranges of virtual addresses: the VAD for the DLL's code section knows it should be backed by the file on disk and mapped read+execute; the VAD for a heap allocation knows it's private, writable, zero-initialized memory with no file behind it at all. When a page fault occurs, the Memory Manager consults the VAD covering that address to know how to resolve the fault — reading from the image file, zeroing a new page, or something else entirely — rather than treating every fault identically.

A worked example: why memory forensics tools walk the VAD tree

Memory-forensics frameworks analyzing a captured process image lean heavily on VAD-tree reconstruction, because it's the single richest source of "what was this region of memory actually being used for" without needing to guess from raw bytes alone: a VAD flagged as an image mapping points at exactly which file was mapped and where; a VAD for a private, executable, non-image region — memory that's both writable and executable, with no backing file — is a genuinely notable finding, since it's exactly the kind of memory region associated with injected or unpacked malicious code, precisely because legitimate code almost never needs that specific combination of properties.

A common mistake

Conflating a VAD with a page table entry — or assuming they answer the same question — misses the layering here. A VAD can cover a large range and remain a single tree node even while, underneath it, individual pages within that range are independently resident or non-resident, clean or modified, shared or private. The VAD is the higher-level "what is this for" description; the page-table-and-PFN-database machinery underneath (covered as part of Paging & page faults) is the lower-level "where is each specific page right now" bookkeeping.

Where this connects

  • Paging & page faults is where a VAD actually gets consulted, every time a fault needs resolving.
  • The DLL loader is what creates the image-mapping VADs this chapter describes, when a program starts.