Files
dohertj2 c95824a65d Initial commit: managed .NET 10 AVEVA Historian SDK + reverse-engineering toolkit
Full read-only SDK (src/AVEVA.Historian.Client) implementing the CLAUDE.md required
surface against AVEVA Historian's binary WCF protocol — no native AVEVA runtime
dependency. All operations live-verified against a local Historian:

- ProbeAsync, ReadRawAsync, ReadAggregateAsync, ReadAtTimeAsync, ReadEventsAsync
- BrowseTagNamesAsync, GetTagMetadataAsync (17 native data-type codes mapped)
- GetConnectionStatusAsync, GetStoreForwardStatusAsync, GetSystemParameterAsync
- 108/108 unit + integration tests pass

Includes the reverse-engineering toolkit (tools/AVEVA.Historian.ReverseEngineering)
used to decode the protocol: WCF probes, IL inspection via dnlib, and IL-rewrite
instrumentation (instrument-wcf-{write,read}message etc.) plus the .NET Framework
trace harness (tools/AVEVA.Historian.NativeTraceHarness) for parity testing.

Sanitized handoff evidence under docs/reverse-engineering/. Native AVEVA binaries
(current/, aveva-install-x64/, aveva-install-x86/) are gitignored — fetch separately
from the AVEVA installer.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-04 06:31:48 -04:00

111 lines
4.0 KiB
Markdown

# Native Export Findings
Source binaries:
- `current\aahClient.dll`
- `current\aahClientCommon.dll`
- `current\aahClientManaged.dll`
`dumpbin` was not available on PATH, so the PE export table was read directly.
## Export Counts
- `aahClient.dll`: 99 exports
- `aahClientCommon.dll`: 2 exports
- `aahClientManaged.dll`: 0 exports
Current DLL hashes are recorded in `capture-manifest.json`.
The x86 and x64 `aahClient.dll` builds both expose 99 exports. The undecorated
`mdas_*` names are stable across architectures; decorated C++ names differ only
by pointer/reference decoration.
This confirms `aahClientManaged.dll` is a managed/C++-CLI wrapper with no native
export surface of its own. The useful native ABI is in `aahClient.dll` and
`aahClientCommon.dll`.
## Relevant Query Exports
The exports below are the first ABI anchors for reproducing the native client
behavior in managed C#:
```text
mdas_StartDataRetrievalQuery
mdas_GetNextDataQueryResult
mdas_StartEventDataRetrievalQuery
mdas_GetNextEventDataQueryResult
mdas_StartBlockRetrievalQuery
mdas_GetNextBlockQueryResult
mdas_EndQuery
mdas_GetSystemParameter
mdas_GetRuntimeParameter
mdas_SetConnectionParameter
mdas_ConfigureParameter
mdas_SetParameter
mdas_GetSFParameter
mdas_SetSFParameter
```
`aahClient.dll` also exports decorated C++ names for newer structures:
```text
?mdas_AddHistorianValue2@@YAHKPEAUHISTORIAN_VALUE2@@PEAUHISTORIAN_ERROR@@@Z
?mdas_GetNextEventDataQueryResult@@YAHKKPEAVEventQueryResultRow@@PEAUHISTORIAN_ERROR@@@Z
?mdas_StartEventDataRetrievalQuery@@YAHK_K0IIGGAEAVEventQueryFilters@@PEB_WPEAKPEAUHISTORIAN_ERROR@@@Z
```
## Client Common Exports
`aahClientCommon.dll` exposes only:
```text
?CreateClientCommon@@YAPEAVIClientCommon@@PEA_W@Z
?DeleteClientCommon@@YAXPEAVIClientCommon@@@Z
```
That suggests `aahClientCommon.dll` owns the higher-level client object used by
the C++/CLI wrapper, while `aahClient.dll` exposes the procedural MDAS query ABI.
## Wrapper Load Evidence
The `mdas_*` exports remain useful ABI anchors, but they are not yet proven to
be on the active `aahClientManaged.dll` wrapper path.
Two local integrated read probes are negative evidence for that path:
- `dumpbin /dependents current\aahClientManaged.dll` shows no dependency on
`aahClient.dll` or `aahClientCommon.dll`. The mixed-mode wrapper imports
system DLLs such as `WS2_32.dll`, `Secur32.dll`, `RPCRT4.dll`, `NETAPI32.dll`,
`CRYPT32.dll`, and `mscoree.dll`.
- `Test-AahClientManagedReadIntegrated.ps1 -DumpLoadedModules` lists only
`aahClientManaged.dll` among the AVEVA/current DLLs during a successful
wrapper read. It does not show `aahClient.dll` or `aahClientCommon.dll` loaded
as separate modules.
- `Attach-NativeTraceHarnessAahClientExportCapture.ps1` attached before
`aahClientManaged.dll` load and attempted to hook interesting exports from
`aahClient.dll`. The same native direct history read succeeded, but the Frida
capture never observed `aahClient.dll` being loaded and installed no export
hooks.
This does not make the exported `mdas_*` ABI irrelevant; it may still be a
separate supported native client surface. It does mean the current C++/CLI
wrapper evidence target remains inside `aahClientManaged.dll` or a lower system
boundary, not `aahClient.dll` exports.
Follow-up system-boundary Frida passes also failed to catch the active wrapper
transport through exported user-mode APIs. Even when a Debian relay connection
was owned by the harness PID, hooks on exported Winsock calls, `WSAIoctl`,
`mswsock` extension exports, and `NtDeviceIoControlFile` produced no call
callbacks before the server-side security reset. Treat these exports as useful
static/native SDK evidence, not as the active wrapper capture route.
## Next ABI Tasks
- Demangle the decorated exports to recover exact signatures.
- Compare x86 and x64 export tables for drift.
- Capture call arguments for `mdas_StartDataRetrievalQuery`,
`mdas_GetNextDataQueryResult`, `mdas_StartEventDataRetrievalQuery`, and
`mdas_EndQuery`.
- Correlate the ABI calls with packet captures to map exported function calls to
wire frames.