PML File Format

October 4, 2025 ยท View on GitHub

PML (Process Monitor Log file) is the file format which Procmon uses to save the logs it has captured to the disk. There is no official documentation of this format so everything here was reverse engineered, and there are a lot of unknown fields.

This file contains information about the operating system, the running processes, their modules, and of course the captured events themselves.

The file starts with a header:

PML Header

OffsetData TypeSize (bytes)Description
0x000char[4]4Magic Signature - 'PML_'.
0x004uint324Version of the PML file. 9 in the current version.
0x008uint324System bitness: 1 if the system is 64 bit, 0 otherwise.
0x00Cwchar_t[0x10]32Name of the computer (that did the capture).
0x02Cwchar_t[0x104]512System root path (e.g. "C:\Windows").
0x234uint324Total number of events in the log file.
0x238uint648? (seems to be unused)
0x240uint648File offset to the start of the events array.
0x248uint648File offset to an array of offsets to all the events.
0x250uint648File offset to the array of processes.
0x258uint648File offset to the array of strings.
0x260uint648File offset to the icons array.
0x268uint648SYSTEM_INFO.lpMaximumApplicationAddress: Maximum User Address
0x270uint324OSVERSIONINFOEXW.dwOSVersionInfoSize: sizeof(OSVERSIONINFOEXW)
0x274uint328OSVERSIONINFOEXW.dwMajorVersion: Major version number of the operating system.
0x278uint328OSVERSIONINFOEXW.dwMinorVersion: Minor version number of the operating system.
0x27Cuint328OSVERSIONINFOEXW.dwBuildNumber: Build number of the operating system.
0x280uint328OSVERSIONINFOEXW.dwPlatformId: Operating system platform.
0x284wchar_t[0x100]512OSVERSIONINFOEXW.szCSDVersion: Indicates the latest Service Pack installed.
0x384uint162OSVERSIONINFOEXW.wServicePackMajor: Major version number of the latest Service Pack.
0x386uint162OSVERSIONINFOEXW.wServicePackMinor: Minor version number of the latest Service Pack.
0x388uint162OSVERSIONINFOEXW.wSuiteMask: Bit mask that identifies the product suites available.
0x38Auint81OSVERSIONINFOEXW.wProductType: Additional information about the system.
0x38Buint81OSVERSIONINFOEXW.wReserved: Reserved for future use.
0x38Cuint324SYSTEM_INFO.dwNumberOfProcessors: Number of logical processors.
0x390uint648MEMORYSTATUSEX.ullTotalPhys: Total physical memory (in bytes).
0x398uint648File offset to the start of the events array (again).
0x3A0uint648File offset to hosts and ports arrays.

The header has file pointers to 5 important arrays:

Strings Array

This is an array of strings, which allows other parts of the file to refer to strings by their index in this array. Every String is represented by the struct:

typedef struct {
    uint32_t size;
    wchar_t string[size / sizeof(wchar_t)];
} String;

The array itself is represented by:

OffsetData TypeDescription
0x0UInt32The number of strings in the array.
0x4Uint32[]Array of relative offsets to every string in the array.
0x4+nString[]The array of the strings itself.

Process Array

The array of processes, which allows every event to have the process as an index in the array.

OffsetData TypeDescription
0x0UInt32The number of strings in the array.
0x4Uint32[]Array of the process indexes.
0x4+nUint32[]Array of relative offsets to every string in the array.
0x4+2nProcess[]The array of the processes.

A process is represented by:

OffsetData TypeDescription
0x0Uint32The process index (for events to use as a reference to the process)
0x4Uint32Process id
0x8Uint32Parent process id
0xCUint32Parent Process index.
0x10Uint64Authentication id
0x18Uint32Session number
0x1CUint32Unknown
0x20FILETIMEThe startinig time of the process.
0x28FILETIMEThe ending time of the process.
0x30Uint321 if the process is virtualized, 0 otherwise.
0x34Uint321 if this process is 64 bit, 0 if WOW64.
0x38Uint32Integrity - as a string index
0x3CUint32the user - as a string index
0x40Uint32the process name - as a string index
0x44Uint32the image path - as a string index
0x48Uint32the command line - as a string index
0x4CUint32company of the executable - as a string index
0x50Uint32version of the executable - as a string index
0x54Uint32description of the executable - as a string index
0x58Uint32Icon index small (0x10 pixels)
0x5CUint32Icon index big (0x20 pixels)
0x60PVoidUnknown
0x64/0x68Uint32number of modules in the process
0x68/0x6CModule[]Array of the modules loaded in the process.

A module is represented by:

OffsetData TypeDescription
0x0PvoidUnknown
0x8PvoidBase address of the module.
0x10Uint32Size of the module.
0x14Uint32image path - as a string index
0x18Uint32version of the executable - as a string index
0x1CUint32company of the executable - as a string index
0x20Uint32description of the executable - as a string index
0x24Uint32timestamp of the executable
0x28Uint64[3]Unknown

Hosts and Ports array

All the hosts and ports names for the network events are cached in these arrays:

Data TypeDescription
Uint32Number of elements in the hosts array
Host[]The hosts
Uint32Number of elements in the ports array
Port[]The ports

where hosts and ports are represented by:

typedef struct {
    char ip[16]; // the bytes of the ip, either IPv6 or IPv4 (only first 4 bytes used for IPv4)
    String host; // the name of the host as a string
} Host;

typedef struct {
    uint16_t port_number; // the number of the port
    uint16_t is_tcp; // true if this port is for TCP, false for UDP.
    String port_name; // the string value of the port name (for example http for TCP,80)
} Port;

Icon Array

Icons of captured process are stored in this array in the following format:

OffsetData TypeDescription
0x0UInt32The number of icons in the array.
0x4Uint32[]Array of relative offsets to every icon in the array.
0x4+nIcon[]The array of the icons itself.

The icons are being shown in the GUI with CreateIconFromResourceEx. Every icon is represented in the file by:

OffsetData TypeDescription
0x0Uint32the cxDesired and cyDesired
0x4Uint32the size of the icon in bytes.
0x8ICONIMAGEthe icon itself.

Events Array

This is the array of all the captured events. Each event has the information needed for all the columns, regardless of the selected columns in the configuration. Every event start at an offset from the event offsets array, in the following layout:

OffsetData TypeDescription
0x0Uint32The index to the process of the event.
0x4Uint32Thread Id.
0x8Uint32Event class - see class EventClass(enum.IntEnum) in consts.py
0xCUint16Operation type - see ProcessOperation, RegistryOperation, NetworkOperation, FilesystemOperation in consts.py
0xEByte[6]Unknown.
0x14Uint64Duration of the operation in 100 nanoseconds interval.
0x1CFILETIMEThe time when the event was captured.
0x24Uint32The value of the event result.
0x28Uint16The depth of the captured stack trace.
0x2AUint16Unknown
0x2CUint32The size of the specific detail structure (contains path and other details)
0x30Uint32The offset from the start of the event to extra detail structure (not necessarily continuous with this structure).
0x34PVoid[]Array of the addresses of the stack frames.
0x34+nByte[]A detail structure based on the operation type.

Detail Structures

Every event has a different detail structure at the end of the structure, based on the operation. The detail structure contains the path column, the category column and the detail column of the event. There are something like 50+ operation and sub operation types so most of them are still unknown.
In addition, an event can have an extra detail event, which can contain even more detail values. The extra detail structure doesn't necessarily comes after the event structure, so there is an offset field relative to the event structure.

All of the detail structures that are known are described in stream_logs_detail_format.py.

Network

Process

Process Create
Process Exit
Thread Create
Thread Exit
Load Image
Process Start

Registry

File system