rmagent-at — The App Tracing skill
Resident, on-device application tracing using Windows' built-in ETW. No SDK, no agent install, no lake — the data is already being written; this skill just asks for it.
The application-tracing sibling of rmagent-so (security questions) and
rmagent-fr (the Flight Recorder). Same constitution: pull-only, named
questions, capped answers, holes instead of dumps.
The architecture
┌─────────────────────────────────────────────────────┐
│ APPLICATION (.NET, IIS, HTTP.sys, anything) │
│ Already emitting into ETW — zero code change │
└────────────────────┬────────────────────────────────┘
│
┌────────────────────▼────────────────────────────────┐
│ ETW KERNEL RING BUFFER (AutoLogger session) │
│ • Starts at BOOT, resident in kernel memory │
│ • 512 MB default (enterprise scale, tunable) │
│ • Circular: old events overwritten — no lake │
└────────────────────┬────────────────────────────────┘
│
┌────────────────────▼────────────────────────────────┐
│ THE PULL (rmagent pattern — on demand, capped) │
│ • apptrace / appslow / apperrors / appnet / appproc│
│ • Writes to the case file │
└─────────────────────────────────────────────────────┘
Enterprise scale — the ring buffer
The default is 512 MB for the AppTrace session (256 MB for NetTrace, 128 MB for ProcTrace). At typical event rates that gives hours to days of retention instead of minutes. Everything is tunable:
# default (512/256/128 MB)
python3 autologger.py --inventory estate.yaml --setup
# grow everything to 1 GB
python3 autologger.py --inventory estate.yaml --setup --resize 1024
Why this is not a lake: the buffer is circular. When it fills, the oldest events are overwritten. Nothing is retained forever, nothing is shipped anywhere, and the total footprint is bounded by the buffer size you chose. It is a ring, not a warehouse.
The sessions
| Session | Purpose | Ring | Providers (LIVE-VERIFIED 2026-09-04) |
|---|---|---|---|
RMAgent-AppTrace |
Application events | 512 MB circular | DotNETRuntime {E13C0D23-CCBC-4E12-931B-D9CC2EEE27E4}, HTTP.sys {DD5EF90A-6398-47A4-AD34-4DCECDEF795F} |
RMAgent-NetTrace |
TCP connections with PID | 256 MB circular | Kernel-Network {7DD42A49-5329-4832-8DFD-43D979153A88} |
RMAgent-ProcTrace |
Thread/image activity | 128 MB circular | Kernel-Process {22FB2CD6-0E7B-422B-A0C7-2FAD1FD0E716} |
The ring is REAL now (Rev 18). The original config set LogFileMode 0x1004
= APPEND mode — a file that grows to its cap and then the session DIES (found
live: all three sessions Stopped with zero bytes recorded, 4 of 5 provider
GUIDs wrong). Rev 18 uses logman update -f bincirc -max <MB> -r — a true
circular file that overwrites oldest-first and restarts into new segments
continuously. Verified live on WS1: sessions Running, Circular: On,
ring files at C:\etw\<name>_000001.etl.
Six logman/registry facts learned live (the setup payload encodes all of
them): Impacket's reg.py shadows reg.exe (absolute paths mandatory);
logman create's own DCS config SHADOWS the AutoLogger registry values;
providers added via -p default to Level 0 / Keywords 0x0 = capture NOTHING
(every provider needs an explicit keyword mask + level); a circular session
without -r fills one segment and stops; kernel providers engage their flags
only at trace start; and a teardown must poll for stop before delete or the
next setup hits "Data Collector already exists".
The questions
| Question | Returns | Must NOT return |
|---|---|---|
apptrace |
Recent application events from the ring (provider, id, level, message) | full event dumps |
appslow |
Requests/operations over 500ms, sorted slowest-first | all events |
apperrors |
Errors and warnings (Level ≤ 3) with counts | full error dumps |
appnet |
TCP connections (src → dst), deduplicated | full netflow |
appproc |
Process start/end events with command lines | full process list |
appsysmon |
Sysmon security telemetry: image SHA256s, LSASS access, image loads, registry sets, Guid-keyed connections | raw Sysmon dump |
appsysmon — the security layer, read not installed
Sysmon is a separate telemetry plane from the ETW ring. The ring sessions
(ProcTrace, NetTrace) capture process and connection events from the
kernel. Sysmon adds the security context the kernel providers do not emit:
| Sysmon event | What it adds over the ring |
|---|---|
| Event 1 (hashes) | SHA256 of every binary executed — "did this binary ever run here?" is answerable without the file still being present |
| Event 3 (ProcessGuid) | Connections keyed by ProcessGuid, not PID — PIDs are reused, Guids are not |
| Event 7 (image loads) | DLL loads — injection and LOLBin abuse |
| Event 10 (LSASS) | Credential-access attempts the process provider does not see |
| Event 13 (registry) | Registry value sets — the persistence channel ProcTrace misses entirely |
This skill does not install Sysmon. It reads the log that is already
running. If Sysmon is absent, the answer carries sysmon: 'not-installed'
and empty lists — a hole, not an error, and not a reason to install anything.
Installation is an EDR decision, not a tracing one.
The honest overlap: process create/exit and network connections appear in both
planes. Where they duplicate, the ETW ring is the application view (what ran,
what connected) and Sysmon is the security view (what it was, its hash, its
Guid). Use appproc/appnet for volume; use appsysmon when you need to
tie an action to a specific binary identity.
Setup (MOP-level — this is a persistent change)
The AutoLogger sessions start at boot and run resident. That is a persistent change to the witness, so it is a MOP-level action, not a Phase 0 question. Everything is reversible:
# create the sessions (admin)
python3 autologger.py --inventory estate.yaml --setup
# check what's running
python3 autologger.py --inventory estate.yaml --status
# grow the buffers
python3 autologger.py --inventory estate.yaml --setup --resize 1024
# remove everything (stops sessions, deletes registry keys, removes files)
python3 autologger.py --inventory estate.yaml --teardown
Pulling (Phase 0 — the questions are read-only)
# from hunt.py or the agent
lib.ask(row, "apptrace", since_hours=2, limit=50)
lib.ask(row, "appslow", since_hours=24, limit=20)
lib.ask(row, "apperrors", since_hours=1, limit=30)
Non-negotiables
- The setup is MOP; the questions are Phase 0. Creating the sessions changes the witness. Reading them does not.
- The ring is bounded. You chose the size; the kernel enforces it. Nothing is retained beyond the ring.
- Pull-only questions. Named, allowlisted, capped, read-only.
- Never trust a quiet ring.
ringhealthis the attest/blind_check of this plane: Stopped AutoLogger →witness_blind, not a quiet app. - Fully reversible.
--teardownstops the sessions, deletes the registry keys, and removes the files. - Your estate only.
Honest limits
- The ring overwrites. A busy box will cycle a 512 MB buffer in hours, not days. Increase the buffer if you need longer retention — the cost is disk (bincirc) rather than kernel memory.
- Structured parsing, name-keyed.
appnet/appprocparse the event's XML payload by PROPERTY NAME (Message is null for ETL-file events — the original prose-regex parsing saw volume with zero findings and reported it as a quiet box).parse_failuresin every answer makes "N events, 0 parsed" a hole, not a clean bill. - NetTrace's kernel limitation (found live 2026-09-04). The
Kernel-Network provider config verifies correct (Level 255, all keywords,
Running/Circular) yet Server 2022's AutoLogger delivers no kernel-network
events to the ring.
appnettherefore PREFERS the ring and FALLS BACK to Sysmon EID 3 (same pull, same box, better source — it also carries the process name). If both sources are empty the answer sayssource='none'— an honest hole, not a fake clean bill. - ProcTrace carries thread events, not command lines. The Kernel-Process
AutoLogger ring delivers thread-start/stop (ProcessID, ThreadID,
Win32StartAddr) — process command lines and binary hashes live in Sysmon
Event 1 via
appsysmon. Stated in the payload itself. - No LLM token counts / prompt text. This is application tracing, not OpenLLMetry. Different layer.
- The AutoLogger is a persistent change.
--setupis MOP-level: dry-run by default,--applyrequired,--teardown --applyreverses everything (verified: teardown removes DCS + registry keys + ring files).
Relationship to the other skills
| Skill | Plane |
|---|---|
rmagent-so |
Security questions (identity-led) |
rmagent-fr |
The Flight Recorder (ticket-led tracing of the investigation) |
rmagent-at |
This skill — application tracing (ETW, resident) |
rmagent-ao |
The Agent Observatory (agent census) |
rmagent-windows |
The complete Windows skill (so + fr) |
rmagent-redteam |
The drill |
rmagent-actuate |
Phase 1 response |
rmagent-linux |
The Linux/macOS sibling |