Skip to content

About

Measure exactly how much latency your antivirus is adding to file I/O on Windows. Pick a process, run a workload, get a per-directory / per-process / per-extension breakdown plus ready-to-paste exclusion commands for Defender, CrowdStrike, SentinelOne, and Sophos.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

ET Ducky AvProfiler

A standalone Windows tool for measuring the antivirus tax on your file I/O. Pick a process (or capture system-wide), run a workload, and get a per-path / per-process / per-extension breakdown of how much slower the I/O ran compared to your machine's baseline — plus ready-to- paste exclusion commands for Defender, CrowdStrike, SentinelOne, and Sophos.

Open-source under the Apache License 2.0. No telemetry, no cloud. This is a self-contained app that runs on its own without installing anything locally.

Built on Microsoft.Diagnostics.Tracing.TraceEvent, the same library that backs PerfView and several Microsoft diagnostic tools.

What it does

Four tabs:

  • Record — type an optional process regex (e.g. msbuild|dotnet|node) or leave blank for system-wide. Click Start, run the slow workload, click Stop. The tool runs a baseline I/O probe first, then measures every file IRP your tracked processes issue during the capture.
  • Results — three side-by-side grids: Hot Paths (by directory), Hot Processes (by image name), Hot Extensions (by suffix). Each row shows operation count, total wall-clock latency, mean / P95 per IRP, and a multiplier against your machine's baseline. The bottom panel lists every minifilter driver currently attached to your I/O stack — AV, EDR, DLP, BitLocker, OneDrive, backup agents — with the vendor product name where we can identify it.
  • Recommend — for the worst offenders, copy-paste-ready exclusion commands for each AV / EDR we detected in your stack. Each recommendation includes a rationale and a safety note when the target is in a category we wouldn't blindly suggest excluding (system folders, user data, etc.).
  • Help — a primer on minifilter drivers, what makes them slow, and the safety rules for exclusions (what's fine, what isn't).

The measurement is deterministic. Each file IRP is timed in microseconds against a per-machine baseline; aggregation and ranking are pure arithmetic over those measurements. There is no AI inference or heuristics that change between runs.

Why this exists

AvProfiler measures the per-IRP latency your tracked processes pay in the kernel I/O stack — every minifilter driver attached to the volume (AV, EDR, DLP, BitLocker, OneDrive, backup agents) contributes to that latency. By comparing each hot directory and process against your machine's baseline I/O, the tool produces an evidence-backed exclusion list specific to your workload and your minifilter stack, not a generic vendor recommendation.

Typical findings:

  • A build output directory (bin\, obj\, target\) running at 50–200x baseline latency because every .obj and .pdb gets a full on-access scan.
  • A local package cache (npm, NuGet, Maven) re-scanned on every read despite already being integrity-checked by its package manager.
  • A .git directory with thousands of small object reads paying full scan cost per file.
  • A dev tool (msbuild, dotnet, node) whose every output write is scanned because the AV doesn't recognise it as a known-good process.

Download

Pre-built signed Windows executables are published on the Releases page. Download ETDucky.AvProfiler.exe, right-click → Properties → Unblock (mark-of-the-web), then run.

The app requires Administrator. The manifest requests elevation; you'll see one UAC prompt at launch.

Build from source

Requirements: Windows 10+, .NET 10 SDK.

git clone https://github.com/trucule/ETDucky.AvProfiler.git
cd ETDucky.AvProfiler
dotnet build -c Release

Single-file self-contained publish:

dotnet publish -c Release -r win-x64 `
  -p:SelfContained=true `
  -p:PublishSingleFile=true `
  -p:IncludeNativeLibrariesForSelfExtract=true

How it works

IRP latency capture

A WinForms shell drives a private kernel ETW session (System Trace Provider Group, Windows 8+) with two providers enabled:

Provider Captured
Microsoft-Windows-Kernel-FileIO Create / Read / Write / Cleanup / Close, IRP-correlated
Microsoft-Windows-Kernel-Process spawn / exit (for process-tracker child following)

For every file operation, the tool stashes the IRP-issue event keyed on IrpPtr, then matches it against the IRP-completion event to compute the wall-clock duration. That duration is the total time the operation spent traversing the kernel I/O stack — including every minifilter driver attached to the volume.

A ProcessTracker keeps the live set of tracked PIDs. A PID joins the set on two conditions: its image filename matches the operator-supplied regex, or its parent PID is already tracked (so build-tool children, service spawns, etc. are followed automatically). Every event is filtered against this set before the recorder sees it. Blank or * filter means system-wide capture.

The kernel session is a private kernel session, not the legacy NT Kernel Logger. The tool coexists with PerfView, xperf, ProcDelta, ProviderExplorer, the ET Ducky agent, and other ETW capture tools; the per-host limit is 8 concurrent kernel sessions.

Baseline probe

Before the capture window opens, the tool runs a synthetic workload in your %TEMP% folder: 20 iterations of CreateFile + Write + Close

  • Open + Read + Close + Delete on small files. Each operation is timed with Stopwatch, then a 20%-trimmed mean is taken so a single preempted iteration doesn't skew the result.

The baseline mean is then used as the divisor when the aggregator computes each hot path's "× baseline" multiplier. A multiplier of 1.0 means "no slower than your machine's everyday I/O"; 50.0 means "50x slower." This gives meaningful numbers across SSDs, HDDs, encrypted volumes, hypervisors, etc., without the user having to know what "normal" microseconds are on their hardware.

Important caveat: the probe runs through the same minifilter stack as the workload, so it includes everyday AV overhead. The multiplier shows ADDITIONAL cost above your machine's everyday AV baseline, which is conservative on purpose.

Aggregation

Captured IRPs are grouped by directory (Hot Paths), by process basename (Hot Processes), and by extension (Hot Extensions). Each group reports count, total latency, mean, P95, and a baseline multiplier weighted by the group's operation mix (Creates cost more than Reads on most stacks). Ranking is by total latency — twenty 50-microsecond Creates aren't worth excluding; thirty thousand 2-millisecond Creates absolutely are.

Minifilter enumeration

Shells out to fltmc.exe filters to list every registered minifilter on the host. The driver name is matched against a small static table of known AV/EDR/utility products to produce a human-readable vendor label (CrowdStrike Falcon, Microsoft Defender, SentinelOne, Sophos, ESET, etc.). Drivers we don't recognise still appear in the table with vendor "(unknown)" — useful for spotting unexpected filters (third-party DLP, file-sync, backup agents).

Exclusion command generation

For each hot entry above 3x baseline, the recommender generates vendor-specific exclusion commands:

  • Defender: PowerShell Add-MpPreference -ExclusionPath '...' or -ExclusionProcess '...'
  • CrowdStrike: Falcon Console navigation + the exclusion pattern
  • SentinelOne: Management Console navigation + path/mode
  • Sophos: Sophos Central navigation + exclusion value
  • Generic: the raw path or process for any AV not listed above

When the hot entry is a known dev tool (msbuild, dotnet, node, gcc, clang, git, etc.), the recommender prefers a process exclusion over a path exclusion — narrower scope, smaller security gap. When the hot path is under a system folder (C:\Windows) or a user-content folder (Downloads, Desktop, Documents), the recommendation is emitted with a SafetyNote rather than as a clean suggestion.

Architecture

ETDucky.AvProfiler/
├── MainForm.cs                  Four tabs: Record / Results / Recommend / Help
├── Program.cs
├── HelpText.cs                  Static Help-tab content
├── app.manifest                 requireAdministrator
├── app.ico
├── Models/
│   ├── IrpLatencyEvent.cs       One observed I/O op + duration
│   ├── CaptureSession.cs        Lock-free queue of in-flight events
│   ├── HotEntry.cs              Aggregated stats row
│   ├── MinifilterInfo.cs        One registered filter driver + vendor
│   ├── ExclusionRecommendation.cs  Per-vendor exclusion command set
│   ├── CaptureSummary.cs        Top-level result
│   └── PathNormalizer.cs        Device-namespace → DOS path, extension, etc.
└── Services/
    ├── ProcessTracker.cs        Pattern-matched PID set + child following
    ├── IrpLatencyCapture.cs     ETW session + IRP correlation
    ├── BaselineProbe.cs         Synthetic-workload baseline measurement
    ├── HotEntryAggregator.cs    Group/rank events into Hot* tables
    ├── MinifilterEnumerator.cs  fltmc-driven minifilter list
    ├── VendorMapper.cs          Driver name → vendor product
    └── ExclusionGenerator.cs    Hot entries + vendors → exclusion commands

No external services. No ETDucky.Core reference. Standalone.

Caveats

  • Windows-only. ETW is a Windows subsystem.
  • Administrator required. Kernel sessions and fltmc both need it.
  • 8 kernel sessions per host. The tool uses a private kernel session, so it coexists with PerfView, xperf, ProcDelta, the ET Ducky agent, and other ETW capture tools. Only when all 8 slots are full does Start fail.
  • IRP latency is total stack latency, not per-filter latency. ETW doesn't break down which minifilter contributed how much. We can tell you the IRP took 50ms and that you have CrowdStrike + Defender
    • Sophos all installed; we can't attribute the 50ms to one of them specifically.
  • The baseline is computed THROUGH your AV stack. This makes the multiplier conservative (it already discounts everyday AV overhead). Don't use the multiplier as an "AV vs no AV" comparison.
  • No security warranty on recommendations. Every exclusion trades security for performance. The tool flags obviously-dangerous recommendations (system paths, user content folders) but it can't evaluate your specific threat model. Review before applying.

Relationship to ET Ducky

ET Ducky (https://etducky.com) is a commercial cross-platform diagnostic agent that uses ETW on Windows and eBPF on Linux for continuous fleet-wide kernel observability with AI-driven root-cause analysis. AvProfiler is the standalone, workload-driven, single- machine version of one diagnostic pattern the commercial agent runs continuously across endpoints.

The two are independent repositories.

License

Apache License 2.0. Free for any use — commercial or otherwise — with patent grant and trademark protection. See LICENSE for the full terms.

Contributions submitted as pull requests are accepted under the same license. By submitting a PR you confirm you have the right to license your contribution this way.

Contributing

PRs welcome. The codebase is small. Useful directions:

  • More vendor templates in VendorMapper.cs and ExclusionGenerator.cs (Trend Micro, McAfee, Bitdefender, Kaspersky console paths and exclusion-command formats).
  • Per-minifilter latency attribution would be the killer feature, but requires either driver-side instrumentation we can't ship in user mode, or sampling tricks (capture twice with different filters unloaded) that bring their own assumptions.
  • A "starter pack" of pre-recorded baselines for common dev workloads (dotnet build of representative solutions, npm install of a Node monorepo, full Visual Studio open + restore) so users can quickly see whether their machine is in the normal range.
  • CSV export alongside the existing JSON for spreadsheet workflows.

About

Measure exactly how much latency your antivirus is adding to file I/O on Windows. Pick a process, run a workload, get a per-directory / per-process / per-extension breakdown plus ready-to-paste exclusion commands for Defender, CrowdStrike, SentinelOne, and Sophos.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages