Skip to content

progmboy/openprocmon

Repository files navigation

OpenProcMon

OpenProcMon

English · 中文

An open-source Process Monitor implementation for Windows: a kernel miniFilter driver captures process, file, registry and network activity in real time, a Rust SDK talks to the driver and parses the event stream, and a Rust/GPUI desktop GUI presents it.

This is a ground-up Rust rewrite of the SDK and GUI. The kernel driver is unchanged, and the original C++ implementation is kept under cpp-backup/ for reference. The Rust SDK is wire-compatible with the original Process Monitor driver and can read/write Procmon .PML logs.

An AI agent can drive capture and analysis through an MCP server or a skill — see MCP / Skill. The desktop GUI is powered by GPUI and GPUI-Component.

Main window

Contents

Architecture

┌──────────────────────────────────────────────┐
│  GUI            crates/gui  (Rust + GPUI)    │  event table · detail panel ·
│                                              │  filter/highlight · process tree
├──────────────────────────────────────────────┤
│  SDK            crates/sdk  (Rust)           │  driver port · event parsing ·
│                                              │  process tracking · PML read/write
├──────────────────────────────────────────────┤
│  Kernel driver  kernel/     (C, miniFilter)  │  process/file/registry callbacks
└──────────────────────────────────────────────┘

The driver and the SDK communicate over a Filter Manager communication port; the kernel/user-mode contract lives in kernel/logsdk.h, which the Rust SDK mirrors with #[repr(C, packed)] structures.

Repository layout

openprocmon/
├── bin/          # Prebuilt binaries (e.g. the stock Process Monitor driver, PROCMON24.SYS)
├── cpp-backup/   # Original C++ SDK + WTL GUI, kept for reference
├── crates/       # Rust workspace
│   ├── sdk/      #   procmon-sdk — driver comms, event parsing, PML read/write, symbols
│   ├── core/     #   procmon-core — PML analysis layer (query / group-by / timeline)
│   ├── cli/      #   procmon-cli — command-line + MCP server (the AI agent front-end)
│   ├── gui/      #   procmon-gui — GPUI desktop app (live capture + .PML viewing)
│   └── example/  #   procmon-example — console SDK demo (capture / save / replay)
├── docs/         # Design docs, logo, and screenshots
└── kernel/       # miniFilter driver (C, built with the WDK)

Features

  • Real-time monitoring of process, file system, registry, and network activity.
  • Live filtering and highlighting by process name, PID, operation, path, result, or category.
  • Process tree, and activity summaries for processes, files, registry, network, and cross-references.
  • Call stack view with per-frame module resolution.
  • Full .PML interoperability with Sysinternals Process Monitor — files open both ways: capture with OpenProcMon and open the log in the real Process Monitor (event list, the per-process Properties dialog, and kernel-resolved call stacks all work), or open a Procmon-captured .PML here.
  • Full-control Rust SDK — drive everything programmatically: load/connect the driver, choose what to monitor, push filters, and consume the parsed event stream. The GUI is just one consumer (see SDK example).
  • AI agent integration (MCP + skill) — capture and analyze from an AI agent over an MCP server (procmon-cli mcp) or a drop-in skill; one query primitive (filter + group-by / numeric-metric aggregation) answers questions like "what did X write / connect to" without flooding the model (see MCP / Skill).
  • Modern, GPU-accelerated UI (GPUI) with a clean, contemporary design — light/dark themes and English/Chinese localization.

Screenshots

Process activity summary — per-process event counts with a category breakdown.

Process activity summary

Settings — symbol/dbghelp paths, history limits, highlight color, theme and language.

Settings

Build

Prerequisites

  • A recent Rust toolchain (stable) — see rustup.
  • Windows (the SDK and GUI use Win32 APIs).
  • For the kernel driver only: the Windows Driver Kit (WDK).

Rust workspace

# Build everything (GUI, SDK, example)
cargo build

# Release build of the GUI
cargo build -p procmon-gui --release

Run

# GUI driving the real kernel driver (run elevated / as Administrator)
cargo run -p procmon-gui

When procmon.sys sits next to the executable, the GUI loads and starts the driver on demand; capturing the real system requires Administrator privileges.

SDK example

Live capture and offline .PML reading flow through one EventSource, so the consume loop is identical — only how you create the source differs.

Live capture — connect to the driver (loading the .sys on demand):

use procmon_sdk::{
    Action, Column, DriverLoader, EventSource, FilterSet, MonitorFlags, Relation, Rule,
};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let source = EventSource::from_driver(
        DriverLoader::new("OpenProcmon24", "procmon.sys"),
        MonitorFlags::PROCESS | MonitorFlags::FILE | MonitorFlags::REGISTRY,
    )?;

    // An Include rule restricts the view to its matches: show only notepad.exe.
    source.set_filter(FilterSet::new(vec![Rule::new(
        Column::ProcessName,
        Relation::Is,
        "notepad.exe",
        Action::Include,
    )]));

    // `events()` streams parsed events; fields are produced lazily.
    for ev in source.events() {
        if !source.is_visible(&ev) {
            continue; // dropped by the active filter
        }
        println!(
            "{:>6}  {:<22}  {:<16}  {}",
            ev.pid(),
            ev.operation_name(),
            ev.result(),
            ev.path().unwrap_or_default(),
        );
    }
    Ok(())
}

Read a .PML — no driver needed; the loop is exactly the same:

use procmon_sdk::{Action, Column, EventSource, FilterSet, Relation, Rule};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let source = EventSource::from_pml("out.pml")?;

    // Exclude rules hide their matches: drop temp-file noise.
    source.set_filter(FilterSet::new(vec![Rule::new(
        Column::Path,
        Relation::EndsWith,
        ".tmp",
        Action::Exclude,
    )]));

    for ev in source.events() {
        if !source.is_visible(&ev) {
            continue;
        }
        println!(
            "{:>6}  {:<22}  {:<16}  {}",
            ev.pid(),
            ev.operation_name(),
            ev.result(),
            ev.path().unwrap_or_default(),
        );
    }
    Ok(())
}

Run the bundled console demo:

# Live capture (run elevated). The optional .sys path loads the driver on demand.
cargo run -p procmon-example -- [C:\path\to\procmon.sys]

PML logs

OpenProcMon reads and writes the Sysinternals Process Monitor .PML format:

# Capture live, then save to a Procmon-compatible .PML
cargo run -p procmon-example -- --save out.pml [C:\path\to\procmon.sys]

# Replay a .PML (no driver needed)
cargo run -p procmon-example -- --pml out.pml

In the GUI, use File ▸ Open to load a .PML.

MCP / Skill

procmon-cli is a command-line and MCP front-end that lets an AI agent drive OpenProcMon is a capture-then-analyze tool: a capture writes a .PML, and every analysis reads one. The single query primitive (filter + group-by) answers the common questions ("what files did X write?", "registry persistence?", "network endpoints?") without flooding the model with raw events.

cargo build -p procmon-cli --release

# Capture a program + its children for 10s (live capture needs Administrator):
procmon-cli capture --name app.exe --launch "app.exe" --duration 10

# Analyze any .PML (no elevation needed). The filter is an
# expression (&& / || / ! / in (...)); see `vocab` for the full syntax:
procmon-cli query --pml cap.pml --group-by Path \
  --filter 'Category == "File System" && Operation == WriteFile'
procmon-cli vocab            # exact column/operator/operation names + syntax
procmon-cli --help           # all subcommands

Two ways to wire it to an agent:

  • MCP server. procmon-cli mcp serves the operations as MCP tools over stdio. 📖 See the full MCP guide (中文) for client setup (Claude Code / Claude Desktop / Codex / Cursor …) and a worked malware-.PML analysis. Quick start (Claude Code):

    claude mcp add --transport stdio --scope user openprocmon -- procmon-cli mcp

    The server's instructions and the list_filter_columns tool teach the agent the filter vocabulary and recipes, so no extra setup is needed.

  • Skill (for CLI-driving agents). Copy skills/procmon/ into your own ~/.claude/skills/ — it teaches an agent the procmon-cli commands and the filter cookbook.

Live capture requires Administrator (it loads the driver); analyzing a .PML does not.

Kernel driver

The miniFilter driver source is under kernel/; build it with the WDK. The GUI and CLI load a driver image named PROCMON24.SYS: with the embedded-driver feature (on by default) it is embedded from bin/PROCMON24.SYS at build time and dropped to System32\Drivers on demand; with --no-default-features they instead load a procmon.sys from next to the executable.

To use your own driver: build kernel/, sign it (or test-sign it), place the signed .sys at bin/PROCMON24.SYS, then rebuild the GUI / CLI to embed it. A test-signed driver requires test signing enabled / signature enforcement disabled on the machine that loads it.

The SDK is wire-compatible with the original Process Monitor driver — it consumes the same event stream from either — and conversely this driver can stand in for the original to study how Process Monitor works, or as a starting point for your own EDR-style tooling.

Known issues

  • 32-bit (x86) is not supported. OpenProcMon targets 64-bit Windows only — the driver, the SDK's packed kernel structures, and the GUI all assume an x64 host. Running on 32-bit Windows is not supported and not currently planned.
  • 32-bit .PML files are not supported. The PML reader/writer only handles the 64-bit PML format; .PML logs produced on a 32-bit host will not parse.

Status & roadmap

The Rust rewrite is under active development.

  • Rust SDK: driver port, event parsing (process/file/registry/network)
  • Process tracking, image metadata & icon extraction
  • PML reader/writer (Procmon-compatible)
  • GUI: event table, detail panel, filter/highlight, process tree, summaries
  • Call stack with module resolution
  • Save the current capture from the GUI
  • AI MCP server and skills (procmon-cli + procmon-cli mcp)
  • Performance optimization
  • Boot logging capture

License

Released under the MIT License.

Acknowledgements

The desktop GUI is built on:

  • GPUI — Zed's GPU-accelerated Rust UI framework.
  • GPUI-Component — a UI component library for GPUI.

About

open source process monitor

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors