> ## Documentation Index
> Fetch the complete documentation index at: https://siriusbar.net/llms.txt
> Use this file to discover all available pages before exploring further.

# Phase 4 — Everything Is an Object

> The Windows object model: EPROCESS, ETHREAD, handles, tokens, and the three faces of WinDbg.

This is the part I was actually curious about. Phases 1 to 3 were about moving around Windows; this one is about how the kernel thinks. Back in Phase 1 I said Linux is "everything is a file" and Windows is "everything is an object". Now we make that concrete.

## Everything is an object

On Linux, the unifying abstraction is the file. Processes, devices, sockets, even kernel knobs are reachable as file descriptors and paths under `/proc`, `/sys`, and `/dev`. If I can `open`, `read`, and `write` it, I can reason about it.

Windows does not centre on the file. The kernel's unifying abstraction is the **object**, managed by the Object Manager. Processes, threads, files, registry keys, mutexes, tokens — they are all kernel objects of some type, living in an object namespace, and user-mode code rarely touches them directly. Instead it holds a **handle**: an index into a per-process handle table that points at the real object inside the kernel.

* a file descriptor (Linux) ≈ a `handle` (Windows), but the thing on the other end is a typed kernel object, not necessarily a file.
* browsing `/proc/<pid>` ≈ walking objects in `WinDbg`, which we get to below.

> So the first question on Windows is not "what file is this?" but "which object does this handle reference, and what type is it?".

## Processes are containers, threads are what run

Now the objects with the most "wait, that's different" energy: the things Linux calls tasks. In Windows architecture, `tasks` is strictly split into **processes** (containers) and **threads** (units of execution).

* Process (`nt!_EPROCESS`): a static container. It owns the virtual address space, the handle table (open resources), and the `Access Token` (its security context). Although its name is process, the thing itself never "runs" :D
* Thread (`nt!_ETHREAD`): the schedulable thing. It owns the stack, the register context (`nt!_KTRAP_FRAME`), and scheduling priority. This is the "thing" that executes.

This is where the analogy starts to bend. I am used to a `task_struct` that blurs the line, where a process is really its main thread and extra threads are just more tasks sharing memory. Windows draws the line hard: the `EPROCESS` is the box, the `ETHREAD` is the worker, and the scheduler only ever deals with the worker.

> The process owns the address space, but the thread is what the scheduler actually runs. When dumping a process in `WinDbg`, you don't look for "the task." You look for the `EPROCESS` to find the memory layout, then iterate its `ThreadListHead` to find who is actually executing code.

## Tokens, address space, and VADs

A few more things hang off the `EPROCESS`, and each has a familiar echo:

* `Access Token`: the process's security context — its user, groups, and privileges. This is the credentials side of a Linux process (uid/gid plus capabilities), but bundled as an object the kernel hands around.
* Virtual address space: described by `VAD`s (Virtual Address Descriptors), a tree of what is mapped where. This is the Windows answer to reading `/proc/<pid>/maps`.
* Handle table: the open-resources list, closest to `/proc/<pid>/fd`.

> So the privilege question ("what can this process do?") becomes, on Windows, "what is in this process's `Access Token`?" — and that token is an object I can inspect directly.

## WinDbg has three different faces

`WinDbg` is not one single experience. Which face we use decides what we can even see.

1. **User-mode debugging.** This is the equivalent of `gdb ./a.out`: one process, its memory, its threads.
   > ❌ From here we cannot see `EPROCESS`, kernel `VAD`s, tokens, or the scheduler. It is the wrong face for internals.

2. **Kernel dump analysis.** We open a kernel crash dump (`MEMORY.DMP`) and explore the kernel's view offline:
   * `EPROCESS` and `ETHREAD`
   * `VAD` trees
   * tokens
   * handle tables

3. **Live kernel analysis.** We attach the debugger to a running kernel — the most powerful and the most involved, usually driven from a second machine. A bit of an advanced technique.

Once we are in a kernel face, the workflow matches the mental model. Find the process object, then walk its threads:

```text theme={null}
!process 0 0                  list every EPROCESS
dt nt!_EPROCESS <address>     inspect the container's fields
.process /p <address>         switch into that process context
!thread <address>             inspect a specific ETHREAD
!handle                       walk the handle table
```

> The loop is always the same: locate the `EPROCESS`, read its address space and token, then iterate `ThreadListHead` to find the `ETHREAD` that is actually running code. We never schedule a process on Windows; we schedule a thread, and the debugger makes us prove we understand that.

That closes the tour. Four phases in, the through-line holds: Linux hands me one abstraction, the file, and Windows hands me another, the object — and most of "learning Windows internals" is retraining that one reflex.
