
A C#/.NET 9 console tool that captures, records, replays, and explains Microsoft-Antimalware-Engine ETW telemetry for authorized red team and defensive research on Defender behavior.
| Tool | dobin/defender_observer — C#/.NET 9 console tool for capturing, recording, replaying, and analyzing Microsoft Defender Antivirus & EDR ETW telemetry |
| Category | ETW telemetry analysis utility (C#/.NET 9) |
Observing how MsMpEng and the Microsoft-Antimalware-Engine provider react to tooling during authorized engagements, with .jsonl recording and offline replay | |
| Safe Use | Intended for authorized red team assessments, malware analysis labs, and defensive research on systems you own or are contracted to test |
| Telemetry Note | Consumes existing Defender ETW providers read-only; requires administrator privileges, and its own trace sessions (TraceEvent) are themselves visible to defenders via standard ETW auditing |
dobin/defender_observer is a compact C#/.NET 9 console utility whose single purpose is to make the Microsoft-Antimalware-Engine ETW provider legible. Rather than dumping raw trace events into an unstructured firehose, it wraps Microsoft's TraceEvent library in a workflow built around four verbs: capture, replay, and explain. The README is explicit about the audience — red teamers who want to observe how Defender reacts to their offensive tooling — but the same machinery is directly useful to defenders, AV engineers, and detection researchers who need ground truth on what the engine emits and when.
The tool targets one provider: Microsoft-Antimalware-Engine, the ETW channel exposed by Defender's MsMpEng process. Attaching requires administrator privileges, which the README states plainly. Once attached, every event the engine emits is intercepted, parsed, and rendered with a timestamp, the source PID bracket notation like [MsMpEng:32456], the event class name such as StreamScanRequestStartEvent, the numeric event/opcode tuple (ID:5.1), and the full structured payload including Path, Process, Reason, and PID fields. This is the level of detail that normally requires assembling a custom TraceEvent consumer by hand.
What elevates it above a bare event dumper is the integrated knowledge base. Every printed event carries an inline ℹ explanation line — the example shows StreamScanRequestStartEvent glossed as starting a scan request for streamed content with path and process context. This catalog is shipped as JSON inside the repository, and the standalone explain verb interrogates it without any live capture: explain 74 returns the description, opcode, and fields for SenseRemediation Event 74, explain Tainting performs full-text search across event documentation, and explain --tasks / explain --enums enumerate Defender task names and value maps like SMS scan results and stop reasons. For anyone learning the provider from scratch, this turns the tool into a reference manual as much as an observer.
Recording is handled through streaming JSON Lines output. The -o trace.jsonl flag writes live telemetry directly to NDJSON as it arrives, which matters for two reasons: the file is complete even if a capture is cut short, and it becomes the input for the replay verb. Replay applies identical filtering, formatting, and enrichment to a recorded trace, meaning you can capture once in a lab and then iterate on analysis offline indefinitely — replaying with --path mimikatz -t BehaviorMonitor to isolate behavior-monitoring events touching a specific artifact, or --no-help for a compact view without the explanation annotations. This capture-once/analyze-many pattern is the right architecture for anything involving ETW, where volume makes live triage painful.
The filtering surface is unusually thorough for a one-shot tool. --path <pattern> matches substrings, wildcards, or regexes across all path, file, image, and registry fields — not just the primary path field, which is a thoughtful touch given how Defender events scatter file references. -p|--process matches either a process name substring or a numeric PID, with PIDs auto-resolved both from the OS and from BmProcess events. --event-id and --exclude-id target or blacklists specific numeric IDs, -t|--task filters by Defender task names like BehaviorMonitor, SmsScan, or SenseRemediation, and -s|--search runs full-text search across all payload keys, values, and summaries. Composing these gets you from full-engine noise to a tight slice in one command.
The example output in the README illustrates the event mix you actually see in practice. Scan lifecycle events dominate steady-state activity — StreamScanRequestStartEvent, SkippedFileEvent with a Log skip reason, StreamScanRequestEndEvent — as Defender streams file content from processes like Discord.exe through the engine. Interleaved with these are BehaviorMonitoring events: BmNotificationHandleStartEvent and its StopEvent counterpart reporting MatchedThreatsNumber and multi-process match flags, plus BmEtwEvent entries carrying a Channel=ThreatIntel field. That last family is where detection-relevant signal lives, and watching the start/stop notification pairs is how you correlate engine decisions back to a specific process.
The README is candid about provenance: the project is a self-described vibe-coded one-shot, planned with one Gemini model and implemented with another from a design document at docs/antimalware-engine.md. That disclosure matters for operational trust. The knowledge base is likely model-generated and should be spot-checked against Microsoft's official provider documentation before you rely on an explanation in a report. That said, the architecture — provider capture, JSON Lines persistence, replay with identical semantics, and an externalized knowledge base — is sound regardless of how the code was drafted, and the GPL-3.0 license plus readable C# source means everything is auditable.
In an authorized workflow, the obvious use is pre-engagement rehearsal: run your tooling in a lab VM with capture -o trace.jsonl -p beacon and study exactly which scan requests, behavior-monitoring notifications, and remediation tasks your tooling triggers, then use that telemetry to tune detection engineering or brief the blue team on what they should expect to see. On the defensive side, the same traces are a teaching corpus for writing ETW-based detections, since the replay verb lets you hand a recorded, filterable dataset to analysts without giving them live endpoint access.
The operational footprint itself is worth noting. The tool attaches to an existing provider read-only; it does not patch, tamper with, or disable Defender, and it does not inject into MsMpEng. Its visibility is its privilege requirement: an administrator launching an ETW trace session is itself an observable action, and defenders watching for unexpected TraceEvent sessions or unsigned console binaries run by admins will see this activity. That symmetry is healthy — the tool is for observation, not evasion, and it leaves a normal forensic trail.
At 24 stars, defender_observer is early in its lifecycle, but it fills a genuine gap. Most ETW tooling is either generic (session management with no provider semantics) or heavyweight commercial telemetry platforms. A focused, filterable, replayable consumer for the Microsoft-Antimalware-Engine provider with an inline knowledge base is the kind of niche utility that earns a permanent slot in a lab image. Clone it with git clone https://github.com/dobin/defender_observer, build with dotnet, and run capture from an elevated shell — the rest is reading telemetry you were always entitled to see.
dobin/defender_observer.Educational analysis for authorized security professionals. Use only in controlled, authorized environments.
Related coverage
0 comentários:
Post a Comment
Note: Only a member of this blog may post a comment.