Skip to content

Process Listings and Scans

How to Check

A process listing is the list Windows keeps of what is running, each process with its name, process ID (PID), parent, path, account and start time. It is where most red flags first show, because a wrong path, parent or account sits in plain view. On a clean machine each core process runs from System32 under its usual parent and account, and as many times as it always does. In a memory image, set the list Windows keeps against a scan of memory, which also finds processes that have left the list. Start with the path and parent of every process that carries a Windows name.

What It Shows

A live listing reads each running process from Windows itself, giving the name, PID, parent PID, path, command line, account, session and start time. With the file's signer, these are the fields every normal profile here is compared on, so match the build and set-up first, since normal differs between them. A memory image gives three views to set side by side, which are the kernel's active list, a scan of memory for process objects, and a cross-view of four sources.

Inside Parts It Reads

This check reads these parts, and each page shows what normal looks like.

Three Ways a Memory Image Is Searched for Processes

Windows keeps its running processes in a list, the active process list, with each process record linked to the next. The windows.pslist plugin follows those links, so it shows only what is on the list. The windows.psscan plugin ignores the links and searches the whole memory image for process records, linked or not. So a process that has exited, or one whose record is no longer linked, still turns up in the scan. A process only the scan finds may simply have ended, so read its exit time before calling it hidden.

The Same Memory, Read Two Ways

windows.pslistFollows the Links

  1. System
  2. smss.exe
  3. wininit.exe
  4. services.exe
  5. explorer.exe

It shows only the records on the list.

windows.psscanSearches All of Memory

  • explorer.exe
  • smss.exe
  • notepad.exeExited
  • System
  • A ProcessNot on the List
  • services.exe
  • wininit.exe

It finds every record, linked or not, so a process that has exited and one off the list turn up too.

Volatility 3 PluginHow It Finds ProcessesA Process off the Active ListWhat to Watch For
windows.pslistWalks the kernel's active process listNot shownNames are cut to 14 characters
windows.psscanScans memory for process objectsShown, with an exit time if it endedA row only the scan finds may have exited, so read its exit time first
windows.malware.psxviewSets the active list, a pool scan, a thread scan and csrss.exe's handles side by sideShown, with the views that missed itRead its answers with each exit time before calling a process hidden

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.

  • Is each process what its name claims, with the right path, parent, session, start time and signer?

    On a Running Machine

    In a Memory Image

  • Which account, integrity level and privileges does it run with?

    On a Running Machine

    In a Memory Image

  • Which services does each service host run?

    On a Running Machine

    In a Memory Image

  • Is anything running that the list does not show?

    On a Running Machine

    In a Memory Image

What It Misses

Every way of looking has gaps, so cover these from another source.

  • A live listing shows only what runs at that moment, so a program that ran and exited is gone. Read its creation record instead, such as event 4688 in the Security log (written only when Audit Process Creation is on), Sysmon event 1 or the DeviceProcessEvents table in Defender XDR.
  • Without admin rights a listing cannot read every process's account, path and command line (Microsoft lists SeDebugPrivilege for Win32_Process's ExecutablePath), and a protected process can still refuse, so a blank is unreadable, not a finding.
  • A listing cannot show code running inside a genuine process, which needs the injection checks.

False Positives

These look odd but are normal, so rule them out before you act.

  • A name cut to 14 characters in windows.pslist or psscan, such as SecurityHealth for SecurityHealthSystray.exe, is the kernel's limit, not a misspelling, so read the full name from the image path windows.pstree prints.
  • With Fast Startup on, the default, shutting down hibernates session 0 rather than closing it, so its processes can be days older than the person's sign-in. Judge them against the last full restart.
  • The same path written another way, with a \??\ or \\?\ prefix, as a device path such as \Device\HarddiskVolume3\Windows, or in other capitals, is the same file, so normalise before comparing, but never trim spaces inside a path.

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. Stacking assumes the intruder's file is rare. It misses a tool found everywhere and puts new legitimate software on top, so read each rare path with its signer and parent.

KQLDefender XDR, Advanced hunting
// Process images by path across every device, rarest first; each user's folder is folded so per-user copies stackDeviceProcessEvents| where Timestamp > ago(30d)| extend Path = tolower(FolderPath), Name = tolower(FileName)| extend Path = iff(Path startswith @"c:\users\", strcat(@"c:\users\<user>", extract(@"^c:\\users\\[^\\]+(.*)$", 1, Path)), Path)| summarize Devices = dcount(DeviceId), Starts = count(), Hashes = dcount(SHA1), FirstSeen = min(Timestamp), LastSeen = max(Timestamp) by Path, Name| order by Devices asc, Starts asc| take 100

Sources