R1.8/R1.9: empirical summary-query probe + enum-dump RE command

Pushed on recovering the summary query params. Findings:

- Added `enum-dump` to the RE CLI (dumps a managed enum's literal members).
  Confirmed INSQL_QUERYTYPE / HISTORIAN_SUMMARYTYPE are value__-only in the
  managed metadata — their named members are native-side constants, so they
  can't be recovered statically. Same for CColumnNameMap.LoadColumnNameMap
  (column->bit built from native string/const data, not IL ldstr/ldc).

- Live-probed StartQuery2 against SysTimeSec sweeping QueryType/SummaryType/
  ColumnSelectorFlags. The server ACCEPTS SummaryType 1/2/4/5 (returns a valid
  version-9 buffer) but yields 0 rows; column flags don't change that;
  QueryType 15/16 don't exist. So a summary query is NOT Full+SummaryType+
  flags — the config lives in the AutoSummaryParameters trailer (currently
  zeroed) and/or a native summary QueryType.

Conclusion recorded in the plan: the request shape needs a NATIVE capture
(instrument-wcf-writemessage on a real summary query), not managed-metadata
recovery or blind probing. Decode targets remain located. No guessed code in
src/; probe scaffolding removed. 208 tests green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Joseph Doherty
2026-06-20 16:11:35 -04:00
parent 085f01123c
commit 34e352ba28
2 changed files with 74 additions and 0 deletions
+26
View File
@@ -34,6 +34,32 @@ Found via `methods … Summary` + `dnlib-method`:
| `CTypeMetadata.IsAnalogSummary` / `IsStateSummary` | `0x060001A4/A5` | server-side type gating |
| `INSQL_QUERYTYPE` / `HISTORIAN_SUMMARYTYPE` | enums `0200013F` / `02000191` | the `QueryType` / `SummaryType` values to send |
## Empirical probe results (2026-06-20, live `SysTimeSec` over `StartQuery2`)
Swept `QueryType`/`SummaryType`/`ColumnSelectorFlags` against the live 2020 server:
- `QueryType=2 (Full)`, `SummaryType ∈ {0,3,6}` → normal 109-byte version-9 data buffer.
- `QueryType=2`, `SummaryType ∈ {1,2,4,5}`**valid version-9 buffer with 0 rows** (`09 00 00 00 00 00`).
The server **accepts** these summary types but yields no rows.
- The 0-row result is **unchanged** by `ColumnSelectorFlags` (tried default, all-bits
`0xFFFF…FFFF`, high-dword, low-48). So column flags are *not* the unlock.
- `QueryType ∈ {15,16}``GetNext` blocks/times out (no such INSQL_QUERYTYPE ordinal).
**Conclusion:** a summary query is *not* `Full + SummaryType + column flags`. The summary
configuration lives elsewhere in the request — almost certainly the **`AutoSummaryParameters`
trailer** (`SerializeFullHistoryRequest` currently writes it all-zero via
`WriteAutoSummaryParameters`) and/or a native summary `QueryType`. Both are **native-side
constants** (`HISTORIAN_SUMMARYTYPE` / `INSQL_QUERYTYPE` are `value__`-only in managed metadata;
`CColumnNameMap.LoadColumnNameMap` builds column→bit via native string/const data, not IL
`ldstr`/`ldc`). So they cannot be recovered from managed metadata, and blind probing of the
obvious fields returns empty.
**Therefore the right next step is a native request capture, not more probing:** drive the native
client (NativeTraceHarness / a real summary query) and capture the `pRequestBuff` bytes via the
existing `instrument-wcf-writemessage` pipeline — the same method that produced every other proven
request shape (reads, events, EnsT2). Diff that buffer against a normal Full request to read off
the exact `QueryType` + `SummaryType` + `AutoSummaryParameters` layout, then implement against it.
## Open questions (nail these next, in order)
1. **Request params.** Recover the exact `QueryType` + `SummaryType` (+ whether `ColumnSelectorFlags`