Process (kernel process ETW)¶
This source records process starts, process exits and executable image
(module) loads from the Windows kernel. FreeDR uses it as the process lineage
backbone. Every other source takes its actor_* columns from the live process
state this source maintains.
| Collector ID | freedr.kernel-process-etw |
| Windows mechanism | Classic kernel providers in the shared ETW system logger session FreeDR-Unified |
| Hunt | events view, event_type IN ('process.start','process.exit','image.load') |
| Rule SQL source name | kernel_process_etw |
| Hot table | kernel_process_etw_v6 |
| Code | crates/freedr-collect-process |
ETW providers¶
| Provider | GUID | Kernel flag | Opcodes used |
|---|---|---|---|
| Process | {3D6FA8D0-FE05-11D0-9DDA-00C04FD7BA7C} |
1 (process) |
1 Start, 2 End, 3 DC_START (rundown), 4 DC_END |
| Image | {2CB15D1D-5FC1-11D2-ABE1-00A0C911F518} |
4 (image load) |
10 Load, 3 DC_START (rundown) |
| Thread | {3D6FA8D1-FE05-11D0-9DDA-00C04FD7BA7C} |
2 (thread) |
1–4. Used only to attribute other sources' events to a process. Never stored. |
Raw events pass through a 256 MiB maximum lifecycle ring (see
ring buffers) and two decode workers.
Event types¶
| event_type | Recorded when | Main fields |
|---|---|---|
process.start |
Process created, or already running at session start (rundown) | pid, parent_pid, session_id, user_sid, user_name, image_path, command_line, parent lineage |
process.exit |
Process ended | pid, image_path, exit_code, actor lineage |
image.load |
EXE/DLL mapped into a process | pid, image_path, image_base, actor lineage |
The source drops thread start and stop and image unload before storage.
They are counted only (lifecycle_thread_start, lifecycle_thread_stop,
lifecycle_image_unload).
Columns¶
| Column | Notes |
|---|---|
pid, parent_pid, session_id |
parent_pid 0 is stored as NULL |
user_sid |
Token SID as S-1-… (start only) |
user_name |
DOMAIN\name looked up when the event is collected. Display only. A 1,024-entry cache is used. |
image_path |
Full DOS path (see below) |
command_line |
Up to 64 KiB (start only) |
image_base |
image.load only |
exit_code |
process.exit only |
is_rundown |
true = the process or image already existed when the session started. The time is the snapshot time, not the real start time. |
parent_image_path, parent_command_line, parent_start_at, grandparent_image_path |
Lineage from FreeDR's live process state, on process.start |
actor_image_path, actor_command_line, actor_start_at, actor_user_sid, actor_user_name |
The process the event belongs to, on process.exit / image.load |
This source does not capture integrity level, token elevation, file hashes or
signatures. Hashes and signatures come from the Artifacts
source, which process.start and image.load paths trigger.
Full image path on process.start¶
The kernel start event carries only a short, possibly truncated image name. FreeDR binds it to the full path from the matching image load:
- The match must happen within 2 seconds, with at most 1,024 pending starts (2 MiB).
- The names must match case-insensitively. When the kernel name is 14 or more characters (EPROCESS truncation), the full path need only start with it.
- If no match arrives (timeout, process exit, PID reuse, session restart, limit reached), the start is stored with the short name.
- NT device paths (
\Device\HarddiskVolumeN\…,\SystemRoot\,\??\) are converted to drive-letter paths. Paths that cannot be mapped are kept verbatim. - Pending starts are lost if the agent crashes.
Noise controls and dedupe¶
| Control | Effect |
|---|---|
| System32 DLL filter | image.load of %SystemRoot%\System32\*.dll is dropped. If the drive mapping is ambiguous, nothing is dropped. |
| Per-process image dedupe | Repeated loads of the same path (same size, checksum and timestamp) in the same process instance are dropped. The ASLR base is ignored. Limits: 65,536 images, 16 MiB, 65,536 processes. Above the limit, events are kept. |
| Event ID dedupe | event_id is a UUIDv5 over the event content. The writer suppresses duplicate IDs. |
There are no ADR-0028 measured exclusions for this source.
Startup inventory¶
- ETW rundown emits
process.startandimage.loadrows withis_rundown = truefor everything already running. - A Toolhelp32 snapshot (up to 262,144 processes) at each session start seeds the in-memory actor and lineage state only. It writes no rows.
Health counters¶
Shared ETW decode (TDH) counters, for example schema_not_found,
required_property_missing, malformed_or_truncated_payload,
cache_capacity_exhausted, plus ring and loss counters (see
Storage & health), and the three lifecycle_* counters
above.
Verification status
The design documents for start-image binding (ADR-0065) and user SID capture (ADR-0053) list native Windows qualification as pending.