SYSTEM_TRACE_HEADER

The SYSTEM_TRACE_HEADER is one of several types of fixed-size header that introduce variable-size data for events that are logged through Event Tracing for Windows (ETW). As with other types of event, those that begin with a SYSTEM_TRACE_HEADER accumulate first in trace buffers. To have these events persist in this raw form for ready inspection, configure the event tracing session to flush the trace buffers to an Event Trace Log (ETL) file.

Documentation Status

The SYSTEM_TRACE_HEADER is not documented, but a C-language definition is published in the NTWMI.H from the Enterprise edition of the Windows Driver Kit (WDK) for Windows 10 version 1511.

Were it not for this relatively recent and possibly unintended disclosure, much would anyway be known from type information in symbol files. Curiously though, type information for this structure has never appeared in any public symbol files for the kernel or for the obvious low-level user-mode DLLs. In the whole of Microsoft’s packages of public symbol files, relevant type information is unknown before Windows 8 and appears in symbol files only for appxdeploymentclient.dll, certenroll.dll (before Windows 10) and windows.storage.applicationdata.dll.

Layout

The SYSTEM_TRACE_HEADER is 0x20 bytes in both 32-bit and 64-bit Windows in all versions that are known to have it at all, i.e., 5.0 and higher. Be aware however that the structure can exist in a so-called compact form that is only the first 0x18 bytes.

Offset Definition Remarks
0x00
union {
    ULONG Marker;
    struct {
        USHORT Version;
        UCHAR HeaderType;
        UCHAR Flags;
    };
};
 
0x04
union {
    ULONG Header;
    WMI_TRACE_PACKET Packet;
};
 
0x08
ULONG ThreadId;
 
0x0C
ULONG ProcessId;
 
0x10
LARGE_INTEGER SystemTime;
last member in compact SYSTEM_TRACE_HEADER
0x18
ULONG KernelTime;
 
0x1C
ULONG UserTime;
 

The first 4 bytes have common elements in all the various Trace Headers. All have the high bit set in the Flags at offset 0x03. Of those that have the two highest bits set, what distinguishes a header as continuing specifically as a SYSTEM_TRACE_HEADER is the HeaderType at offset 0x02:

Value Name Implied Layout
0x01 TRACE_HEADER_TYPE_SYSTEM32 full 0x20 bytes of header followed by 32-bit event data
0x02 TRACE_HEADER_TYPE_SYSTEM64 full 0x20 bytes of header followed by 64-bit event data
0x03 TRACE_HEADER_TYPE_COMPACT32 first 0x18 bytes of header followed by 32-bit event data
0x04 TRACE_HEADER_TYPE_COMPACT64 first 0x18 bytes of header followed by 64-bit event data

Also defined in NTWMI.H are combinations of the Flags and HeaderType, ready for use as a basis for the Marker as the first dword:

Value (x86) Value (x64) Name
0xC0010000 0xC0020000 SYSTEM_TRACE_MARKER
0xC0030000
0xC0040000 COMPACT_TRACE_MARKER

To these markers must yet be added the Version. Though the Version is formally the low word, the kernel treats it as 8-bit. It is presently thought that this Version is not of the header but of the event-specific data that follows the header. Both 0x02 and 0x03 are observed in Windows 10.

The WMI_TRACE_PACKET at offset 0x04 is two words:

Offset Definition
0x00
USHORT Size;
0x02
union {
    USHORT HookId;
    struct {
        UCHAR Type;
        UCHAR Group;
    };
};

The total size of data for the event, i.e., both the fixed-size header and the variable-size event data, is given by the Size member of the Packet, i.e., at offset 0x04 in the header. The HookId at offset 0x06 in the header tells what type of event is logged and determines the meaning of whatever event data follows the header. In the absence of an EVENT_DESCRIPTOR for events that have a SYSTEM_TRACE_HEADER, the HookId is effectively the event identifier (no matter that by the time it gets translated for consumers its Group and Type show as a ProviderId and Opcode). A list of the known Hook IDs for NT Kernel Logger Events is presented separately.