Process Trees and Call Chains
A process tree puts each process under the one that started it, so a pair that never belongs together stands out. A shell under a service, or anything at all under lsass.exe, can give a break-in away at a glance. On a clean machine the core processes always start under the same parents, and a person's programs under explorer.exe or the terminal they opened. Live views and memory link a process to its recorded parent ID alone, which Windows reuses, so rebuild a chain from creation records where they exist. Check the parent and its start time first, because a parent that started after its child is not its parent.
What It Shows
A tree puts each process under the one that started it, so a pair that never belongs together stands out. Creation records, such as event 4688 in the Security log, Sysmon event 1 and the DeviceProcessEvents table, are written while the parent runs, so they name launchers that have exited. Live views and memory keep only a parent PID that a newer process may reuse, so join creation records on unique process IDs where a record has them.
Inside Parts It Reads
This check reads these parts, and each page shows what normal looks like.
Where Each Creation Record Keeps the Parent
Each kind of creation record names the parent in its own fields, and only some carry a value unique enough to join a whole chain without the reused-PID trap. Windows writes events 4688 and 4689 to the Security log only when Audit Process Creation and Audit Process Termination are on. Sysmon writes events 1 and 5 to Microsoft-Windows-Sysmon/Operational on machines running Sysmon, and DeviceProcessEvents comes from devices onboarded to Defender for Endpoint.
| Record | Fields That Name the Process | Fields That Name Its Parent | Join a Chain On |
|---|---|---|---|
| Security event 4688 | New Process ID, New Process Name | Creator Process ID, Creator Process Name (Windows 10 and later) | Nothing unique, since both IDs are hexadecimal PIDs, so pair each with the computer and the time |
| Sysmon event 1 | Process | Parent | ProcessGuid and Parent |
| Device | Process | Initiating | ProcessUniqueId and Initiating |
| Security event 4689 and Sysmon event 5 | Process ID and Process Name, then Process | None | The exit time, since a parent that ended before its child started cannot be its parent |
Live and in Memory
Each question has the tools that answer it on a running machine, and in a memory image, a copy of its memory saved to a file.
Who started this process, and is that parent still the same process?
On a Running Machine
- Get-CimInstance Win32_Process (documentation, opens in a new tab)Live Machine A PowerShell command built into Windows. Asked for Win32_Process, it lists each process with its parent and command line.
Get-CimInstance -ClassName Win32_ProcessParentProcessId and CreationDate, where the ID can belong to a later process that reused it, so a parent that started after its child is not its parent. Generic.(documentation, opens in a new tab)Live Machine A Velociraptor artifact. It is a ready-made question Velociraptor asks of running machines, named from general to specific. Pstree means process tree. Each process's call chain across many machines, from live parent PIDs, so a reused PID shows as a wrong parent unless a process tracker runs.System. Pstree - Defender for Endpoint live response (documentation, opens in a new tab)Live Machine Part of Defender for Endpoint. It opens a command console on one machine from the Defender portal, so you can list its processes from your desk.
processesIts processes command lists the running processes from the Defender portal. Microsoft does not list its output fields, so check the JSON output for a parent process ID before you build a tree from it.
In a Memory Image
windows.pstree(documentation, opens in a new tab)Memory Image A Volatility 3 plugin. It is one check run on a saved copy of a Windows machine's memory. pstree means process tree. Builds the tree from the active list by recorded parent PID with no start-time check, so it shows the same wrong parent a live tool does.windows.pslist(documentation, opens in a new tab)Memory Image A Volatility 3 plugin. It is one check run on a saved copy of a Windows machine's memory. pslist means process list. Each process's create time beside its parent's, to catch a parent that started after its child.
- Get-CimInstance Win32_Process (documentation, opens in a new tab)Live Machine A PowerShell command built into Windows. Asked for Win32_Process, it lists each process with its parent and command line.
What did a process start, including children that have already ended?
On a Running Machine
Device(documentation, opens in a new tab)Logs and Records A Defender XDR table. It holds the records Defender for Endpoint keeps of what happened on each machine, and you search it with KQL. Each creation with its parent and grandparent by name, and ProcessUniqueId and InitiatingProcessUniqueId to join a whole chain.Process Events Windows.(documentation, opens in a new tab)Live Machine A Velociraptor artifact. It is a ready-made question Velociraptor asks of running machines, named from general to specific. A tracker fed by kernel events that remembers exited processes, but only from the moment it starts.Events. Track Processes ETW - Defender for Endpoint investigation package (documentation, opens in a new tab)Live Machine A bundle of lists and logs Defender for Endpoint collects from one machine when you ask for it. Its Processes folder holds a list of the processes running at collection, to read offline beside the live tree.
In a Memory Image
windows.psscan(documentation, opens in a new tab)Memory Image A Volatility 3 plugin. It is one check run on a saved copy of a Windows machine's memory. psscan means process scan. Children that have ended but whose process objects are still in memory, with create and exit times.
Can the recorded parent be trusted?
On a Running Machine
Windows.(documentation, opens in a new tab)Live Machine A Velociraptor artifact. It is a ready-made question Velociraptor asks of running machines, named from general to specific. Compares the parent each new process claims with the process that created it, from kernel process events, as processes start.ETW. Detect Process Spoofing
In a Memory Image
windows.pstree(documentation, opens in a new tab)Memory Image A Volatility 3 plugin. It is one check run on a saved copy of a Windows machine's memory. pstree means process tree. Shows only the recorded parent, so it cannot tell a parent set on purpose from the real creator.
What It Misses
Every way of looking has gaps, so cover these from another source.
- A live tree and windows.pstree link each process to its recorded parent PID, so an exited launcher shows as no parent, and a reused PID as the wrong one.
- Trackers, Sysmon and EDR hold nothing from before they started, so a process older than the sensor has no creation record.
- A parent can be set on purpose when a process is created, so pair the tree with telemetry that records the real creator.
False Positives
These look odd but are normal, so rule them out before you act.
- csrss.exe, wininit.exe, winlogon.exe and explorer.exe show no parent in a live tree, because their launchers (a session's copy of smss.exe, and userinit.exe for explorer.exe) exit by design, and creation records still name them.
- An elevated program's recorded parent is the program that asked for it, though a SYSTEM service created it, because User Account Control sets that parent on purpose.
Before You Start
Agree these with the machine's owner before you begin.
- Velociraptor's Windows.Events.TrackProcesses installs Sysmon with a configuration it downloads, which changes the machine, so agree it before you start it.
- Windows.Events.TrackProcessesETW and Windows.Events.TrackProcessesBasic need no Sysmon, and only one tracker should run at a time.
Proves These Red Flags
This check is a step in confirming each sign below.
Hunt It
The same hunt is written for four tools, so pick the one you use. Defender XDR and Sentinel queries are in KQL, which you paste into Advanced hunting in the Defender portal or into Sentinel's Logs page. Splunk queries are in SPL, for its Search page, and Velociraptor queries are in VQL, which you run as a hunt.
Needs Defender for Endpoint on every device. The Initiating columns name the parent as it ran, so an exited launcher still shows. A rare chain is a lead, not a verdict, and Microsoft does not say whether a parent set on purpose or the real creator lands in these columns, so test that before trusting them.
// Who starts each command shell and script host: grandparent, parent and child, rarest chains firstDeviceProcessEvents| where Timestamp > ago( 30d)| where FileName in~ ( "cmd.exe", "powershell.exe", "pwsh.exe", "wscript.exe", "cscript.exe")| summarize Devices = dcount( DeviceId), Starts = count( ), FirstSeen = min( Timestamp), LastSeen = max( Timestamp), Example = take_any( ProcessCommandLine) by InitiatingProcessParentFileName, InitiatingProcessFileName, FileName| order by Devices asc, Starts asc| take 100Sources
- Microsoft Learn: event 4688, a new process has been created (opens in a new tab)
- Microsoft Learn: event 4689, a process has exited (opens in a new tab)
- Microsoft Sysinternals: Sysmon (opens in a new tab)
- Microsoft Learn: Win32_Process class (opens in a new tab)
- Microsoft Tech Community (Ask the Performance Team): WS2008: Startup Processes and Delayed Automatic Start (opens in a new tab)
- Ask the Performance Team blog: WS2008: Terminal Services Architecture (opens in a new tab)
- Microsoft Learn: DeviceProcessEvents table (opens in a new tab)
- Microsoft Learn: investigate devices with live response (opens in a new tab)
- Microsoft Learn: collect an investigation package (opens in a new tab)
- Microsoft Learn: ASIM process event schema (opens in a new tab)
- Microsoft Learn: use ASIM parsers (opens in a new tab)
- Velociraptor: Generic.System.Pstree (opens in a new tab)
- Velociraptor: Windows.Events.TrackProcesses (opens in a new tab)
- Velociraptor: Windows.Events.TrackProcessesETW (opens in a new tab)
- Velociraptor: Windows.Events.TrackProcessesBasic (opens in a new tab)
- Velociraptor exchange: Windows.ETW.DetectProcessSpoofing (opens in a new tab)
- Volatility 3: windows.pstree (opens in a new tab)
- Volatility 3 source: pstree.py (opens in a new tab)
- Volatility 3: windows.pslist (opens in a new tab)
- Volatility 3: windows.psscan (opens in a new tab)
- MITRE ATT&CK T1134.004: Access Token Manipulation: Parent PID Spoofing (opens in a new tab)
- Splunk Security Content: Sysmon EventID 1 data source (opens in a new tab)