Skip to main content
Xsec

Windows Internals

Published on 10 min read

Updated on

Seriesevasion
Part 1 of 3
In this series27 min read in total
  1. Windows Internals
  2. EDR Internals
  3. EDR Neutralization

Follow a Windows operation from its user-mode API to kernel objects, managers, and execution constraints.

Windows Internals becomes tedious when presented as a list of structures. This article instead follows one operation: an application thread requests access to a resource, the system translates the request, validates its context, routes a request, and retains the state required to execute it.

At each layer, the path answers three questions:

  • which component owns the contract;
  • which data crosses the boundary;
  • which conclusions are stable, and which depend on the observed build.
Technical diagram
LAYERED ARCHITECTURE: User-mode APIs reach kernel services through a controlled transition.WINDOWS INTERNALS · PRIVILEGE BOUNDARIESLAYERED ARCHITECTUREUser-mode APIs reach kernel services through a controlled transition.USER MODEKERNEL MODEsyscallPROCESSApplicationCode and librariesNATIVE APIntdll.dllSystem stubsWINDOWS KERNELntoskrnl.exeExecutive · kernelEXECUTIVEManagersObjects · I/O · memoryMODULESDriversDevice stacksABSTRACTIONHAL · hardwareInterrupts · DMAPRIVILEGE BOUNDARY · SYSTEM CONTRACT · EXECUTIVE · DRIVERS · HARDWARE
Conceptual user-mode and kernel-mode domains. The exact components traversed depend on the operation and driver stack.How to read the diagramFollow the request from left to right. An application first calls an API in its process. A Native API routine in `ntdll.dll` can prepare the system transition. In the kernel, `ntoskrnl.exe` and drivers enforce the operation's contract, while the HAL isolates part of the hardware-specific detail.

Crossing the user-mode and kernel-mode boundary

An application runs in user mode, inside an isolated address space. It uses libraries that expose Win32 or more specialized interfaces. Those interfaces can validate arguments, adapt formats, and, when the operation requires a kernel service, reach a Native API routine exported by ntdll.dll.

The system transition changes privilege level, but it does not turn the application into kernel code. ntoskrnl.exe resumes execution at a controlled entry point, validates arguments according to the requested service, and invokes the relevant manager: objects, processes, memory, input/output, or configuration.

The Hardware Abstraction Layer (HAL) isolates some platform details, especially around interrupts and hardware access. Drivers participate in device stacks or call supported kernel interfaces. Running in kernel mode gives them high impact, but does not exempt them from Interrupt Request Level (IRQL), memory, or object contracts.

This architecture establishes where privilege transitions occur. It does not yet describe the durable state on which the kernel operates. Following an operation over time requires separating process and thread objects from their accompanying user-mode structures.

Processes and threads: separating roles

Technical diagram
TWO DOMAINS, SEVERAL OBJECTS: Executive, dispatcher, and user-mode structures have distinct roles.PROCESSES AND THREADS · RELATED STRUCTURESTWO DOMAINS, SEVERAL OBJECTSExecutive, dispatcher, and user-mode structures have distinct roles.KERNEL MODEUSER MODEcontainsrelatescontainsuser-mode referencethread TEBEXECUTIVEEPROCESSToken · handlesaddress spaceEMBEDDEDKPROCESSDispatcher stateschedulingEXECUTIVE THREADETHREADThread contextEMBEDDEDKTHREADScheduler statePROCESSPEBModulesparametersTHREADTEBUser-mode stateSTABLE RELATIONSHIP · CONCEPTUAL ROLES · BUILD-SPECIFIC FIELDS AND OFFSETS
Conceptual relations among EPROCESS, KPROCESS, ETHREAD, KTHREAD, PEB, and TEB. Internal fields and offsets vary by build.How to read the diagramAn `EPROCESS` object represents the process at the executive level and embeds a `KPROCESS` for scheduling state. Each associated `ETHREAD` embeds a `KTHREAD`. The Process Environment Block (PEB) and Thread Environment Block (TEB) reside in user-mode address space and expose a different category of state.

EPROCESS is the opaque process object used by the kernel. Microsoft documents its role and supported routines that accept a pointer to it, but not a contract allowing drivers to modify its fields freely. Offsets displayed by a debugger are therefore observations specific to the loaded symbols and build.

Conceptually, EPROCESS carries executive-level process state and embeds a KPROCESS associated with dispatching and scheduling. A thread is represented by an ETHREAD object that embeds a KTHREAD for kernel execution state. These relations help explain the model; their layouts are not a stable driver ABI.

The Process Environment Block (PEB) and Thread Environment Block (TEB) reside in user mode. The PEB exposes information related to the process and loader; the TEB carries per-thread state. A security tool can read them in some contexts, but their user-mode location means they do not replace the authority of kernel objects.

