Commit Graph

6 Commits

Author SHA1 Message Date
Joseph Doherty ecbf282f6d [M2] mxaccess-rpc: NMX metadata + callback messages + OBJREF builder
Lands the codec-only prerequisites for M2 wave 3 (callback exporter).
The TCP server itself (port of ManagedCallbackExporter.cs's TcpListener
+ accept loop) follows next iteration in the mxaccess-callback crate.

New modules
- nmx_metadata.rs (9 tests) — port of NmxProcedureMetadata.cs.
  INmxService2 + INmxSvcCallback IIDs, NdrProcedureDescriptor with
  per-opnum metadata for the 9 INmxService2 procedures (opnums 3..11)
  and 2 INmxSvcCallback procedures (opnums 3, 4).
- nmx_callback_messages.rs (8 tests) — port of NmxSvcCallbackMessages.cs.
  parse_callback_request decodes OrpcThis + i32 size + i32 max_count +
  body bytes; encode_callback_response produces the 12-byte OrpcThat +
  HRESULT response.

objref.rs additions
- ComObjRefBuilder::create_standard_objref (8 tests) — port of the
  second class in ManagedCallbackExporter.cs:337-393. Pure-Rust OBJREF
  emitter that builds 68-byte header + dual-string array. Note this is
  *not* the Win32 CoMarshalInterface-based ComObjRefProvider.cs (still
  open as F6); it's the higher-level emitter the callback exporter
  uses to build OBJREF bytes from primitives.
- CALLBACK_OBJREF_AUTH_SERVICES const exposes the 7-entry auth-service
  tower-id table (NTLM SSP through Kerberos extension) the .NET
  reference advertises in every callback OBJREF.

Test count delta: 319 -> 344 (+25; mxaccess-rpc 102 -> 127, codec
unchanged at 215, parity unchanged at 2). All four DoD gates green.
Open followups touched: none new; F6 advances toward resolution but
the windows-rs Win32 wrapper part stays open.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 07:23:44 -04:00
Joseph Doherty 30138629d3 [M2] mxaccess-rpc: OXID + RemQI body codecs (wave 2)
Lands M2 wave 2 — two pure-Rust body-codec modules under
crates/mxaccess-rpc, plus a small inline ORPC framing port and a
crate-level type consolidation. Resolves F7+F8 from wave 1.

New modules
- guid.rs (4 tests) — hoisted from objref::Guid; shared by all of
  mxaccess-rpc. Resolves F7.
- error.rs — hoisted RpcError union (ShortRead, UnexpectedPacketType,
  UnknownPacketType, InvalidFragmentLength, TruncatedBindBody,
  InvalidAuthTrailer, MissingAuthValue, Decode). Resolves F8.
- orpc.rs (8 tests) — port of OrpcStructures.cs:1-141. ComVersion,
  OrpcThis (32-byte header), OrpcThat (8-byte header),
  MInterfacePointer (length-prefixed OBJREF), StdObjRef (40 bytes).
