[GH-ISSUE #2689] [Provider proposal] Bounded Windows ETW events for a selected process #979

Open
opened 2026-10-15 18:30:04 +00:00 by bsakaguchi · 3 comments
Owner

Originally created by @LcokHcak on GitHub (Oct 13, 2026).
Original GitHub issue: https://github.com/morluto/rea/issues/2689

Proposal: bounded Windows ETW events for a selected process

Problem and proposed first slice

Static analysis does not show which processes, threads, or modules were observed during a controlled run. I propose an optional Windows ETW provider that starts a uniquely owned, finite session for selected provider/event IDs, retains raw ETW records, filters the selected process with an explicit statement of whether filtering happens at the provider or consumer, and projects supported events into the common v1 trace batch. It would report the provider/event identity, observed PID/TID, actual clock domain and frequency, event-loss counters, retention truncation, cancellation, and session/ETL cleanup. Process/thread/module events would not be presented as arbitrary function-call flow.

Authority and limits

Starting an ordinary ETW session changes host tracing state and requires an elevated administrator, Performance Log Users membership, or supported service identity. Some providers may emit system-wide events before consumer filtering. No automatic elevation, broad system provider by default, unrelated-session takeover, ETL overwrite, or stop of a session REA does not own. A low-privilege private logger is a distinct in-process mode; it cannot silently replace selected cross-process ETW observation.

Evidence available now

On Windows 10.0.26200.0, the Microsoft-Windows-Kernel-Process manifest exposes process/thread/image events. A controlled custom-provider ordinary logman start returned Access denied under the current token. Adding -ul generated PID-suffixed private-logger files but no decodable target trace; the owned session is no longer active. A separate in-process custom EventSource/EventListener fixture produced three real callbacks, all projected to provider-event / instant with callback timestamps and unknown TID/loss. That verifies common-format expressiveness only. No cross-process ETW provider is implemented or verified, and no public CLI/MCP path exists.

Verification required before integration

In an authorized Windows fixture: selected provider/event set and process identity; provider-side versus consumer-side PID filtering; independent process/thread/module evidence; ordinary non-admin denial; event timestamp metadata and loss counters; high-rate bounds; cancellation, target exit and PID reuse; cleanup after normal and failed runs; public CLI/MCP and installed package. Collect no unrelated process payloads during the fixture.

Maintainer decision requested

Is this restricted selected-process ETW lane in REA's dynamic-provider scope? Which providers and keywords, permission model, filtering boundary, host-wide effects, and Windows CI lane are acceptable before integration? Is an in-process private-logger mode useful enough to specify separately?

Related context: Windows parent #38 is closed; its static/package children do not decide ETW scope. Frida #968 addresses a different instrumentation boundary.

Originally created by @LcokHcak on GitHub (Oct 13, 2026). Original GitHub issue: https://github.com/morluto/rea/issues/2689 # Proposal: bounded Windows ETW events for a selected process ## Problem and proposed first slice Static analysis does not show which processes, threads, or modules were observed during a controlled run. I propose an optional Windows ETW provider that starts a uniquely owned, finite session for selected provider/event IDs, retains raw ETW records, filters the selected process with an explicit statement of whether filtering happens at the provider or consumer, and projects supported events into the common v1 trace batch. It would report the provider/event identity, observed PID/TID, actual clock domain and frequency, event-loss counters, retention truncation, cancellation, and session/ETL cleanup. Process/thread/module events would not be presented as arbitrary function-call flow. ## Authority and limits Starting an ordinary ETW session changes host tracing state and requires an elevated administrator, Performance Log Users membership, or supported service identity. Some providers may emit system-wide events before consumer filtering. No automatic elevation, broad system provider by default, unrelated-session takeover, ETL overwrite, or stop of a session REA does not own. A low-privilege private logger is a distinct in-process mode; it cannot silently replace selected cross-process ETW observation. ## Evidence available now On Windows 10.0.26200.0, the `Microsoft-Windows-Kernel-Process` manifest exposes process/thread/image events. A controlled custom-provider ordinary `logman` start returned Access denied under the current token. Adding `-ul` generated PID-suffixed private-logger files but no decodable target trace; the owned session is no longer active. A separate in-process custom `EventSource`/`EventListener` fixture produced three real callbacks, all projected to `provider-event / instant` with callback timestamps and unknown TID/loss. That verifies common-format expressiveness only. **No cross-process ETW provider is implemented or verified**, and no public CLI/MCP path exists. ## Verification required before integration In an authorized Windows fixture: selected provider/event set and process identity; provider-side versus consumer-side PID filtering; independent process/thread/module evidence; ordinary non-admin denial; event timestamp metadata and loss counters; high-rate bounds; cancellation, target exit and PID reuse; cleanup after normal and failed runs; public CLI/MCP and installed package. Collect no unrelated process payloads during the fixture. ## Maintainer decision requested Is this restricted selected-process ETW lane in REA's dynamic-provider scope? Which providers and keywords, permission model, filtering boundary, host-wide effects, and Windows CI lane are acceptable before integration? Is an in-process private-logger mode useful enough to specify separately? Related context: [Windows parent #38](https://github.com/morluto/rea/issues/38) is closed; its static/package children do not decide ETW scope. [Frida #968](https://github.com/morluto/rea/issues/968) addresses a different instrumentation boundary.
Author
Owner

@LcokHcak commented on GitHub (Oct 13, 2026):

Controlled follow-up: I verified a narrower same-process private logger path on Windows x64 (10.0.26200), using only a self-owned synthetic provider and one finite session. A native EventRegister provider was enabled in the same process as StartTraceW; three EventWriteString calls returned success. The offline OpenTraceW/ProcessTrace consumer returned success and read five ETL records, three of which carried the expected provider GUID and the three distinct synthetic labels (enter, branch-App, exit) in order. The session was stopped and the provider unregistered; the pre-stop query reported EventsLost=0 and LogBuffersLost=0. This corrects the earlier statement that no decodable private ETW trace was obtained.

These labels were deliberately written by the fixture; they are not observed function entries, branches, or exits. The result does not validate an ordinary cross-process ETW session, a Windows system provider, complete process flow, or production-safe EventWriteString use. I currently have no isolated Windows host with administrator or Performance Log Users privileges for that separate acceptance lane.

The local common-trace prototype projects the three records as provider-event / instant, retains their ETL callback indices and PID/TID, and now preserves exact windows-filetime-100ns values. A millisecond-only projection collapsed all three distinct timestamps into one millisecond. The prototype is local and not exposed through REA CLI/MCP. Does a same-process private mode belong in the initial scope, or should the first ETW provider wait for ordinary selected-process capture and its privileged verification?

<!-- gh-comment-id:6157033253 --> @LcokHcak commented on GitHub (Oct 13, 2026): Controlled follow-up: I verified a narrower **same-process private logger** path on Windows x64 (10.0.26200), using only a self-owned synthetic provider and one finite session. A native `EventRegister` provider was enabled in the same process as `StartTraceW`; three `EventWriteString` calls returned success. The offline `OpenTraceW`/`ProcessTrace` consumer returned success and read five ETL records, three of which carried the expected provider GUID and the three distinct synthetic labels (`enter`, `branch-App`, `exit`) in order. The session was stopped and the provider unregistered; the pre-stop query reported `EventsLost=0` and `LogBuffersLost=0`. This corrects the earlier statement that no decodable private ETW trace was obtained. These labels were deliberately written by the fixture; they are **not** observed function entries, branches, or exits. The result does not validate an ordinary cross-process ETW session, a Windows system provider, complete process flow, or production-safe `EventWriteString` use. I currently have no isolated Windows host with administrator or Performance Log Users privileges for that separate acceptance lane. The local common-trace prototype projects the three records as `provider-event / instant`, retains their ETL callback indices and PID/TID, and now preserves exact `windows-filetime-100ns` values. A millisecond-only projection collapsed all three distinct timestamps into one millisecond. The prototype is local and not exposed through REA CLI/MCP. Does a same-process private mode belong in the initial scope, or should the first ETW provider wait for ordinary selected-process capture and its privileged verification?
Author
Owner

@LcokHcak commented on GitHub (Oct 14, 2026):

Controlled same-process private ETW follow-up, still not an ordinary cross-process collector:

  • I repeated the owned EventWriteString fixture in a finite private in-process session and retained its ETL, controller result and offline reader result. Three fixture writes succeeded; offline ProcessTrace saw five callbacks, three from the selected provider with distinct exact FILETIME values. The session stopped and unregistered successfully, and the named session was absent afterward.
  • Unlike the earlier pre-stop query, the successful ControlTrace(..., EVENT_TRACE_CONTROL_STOP) returned final EventsLost=0, LogBuffersLost=0, RealTimeBuffersLost=0 and two written buffers. Microsoft documents that a successful stop updates final run statistics. A local offline projection now accepts that event-loss count only when the final stop record matches the decoded ETL path and provider GUID, and reports loss as unknown on missing/failed stop or buffer loss.
  • A local cross-provider v1 schema check passed with 17 real Frida selected events, these three real private ETW provider events, and two synthetic bpftrace records. Their loss fields are respectively unknown / 0 / unknown. The ETW zero is only the private session's reported loss; it does not establish complete execution flow or general cross-process ETW permissions.

No public CLI/MCP provider or privileged session has been added. Is this bounded, read-only private ETL projection a suitable first Windows scope? Ordinary cross-process ETW still needs a separate isolated permission and host-effects acceptance run, which I cannot perform in the current environment.

<!-- gh-comment-id:6160749223 --> @LcokHcak commented on GitHub (Oct 14, 2026): Controlled same-process private ETW follow-up, still **not** an ordinary cross-process collector: - I repeated the owned `EventWriteString` fixture in a finite private in-process session and retained its ETL, controller result and offline reader result. Three fixture writes succeeded; offline `ProcessTrace` saw five callbacks, three from the selected provider with distinct exact FILETIME values. The session stopped and unregistered successfully, and the named session was absent afterward. - Unlike the earlier pre-stop query, the successful `ControlTrace(..., EVENT_TRACE_CONTROL_STOP)` returned final `EventsLost=0`, `LogBuffersLost=0`, `RealTimeBuffersLost=0` and two written buffers. [Microsoft documents](https://learn.microsoft.com/en-us/windows/win32/etw/configuring-and-starting-an-event-tracing-session) that a successful stop updates final run statistics. A local offline projection now accepts that event-loss count only when the final stop record matches the decoded ETL path and provider GUID, and reports loss as unknown on missing/failed stop or buffer loss. - A local cross-provider v1 schema check passed with 17 real Frida selected events, these three real private ETW provider events, and two **synthetic** bpftrace records. Their loss fields are respectively unknown / 0 / unknown. The ETW zero is only the private session's reported loss; it does not establish complete execution flow or general cross-process ETW permissions. No public CLI/MCP provider or privileged session has been added. Is this bounded, read-only private ETL projection a suitable first Windows scope? Ordinary cross-process ETW still needs a separate isolated permission and host-effects acceptance run, which I cannot perform in the current environment.
Author
Owner

@LcokHcak commented on GitHub (Oct 14, 2026):

Local exploratory update: a fresh owned Windows same-process private ETW run registered and enabled one controlled provider, wrote three EventWriteString markers, and stopped/unregistered successfully. The offline reader selected three matching provider/PID events from five callbacks, retaining exact FILETIME values. The final ControlTrace STOP report had EventsLost=0, LogBuffersLost=0 and RealTimeBuffersLost=0 for this private session. A separate cancellation-after-start run retained zero selected events; its v2 batch still identifies the target PID and provider, and a mismatched final-stop PID is rejected.

These are controlled provider events, not arbitrary function-flow tracing. Private same-process ETW does not establish ordinary cross-process capture, which remains untested without an isolated Windows host with the required privileges. The adapter is local-only and is not exposed through CLI/MCP. Please clarify whether this narrow offline private-session projection is a useful first scope, and what boundary and host-impact verification would be needed for any later cross-process session support.

<!-- gh-comment-id:6165131971 --> @LcokHcak commented on GitHub (Oct 14, 2026): Local exploratory update: a fresh owned Windows same-process private ETW run registered and enabled one controlled provider, wrote three `EventWriteString` markers, and stopped/unregistered successfully. The offline reader selected three matching provider/PID events from five callbacks, retaining exact FILETIME values. The final `ControlTrace STOP` report had `EventsLost=0`, `LogBuffersLost=0` and `RealTimeBuffersLost=0` for this private session. A separate cancellation-after-start run retained zero selected events; its v2 batch still identifies the target PID and provider, and a mismatched final-stop PID is rejected. These are controlled provider events, not arbitrary function-flow tracing. Private same-process ETW does not establish ordinary cross-process capture, which remains untested without an isolated Windows host with the required privileges. The adapter is local-only and is not exposed through CLI/MCP. Please clarify whether this narrow offline private-session projection is a useful first scope, and what boundary and host-impact verification would be needed for any later cross-process session support.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#979
No description provided.