Handles connect the process to objects such as files, events, sections, or registry keys. A handle is not the object itself: it is an entry in a handle space associated with granted rights. The process primary token also supplies security context for many access checks.

These structures describe who executes and which objects it can reach. They do not say when a thread actually obtains a processor. The next mechanism is therefore the scheduling lifecycle.

Scheduling: from ready thread to wait

Technical diagram
STATE TRANSITIONS: The scheduler selects a ready thread; waits remove it from the CPU.SCHEDULING · THREAD LIFECYCLESTATE TRANSITIONSThe scheduler selects a ready thread; waits remove it from the CPU.dispatchpreemptwaitexitsatisfiedback to readyELIGIBLEReadyPriority queueCPURunningExecuting threadBLOCKEDWaitingI/O · object · timerEXITTerminatedDeferred cleanupSCHEDULERDispatcherPriority · affinitySIGNALWakeBecomes readyREADY · DISPATCH · RUNNING · WAIT · WAKE · TERMINATE
Simplified thread lifecycle. Windows has additional states and transitions that depend on the execution path.How to read the diagramA ready thread can be dispatched to a processor. Preemption makes it schedulable again. Waiting for I/O or an object blocks it until the condition is satisfied, after which it becomes ready. Termination removes that thread from the scheduling cycle.

Windows uses priority-based preemptive scheduling. A ready thread is eligible to execute. Once dispatched to a processor it runs; preemption can make it ready again. Waiting for I/O, a dispatcher object, or a timer removes it from the processor until the condition is satisfied.

Thread priority and current IRQL are different concepts. Priority helps the scheduler choose among ready threads. IRQL is a per-processor execution level that masks some interrupts and constrains permitted kernel operations. An ordinary thread runs at PASSIVE_LEVEL even when its scheduling priority is high.

Scheduling explains when code runs, but not where its instructions and data reside. Windows interposes a virtual address space and memory manager for that purpose.

Virtual memory: translating an address and recovering content

Technical diagram
FROM ADDRESS TO CONTENT: A virtual page can be resident, recoverable, or materialized on demand.VIRTUAL MEMORY · PAGE RESIDENCYFROM ADDRESS TO CONTENTA virtual page can be resident, recoverable, or materialized on demand.validinvalidPROCESSVirtualaddressRead · writeTRANSLATIONPage tablesPTE entryRESIDENTPhysical framePFN databasePAGE FAULTMemorymanagerResolves sourceMEMORYStandby · zeroSoft faultSTORAGEPage filePrivate dataSECTIONMapped fileFile bytesVIRTUAL ADDRESS · PTE · WORKING SET · PFN · PAGE FILE · MAPPED FILE
Conceptual address translation and possible page sources. Page-table formats depend on architecture and configuration.How to read the diagramPage tables translate the virtual address. A valid entry references a physical frame tracked in the PFN database. Otherwise, the memory manager may satisfy the fault from an in-memory list, the page file, or the bytes of a mapped file.

Each process operates on virtual addresses. Architecture-defined page tables translate those addresses into physical-memory frames while a page is resident. The Page Frame Number (PFN) database tracks physical-frame state; a process working set describes the pages currently resident for that process under memory-manager policy.

An invalid entry does not necessarily mean that the data is absent. A page fault can be satisfied from an in-memory list, a private page stored in the page file, or the bytes of a mapped file. The exact source depends on the mapping type and current state.

DefinitionWhat does “the pages of a file” mean?

A file is conceptually a stream of bytes, not a container that already stores “memory pages.” The phrase refers to fixed-size ranges of those bytes when a section maps the file into virtual memory. Each virtual page then corresponds to a file offset. If its content is not resident, the memory manager can read the corresponding range from the file.

The memory manager therefore establishes how a buffer becomes available to the CPU. It does not by itself transport a request to the file system or hardware. That transport belongs to the input/output model.

Input/output: request down, completion up

Technical diagram
PATH OF A FILE OPERATION: The request travels down the stack; status returns to the caller.INPUT/OUTPUT · REQUEST AND COMPLETIONPATH OF A FILE OPERATIONThe request travels down the stack; status returns to the caller.syscallstatus and dataAPPLICATIONCreateFileWKernel32.dllKernelBase.dllNATIVE APINtCreateFilentdll.dllKERNELI/O ManagerIRP_MJ_CREATEFILE STACKMinifilters+ NTFSMetadataVOLUME STACKVolume+ storageDevice requestDEVICEHardwareDMA · interruptWIN32 · NATIVE API · IRP · FILE SYSTEM · VOLUME · STORAGE · COMPLETION
Simplified file-operation path. Present minifilters, volume drivers, and storage drivers vary by configuration.How to read the diagram`CreateFileW` is a Win32 API exposed by `Kernel32.dll` and commonly forwarded through `KernelBase.dll`. `NtCreateFile` is the Native API entry in `ntdll.dll`. After the system transition, the I/O manager builds the request, then the driver stack processes it downward before completion travels upward.

To open a file, an application can call CreateFileW. The API is exported by Kernel32.dll, declared in fileapi.h, and linked through Kernel32.lib; depending on the build, the export can forward its implementation to KernelBase.dll. The corresponding Native API, NtCreateFile, is exported by ntdll.dll and declared in winternl.h.

After the system transition, the I/O manager in ntoskrnl.exe builds a request. In the Windows Driver Model (WDM), this is generally represented by an I/O Request Packet (IRP). An open operation carries the IRP_MJ_CREATE major code. Each driver in the stack receives parameters for its level and can process or pass the request downward.

A file path can traverse minifilters, the file system, volume drivers, and storage drivers. This list is conceptual: actual components depend on configuration, device type, and operation. The request travels toward the device; status, byte count, and any data return through completion routines.

Direct Memory Access (DMA) lets some devices transfer data without making the CPU copy every byte. Memory Descriptor Lists (MDL) and mapping mechanisms describe buffers according to driver and platform contracts.

The I/O model explains how a request reaches its provider. It is not enough to decide whether the caller has the required rights. Before returning a useful handle, Windows must compare caller security context with object policy.

Access checks: computing handle rights

Technical diagram
DECIDING GRANTED RIGHTS: Caller context is compared with the object's policy.SECURITY · ACCESS CHECKDECIDING GRANTED RIGHTSCaller context is compared with the object's policy.yesnoREQUESTObject + rightsDesired accessCALLERAccess tokenSID · groupsprivilegesOBJECTSecuritydescriptorDACL · SACLKERNELAccess checkComputes maskALLOWEDHandle grantedEffective rightsDENIEDAccess deniedFailure statusAUDITSACLIf configuredTOKEN · SID · PRIVILEGES · DESCRIPTOR · DACL · SACL · ACCESS MASK
Conceptual access-check model. Privileges, Mandatory Integrity Control, and object-type rules can add conditions.How to read the diagramThe token carries the caller's Security Identifiers (SID), groups, and privileges. The security descriptor carries the Discretionary Access Control List (DACL) and may carry a System Access Control List (SACL) for auditing. The check computes granted rights before handle creation.

An access token contains the user’s and groups’ Security Identifiers (SID), as well as privileges. A security descriptor identifies the owner of a securable object and can contain a Discretionary Access Control List (DACL), which allows or denies rights, and a System Access Control List (SACL), which configures auditing.

The check compares desired access with caller context and object rules. Other mechanisms can participate, including privileges, Mandatory Integrity Control, and object-type-specific checks. On success, the returned handle carries the rights actually granted; it does not automatically confer every possible right on the object.

WinDbg observation: an internal field is not a contract

WarningIsolated lab only

The following captures come from a high-integrity kernel-debugging session. Directly modifying an EPROCESS bypasses supported interfaces, can break reference counts, and can destabilize the target. The purpose is to show the boundary between a documented object and a build-specific layout, not to present an administration method.

The first view establishes the general WinDbg session context.

WinDbg session connected to a Windows target
Lab observation: kernel-debugging session used to inspect process objects.

The !process 0 0 cmd.exe command recovers the process-object address for cmd.exe.

WinDbg process command output for cmd.exe
Lab observation: the `!process` extension returns the target process EPROCESS address for this boot.

dt nt!_EPROCESS Token queries symbols for the current build. The visible offset must never be reused as a universal constant.

EPROCESS structure and Token field displayed in WinDbg
Build-specific observation: `Token` field type and offset resolved from the loaded symbols.

The same enumeration finds the System process object, used here only to compare two fields.

WinDbg process command output for System
Lab observation: System process EPROCESS address in the current session.

The field has type _EX_FAST_REF, an object reference combining an aligned pointer and reference-count bits. Reading only the address without understanding those bits produces an incorrect interpretation.

System token EX_FAST_REF value displayed in WinDbg
Lab observation: `_EX_FAST_REF` representation of the token. The pointer and reference bits must be distinguished.

The next capture shows state after an experimental write. It demonstrates that a kernel debugger can modify the observed layout, not that the layout is a supported interface.

cmd.exe Token field read after a WinDbg modification
Lab observation: reading the modified field. Equal values do not guarantee correct reference accounting or target stability.

Execution then resumes so consequences can be measured on the target.

Target execution resumed in WinDbg
Lab observation: resuming the virtual machine after the experiment. Validation must include stability and side effects.

This case shows why an internal offset must not be confused with an API. One central configuration resource remains: the registry, whose logical names connect to hives and specialized callbacks.

Registry: from logical views to hives

