Event tracing for Windows (ETW) is a lightweight
logging facility first introduced with Windows 2000. Originally
intended as a software diagnostic, troubleshooting and performance
monitoring tool, it was greatly expanded in Windows Vista to create a
The basic architecture of ETW has three discrete components:
providers, controllers, and consumers. The providers supply the trace
data, controllers control capture sessions, and the consumers process
the data returned from the providers. Figure 1 shows an overview of
Figure 1: ETW Architecture
Windows 7 has more than 600 providers installed by default, many of
which provide verbose trace data. ETW data can be used to conduct
research into almost any area of the OS without the need for a
debugger. A default Windows installation ships with all the tools
needed to capture ETW data, but these tools are somewhat inflexible.
Another drawback is that a different tool is usually needed when
analyzing the captured data.
Prior to making the decision to create an entirely new project,
research was conducted to see if there was an existing project that
would work. Several projects were found, with KrabsETW from
Microsoft and Google’s pyetw
looking the most promising. Neither of these were quite right,
however, since KrabsETW is not written in Python and therefore not
compatible with existing projects, and pyetw is no longer maintained.
We found simple programmatic access to ETW using Python was missing.
Pywintrace is a
Python package developed by the FireEye Innovation and Custom
Engineering (ICE) team to fill the need for a flexible wrapper around
Windows APIs to accelerate ETW research. Using Python’s ctypes, the
team created a module that can create and control a capture session,
as well as process trace events. The package contains three main classes:
- EventProvider – Wraps interactions with ETW providers
- EventConsumer – Consumer to process messages emitted from ETW
- ETW – Main class for ETW captures
Using pywintrace is simple, and it can be extended as needed to fit
nearly any desired capture scenario. Typically, a user would create an
instance of the ETW class to begin capturing data. Figure 2 shows a
simple example of this.
Figure 2: Simple capture script
In Figure 2, the ETW provider “Some Provider” with GUID
“11111111-1111-1111-1111-111111111111” is being captured, and the
resultant message data is written to the console. The run function in
Figure 2 is a helper function that will process the messages returned
by the system. If desired, a user may specify their own callback
function and process the messages however they choose.
The example in Figure 2 is simple, but shows how easy pywintrace is
to use. For more examples, see the examples directory of the
Capturing Interesting Data
While there are many interesting providers to investigate, a blog
published by Microsoft demonstrated the usefulness of the Microsoft-Windows-WinINet
provider on Windows 7. Another interesting WinInet provider, Microsoft-Windows-WinINet-Capture,
was added with Windows 10. Using pywintrace the ICE team was easily
able to perform an ETW capture using both. Since the ETW messages are
delivered chronologically by the system, there is no need for
special processing when using multiple providers. Figure 3 shows some
of this capture data.
Figure 3: ETW traffic capture
At a minimum, each message contains a message ID, an associated
event type name, description, task name, and an EventHeader. In Figure
3 the first message (ID 108), a Microsoft-Windows-WinINet provider
message, shows a request handle being created for the server at
‘www.google.com’. Of note is that domain specific information is
returned, and is emitted from several other providers as well –
without the need for a Layered Service Provider (LSP) or driver.
In the second message (ID 2001), a Microsoft-Windows-WinINet-Capture
provider message, shows the request data being sent to the server. The
‘payload’ field of this message is a hex stream of the plaintext
traffic. The decoded data is shown in Figure 4.
Figure 4: Decoded HTTPS traffic
It should be noted that this capture was performed on a Windows 10
machine using the Edge browser. Other browser and OS combinations may
provide different results. This information can be very useful,
however, since it could be used to detect malicious activity that
would normally be masked by a layer of encryption.
Capturing Malicious Activity
Figure 5 shows a snippet of a WinINet capture of traffic generated
by a malware sample in a controlled environment.
Figure 5: Malicious traffic
Here the malware is seen beaconing out to its command and control
(C2) server and requesting a web page. This single message shows the
URL of the page being requested as well as the Process ID and Thread
ID that originated the malicious activity. From this message, the URL
could be used to determine if the request was malicious and the
process / thread information could be used to track down the malware –
especially in cases of process hollowing or DLL injection.
ETW provides a very powerful lightweight trace mechanism
conveniently baked into Windows. Among other things it can be used to
potentially detect malicious activity on an endpoint. Using pywintrace
to capture ETW data is simpler than using multiple tools to do the
same job, and since it is written in Python it is easy to modify for
whatever is needed. This makes the job of slogging through the
hundreds of ETW providers much easier, and accelerates efforts to find
Download pywintrace today!
Special thanks to the entire ICE team. ICE is a small, highly
trained, team of engineers that incubate and deliver capabilities that
matter to our products, our clients and our customers. ICE is always
looking for exceptional candidates interested in solving challenging
Also, thanks to Microsoft for their extensive blog posts and
documentation on ETW.