Files
histsdk/docs/reverse-engineering/native-exports.md
T
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

4.0 KiB

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#:

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:

?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:

?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.