ProcMon as… an API Monitor

April 8, 2020 in Malware Analysis

A competition for the most important research tool on Windows platform is not necessary – ProcMon will always win.

Why?

It helps us with research, troubleshooting, and it still works after so many years, and despite so many changes introduced to Windows during this time.

And it still can surprise you.

In this post I briefly describe ProcMon functionality that many people may not be aware of. Actually, two features that offer a very interesting functionality.

The first one is Stack Trace.

Any event you see caught by ProcMon has an associated Stack trace that you can explore by double clicking the event of interest, and selecting the ‘Stack’ tab:

This is pretty cool as it helps researches to find out where the possible access to an interesting object (a key, a file, etc.) comes from -i.e. from main .exe or loaded .dll.

The second feature is the export to XML that may include the aforementioned stack trace (tick the ‘Resolve stack symbols’ as well – it will resolve addresses to actual function names if these are available in symbols).

This will create a HUGE XML file.

And a very interesting one…

It includes sections for process list and events. The first one includes a list of processes and their properties:

  • Time
  • Processes name
  • Process ID
  • Parent process ID
  • Command Line
  • Integrity
  • Owner
  • Base Addresses
  • Modules Loaded

And the second one lists the actual events:

  • Time
  • Process Name
  • Process ID
  • Operation
  • Path
  • Result
  • Location
  • Detail

followed by the stack trace – all frames one bye one:

  • Depth
  • Address
  • Path
  • Location

With this data, and taking selective stack trace entries, it’s very easy to convert it to a timeline that resembles a log from an API Monitor…

A small snippet of data:

<?xml version="1.0" encoding="UTF-8"?>
<procmon><processlist><process>
<ProcessIndex>100</ProcessIndex>
<ProcessId>160</ProcessId>
<ParentProcessId>2880</ParentProcessId>
<ParentProcessIndex>101</ParentProcessIndex>
<AuthenticationId>00000000:00071cd1</AuthenticationId>
<CreateTime>132308446793816226</CreateTime>
<FinishTime>0</FinishTime>
<IsVirtualized>0</IsVirtualized>
<Is64bit>1</Is64bit>
<Integrity>High</Integrity>
<Owner>user</Owner>
<ProcessName>Procmon64.exe</ProcessName>
<ImagePath>C:\Users\user\AppData\Local\Temp\Procmon64.exe</ImagePath>
<CommandLine>"C:\Users\user\AppData\Local\Temp\Procmon64.exe" /originalpath "C:\tools\Procmon.exe"</CommandLine>
<CompanyName>Sysinternals - www.sysinternals.com</CompanyName>
<Version>3.53</Version>
<Description>Process Monitor</Description>
<modulelist>
<module>
<Timestamp>132308446979926644</Timestamp>
<BaseAddress>0x2360000</BaseAddress>
<Size>77824</Size>
<Path>C:\Windows\system32\wbem\wbemsvc.dll</Path>
<Version>10.0.14409.1005 (rs1_srvoob.161208-1155)</Version>
<Company>Microsoft Corporation</Company>
<Description>WMI</Description>
</module>
...
<eventlist>
<event>
<ProcessIndex>105</ProcessIndex>
<Time_of_Day>11:38:18.1001657</Time_of_Day>
<Process_Name>Explorer.EXE</Process_Name>
<PID>2192</PID>
<Operation>CreateFile</Operation>
<Path>C:\Users\user\AppData\Local\Temp\Procmon64.exe</Path>
<Result>SUCCESS</Result>
<Detail>Desired Access: Read Attributes, Disposition: Open, Options: Open Reparse Point, Attributes: n/a, ShareMode: Read, Write, Delete, AllocationSize: n/a, OpenResult: Opened</Detail>
<stack>
<frame>
<depth>0</depth>
<address>0xfffff8800116d067</address>
<path>C:\Windows\system32\drivers\fltmgr.sys</path>
<location>FltAcquirePushLockShared + 0x907</location>
</frame>
…
<frame>
<depth>1</depth>
<address>0xfffff8800116f9aa</address>
<path>C:\Windows\system32\drivers\fltmgr.sys</path>
<location>FltIsCallbackDataDirty + 0x20ba</location>
</frame>
…
<frame>
<depth>39</depth>
<address>0x78e7c521</address>
<path>C:\Windows\SYSTEM32\ntdll.dll</path>
<location>RtlUserThreadStart + 0x21</location>
</frame>
</stack>
</event>

The Stack Trace covers the stack from user and kernel mode.

You may be wondering now… what happens when Procmon detects API calls from a code injected into another process?

Great question…

They stand out as hell… as Procmon is unable to resolve them:

<ProcessIndex>105</ProcessIndex>
<Time_of_Day>11:38:34.0276039</Time_of_Day>
<Process_Name>Explorer.EXE</Process_Name>
<PID>2192</PID>
<Operation>RegOpenKey</Operation>
<Path>HKCU\Software\Microsoft\Windows\CurrentVersion\Run</Path>
<Result>SUCCESS</Result>
<Detail>Desired Access: Write, Query Value, Enumerate Sub Keys, Delete</Detail>
<stack>
<frame>
<depth>0</depth>
<address>0xfffff80002e3e550</address>
<path>C:\Windows\system32\ntoskrnl.exe</path>
<location>MmUnmapViewInSessionSpace + 0x7a0</location>
</frame>
…
<frame>
<depth>12</depth>
<address>0x16000067c</address>
</frame>
</stack>
</event>

That last address 0x16000067c?

Bingo! It’s a code injected by malware.

Now, all you have to do is to filter this data by PID, address range, etc. I am not a XML wizard so I take a shortcut and parse this data in a line-by line way using a simple state machine; still, the result is pretty… API Monitorish…

105 svchost.exe 0x2600475cc 9 RegQueryKey HKCU SUCCESS
105 svchost.exe 0x2600475cc 12 RegOpenKey HKCU\
Software\Microsoft\Windows\CurrentVersion\Run SUCCESS
105 svchost.exe 0x2600475cc 8 RegSetInfoKey HKCU\
Software\Microsoft\Windows\CurrentVersion\Run SUCCESS
105 svchost.exe 0x2600471dd 13 RegCloseKey HKCU SUCCESS
105 svchost.exe 0x2600471dd 14 RegOpenKey HKCU SUCCESS
105 svchost.exe 0x260047291 7 RegEnumKey HKCU SUCCESS
105 svchost.exe 0x260047291 7 RegEnumKey HKCU SUCCESS

And the bonus:

You could convert these events and incorporate them as comments into IDA, extract IOCs (e.g. by filtering over ‘CreateFile’, etc.), and probably do a few more interesting things (support PE dumping of injected code?)

Comments are closed.