Technical diagram
FROM KEY NAME TO STORAGE: The Configuration Manager connects registry views to loaded hives.REGISTRY · LOGICAL VIEWS AND HIVESFROM KEY NAME TO STORAGEThe Configuration Manager connects registry views to loaded hives.statusUSER MODEReg* APIAdvapi32.dllNATIVE APINt/Zw*ntdll · ntoskrnlKERNELConfigurationManagerKey objectsNOTIFICATIONPre callbackBefore operationNOTIFICATIONPost callbackResulting statusSTORAGEHives+ cellsSYSTEM · SOFTWARERECOVERYLogsStateREG* API · NATIVE API · CONFIGURATION MANAGER · KEY OBJECTS · HIVES · LOGS
Conceptual registry view. Some root keys are views or links to locations managed by the Configuration Manager.How to read the diagramUser-mode APIs in `Advapi32.dll` reach Native API services in `ntdll.dll`, then the Configuration Manager in `ntoskrnl.exe`. It resolves names, key objects, and hive cells. Callbacks registered through `CmRegisterCallbackEx` observe distinct pre and post notification classes.

The registry organizes keys and values into hierarchical views. A hive is a logical group of keys, subkeys, and values with supporting files loaded into memory. Major system hives use files under %SystemRoot%\System32\Config; user profiles have separate files.

Log files participate in consistency and recovery. Cells, indexes, and other internal structures explain a build’s implementation, but applications should use documented APIs instead of depending on their layout.

RegOpenKeyExW and RegSetValueExW are exposed by Advapi32.dll, declared in winreg.h, and linked through Advapi32.lib. They reach Native API services in ntdll.dll, then the Configuration Manager in ntoskrnl.exe.

A filtering driver can call CmRegisterCallbackEx. The routine executes from ntoskrnl.exe, is declared in wdm.h, and is linked through NtosKrnl.lib. It registers a driver-supplied function and altitude. The Configuration Manager then delivers distinct REG_NOTIFY_CLASS values before or after operations. Available data and permitted changes depend on the exact class.

The registry adds configuration state and telemetry. It does not remove the kernel-execution constraints that apply to the callback. Understanding which routines and memory remain safe at that moment requires IRQL.

IRQL and synchronization: context is part of the contract

Technical diagram
HIGHER LEVEL, TIGHTER CONTRACT: IRQL constrains allowed interrupts and safe operations.KERNEL · INTERRUPT REQUEST LEVELHIGHER LEVEL, TIGHTER CONTRACTIRQL constrains allowed interrupts and safe operations.LOW IRQLPASSIVE_LEVELWait permittedpageable memoryAPCAPC_LEVELDelivery restrictedDISPATCHERDISPATCH_LEVELNo waitno page faultINTERRUPTDIRQLDevice-specificTOPHIGH_LEVELMaximum contextRULEBriefCURRENT IRQL · NONPAGED MEMORY · NO WAIT AT DISPATCH_LEVEL · SHORT SECTIONS
Conceptual IRQL hierarchy. Exact values and Device IRQLs (DIRQL) depend on architecture and platform.How to read the diagramAt `PASSIVE_LEVEL`, code can wait and touch pageable memory when its contract allows it. `APC_LEVEL` masks some delivery. At `DISPATCH_LEVEL`, waiting or causing a page fault is no longer allowed. DIRQL values serve device interrupts; `HIGH_LEVEL` is the highest symbolic level.

Interrupt Request Level (IRQL) is per-processor state. Raising IRQL masks some interrupts at lower or equal levels and restricts safe operations. It does not measure a driver’s “power”; it describes execution context.

At PASSIVE_LEVEL, a routine can wait and access pageable memory when its own contract permits. At DISPATCH_LEVEL and above, it must not perform a blocking wait or cause a page fault. Device IRQLs (DIRQL) serve device-interrupt routines. Exact values depend on architecture; HIGH_LEVEL symbolically names the highest level.

KeAcquireSpinLock is a macro declared in wdm.h and linked through Hal.lib under the WDK requirements. It raises the processor to DISPATCH_LEVEL, acquires the spinlock, and returns the old IRQL to the caller. The protected section must remain nonpageable and very short.

An executive resource solves a different problem. ExAcquireResourceSharedLite and ExAcquireResourceExclusiveLite provide a reader-writer lock that can wait. These routines execute from ntoskrnl.exe, are declared in wdm.h, and are linked through NtosKrnl.lib; their contracts require a compatible IRQL and management of normal kernel APC delivery. They are not interchangeable with a spinlock at DISPATCH_LEVEL.

Conclusion

Windows internals form a chain of contracts. An API prepares a request, the Native API crosses the boundary, a manager selects objects and rights, requests move through stacks, and scheduling, memory, and IRQL constrain execution.

This foundation makes the next two articles readable without repeating the same definitions: the EDR internals technical review applies these contracts to sensors, while EDR Neutralization examines the gap between loading trust and authorization in a driver protocol.

References

Use with an AI

Actions