- object_exporter.rs (~530 LoC, 20 tests) — port of
  ObjectExporterMessages.cs:1-141. IObjectExporter IID, opnums,
  ResolveOxid request encoder + ResolveOxidResult/Failure parsers.
  Owned-string protocol labels cleaned up via Cow upgrade rather than
  Box::leak (ComDualStringEntry::protocol is now Cow<'static, str>).
- rem_unknown.rs (~340 LoC, 11 tests) — port of RemUnknownMessages.cs.
  IRemUnknown IID, RemQueryInterface request/response, RemQiResult.
  4-byte NDR pad in REMQIRESULT preserved as pad_after_hresult per
  CLAUDE.md unknown-bytes rule.

Test count delta: 277 -> 319 (+42; codec 215 unchanged, mxaccess-rpc
60 -> 102, codec parity 2 unchanged).
Open followups touched: F7 + F8 resolved; F9, F10, F11 added.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 07:14:29 -04:00
Joseph Doherty 95bd218183 [M2] mxaccess-rpc: NTLMv2 + DCE/RPC PDU + OBJREF parser (wave 1)
Lands M2 wave 1 — three pure-Rust modules under crates/mxaccess-rpc with
60 unit tests. Each is a 1:1 port of one .NET reference file:

- ntlm.rs (1137 LoC, 19 tests) — `ManagedNtlmClientContext.cs`. NTLMv2
  challenge/response, Type1/Type3 builders, sign() with RC4-sealed checksum
  and per-call sequence advance. Manual `Debug` impl that hides credentials;
  not Clone (rc4 0.2 cipher state is non-Clone). Pure-Rust crypto via
  hmac/md-5/md4/rc4 v0.2/rand v0.8 (rc4 0.2 chosen per design/review.md:78).
- pdu.rs (1573 LoC, 33 tests) — `DceRpcPdu.cs` + auth-trailer types from
  `DceRpcAuthentication.cs`. Bind/AlterContext/Auth3/Request/Response/Fault
  PDUs, NDR20 transfer syntax, auth_value with 4-byte alignment padding,
  preserved-byte fields per CLAUDE.md unknown-bytes rule.
- objref.rs (~470 LoC, 11 tests including a 366-byte captured OBJREF
  round-trip) — `ComObjRef.cs`. MEOW signature, OXID/OID/IPID, dual-string
  array with printable-ASCII escaping and security-binding boundary.
  ComObjRefProvider.cs deferred (windows-rs Win32 wrapper — see F6).

Every wire-byte claim cites src/MxNativeClient/<file>.cs:LINE per
CLAUDE.md "no fabricated protocol behaviour" rule.

Test count delta: 217 → 277 (+60)
Open followups touched: F1–F8 (new — see design/followups.md)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 06:54:39 -04:00
Joseph Doherty 16f2c148e5 design: parallelism map + /loop driver prompt + followups triage
- design/dependencies.md: per-milestone parallelism map for M2–M6 with
  per-phase agent budgets (peak 4 in parallel for M5 framing wave;
  7-agent maximum if M2 wave 1 + M5 framing run concurrently).
- design/prompt.md: self-contained /loop driver. Step 0 triages
  design/followups.md (auto-resolves items whose preconditions are met,
  shelves the rest). Step 3 spawns parallel general-purpose agents per
  design/dependencies.md when the active wave has multiple lanes.
  Sequential lanes (M4 Session core, M5 client integration) run directly.
  Local-commit-only by default; explicit stop conditions; Q7 hasDetailStatus
  audit reminder for any new conditional-read codec port.
- design/README.md: index updated to reference prompt.md, followups.md,
  dependencies.md, and review.md.

design/followups.md is intentionally not pre-created — prompt.md Step 0
bootstraps it on first /loop run.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 06:34:30 -04:00
Joseph Doherty fe2a6db786 Initial project state: .NET reference, design, Rust port (M0+M1), evidence
rust / build / test / clippy / fmt (push) Has been cancelled
Layout:
- src/                    .NET 10 x64 reference: MxNativeCodec, MxNativeClient,
                          MxAsbClient, probes, tests, harnesses. Executable spec.
- design/                 Architectural plan for the Rust port (M0–M6), error
                          model, protocol invariants, risks (R1–R16), adversarial
                          review log (review.md).
- rust/                   Rust workspace. M0 skeleton + M1 codec parity.
                          mxaccess-codec: 215 unit tests + 2 cross-implementation
                          parity tests (byte-identical against .NET reference).
                          Other crates are M0 stubs awaiting M2+.
- captures/               Frida + netsh + pcap evidence per CLAUDE.md
                          ("captures are evidence, not throwaway logs").
- analysis/               Decompiled C# (frida/proxy/decompiled-*),
                          Ghidra exports for native DLLs (`exports/` only —
                          working state at `projects/` and AVEVA's input
                          binaries at `input/` are gitignored).
- docs/                   Reverse-engineering reference docs.
- tools/                  Setup-LiveProbeEnv.ps1 (Infisical credential fetcher),
                          Compute-Crc.ps1 (.NET parity helper).
- .github/workflows/      Rust CI: fmt + build + test + clippy on Windows.
- LICENSE                 MIT (Joseph Doherty, 2026).

Verified:
- cargo test --workspace → 217 passed (215 unit + 2 .NET parity), 0 failed
- cargo clippy --workspace -- -D warnings → clean
- cargo fmt --all -- --check → clean
- cargo publish --dry-run -p mxaccess-codec → packages cleanly

Excluded from history (see .gitignore):
- **/bin, **/obj, **/target — build artifacts
- analysis/ghidra/projects/ — Ghidra working state (regenerable)
- analysis/ghidra/input/ — AVEVA proprietary DLLs (vendor IP)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-05 06:21:00 -04:00
Joseph Doherty 43733699b0 init: empty commit to unblock codex-companion 2026-05-05 03:25:40 -04:00