ProcMon as… an API Monitor

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?)

Quick & Dirty Sysmon Replacement aka Process Hacker logging

Sysmon is great, no doubt. However… very often an overkill.

Yes, you’ve read this right. I say: who cares about registry writes, process access, driver or module loads, etc. ? What if we just want to log running processes?

Process Hacker comes to our rescue.

The recent versions of this tool include a very handy logging capability that is available not only from a GUI level (CTRL+L keyboard shortcut), but also helps to write stuff that is ‘happening’ directly to a log file – yes, as it happens.

I find it very useful as it helps to monitor unusual activity of the system w/o engaging the full-blown capabilities of Sysmon (performance!). And yes, I do know how weird it sounds… Sysmon cures everything…

How do we set our Process Hacker instance to deliver all this goodness?

We first run Process Hacker with our Admin creds. Then we open Hacker \ Options menu item:

Then choose one of the ‘Notification’ options and either leave it as it is (log everything) or we write down our own rules that can either include or exclude certain paths….

In the below example we include all the process names:

and then we exclude notepad*.exe:

We can include/exclude both processes and services. This is awesome. It’s simple, it’s working.

And if you are curious where the information about these is stored, look for a `ProcessHacker.exe.settings.xml`file that lists the following:

  <setting name="ProcessHacker.ExtendedNotifications.LogFileName">LOGFILEPATH</setting>
  <setting name="ProcessHacker.ExtendedNotifications.ProcessList">PROCESSLIST</setting>
  <setting name="ProcessHacker.ExtendedNotifications.ServiceList">SERVICELIST</setting>

where PROCESSLIST/SERVICELIST has a form of:

  • \e<pattern for exclusion
  • \i<pattern for exclusion

That’s it really… Nothing ground breaking, but a very handy tool for quick & dirty investigations. I find it most useful to detect ‘funny’ Windows 10 services that start ‘out of nowhere’. I then… usually kill them. One by one, you may eventually kill’em all…

Oh yeah.. it may help with malware analysis too 😉 but somehow.. the analysis techniques and priorities changed a lot over last few years…