param( [ValidateSet("history", "event")] [string]$Scenario = "history", [string]$ServerName = "localhost", [string]$TagName = "OtOpcUaParityTest_001.Counter", [string]$RetrievalMode = "Full", [int]$LookbackMinutes = 1440, [int]$MaxRows = 1, [UInt64]$ResolutionTicks = 0, [switch]$DirectConnection, [int]$PreLoadSleepSeconds = 10, [int]$ConnectionWaitSeconds = 15, [string]$OutputPath = $null ) $ErrorActionPreference = "Stop" $repoRoot = Split-Path -Parent $PSScriptRoot $fridaScript = Join-Path $PSScriptRoot "frida\aahclient-exports.js" $harness = Join-Path $repoRoot "tools\AVEVA.Historian.NativeTraceHarness\bin\Debug\net481\AVEVA.Historian.NativeTraceHarness.exe" if (-not (Test-Path -LiteralPath $harness)) { throw "Missing harness executable. Run dotnet build .\Histsdk.slnx first." } if ([string]::IsNullOrWhiteSpace($OutputPath)) { $stamp = Get-Date -Format "yyyyMMdd-HHmmss" $OutputPath = Join-Path $repoRoot "docs\reverse-engineering\aahclient-export-frida-$Scenario-$stamp.ndjson" } $outputDirectory = Split-Path -Parent $OutputPath New-Item -ItemType Directory -Force -Path $outputDirectory | Out-Null $childOut = Join-Path $env:TEMP ("histsdk-aahclient-export-{0}.out.log" -f ([Guid]::NewGuid().ToString("N"))) $childErr = Join-Path $env:TEMP ("histsdk-aahclient-export-{0}.err.log" -f ([Guid]::NewGuid().ToString("N"))) $args = @( "--scenario", $Scenario, "--server-name", $ServerName, "--tag", $TagName, "--retrieval-mode", $RetrievalMode, "--lookback-minutes", $LookbackMinutes.ToString(), "--max-rows", $MaxRows.ToString(), "--connection-wait-seconds", $ConnectionWaitSeconds.ToString(), "--pre-load-sleep-seconds", $PreLoadSleepSeconds.ToString() ) if ($ResolutionTicks -gt 0) { $args += @("--resolution-ticks", $ResolutionTicks.ToString()) } if ($DirectConnection) { $args += "--direct-connection" } Write-Host "Starting native trace harness with $PreLoadSleepSeconds second pre-load pause." $process = Start-Process -FilePath $harness -ArgumentList $args -WorkingDirectory $repoRoot -RedirectStandardOutput $childOut -RedirectStandardError $childErr -PassThru -WindowStyle Hidden try { Start-Sleep -Seconds 1 Write-Host "Attaching aahClient.dll export Frida capture to PID $($process.Id). Capture: $OutputPath" & frida -q -p $process.Id -l $fridaScript 2>&1 | Tee-Object -FilePath $OutputPath if (-not $process.HasExited) { $process.WaitForExit(30000) | Out-Null } } finally { if (-not $process.HasExited) { Stop-Process -Id $process.Id -Force -ErrorAction SilentlyContinue } "--- native stdout ---" | Tee-Object -FilePath $OutputPath -Append Get-Content -LiteralPath $childOut -ErrorAction SilentlyContinue | Tee-Object -FilePath $OutputPath -Append "--- native stderr ---" | Tee-Object -FilePath $OutputPath -Append Get-Content -LiteralPath $childErr -ErrorAction SilentlyContinue | Tee-Object -FilePath $OutputPath -Append Remove-Item -LiteralPath $childOut, $childErr -ErrorAction SilentlyContinue } Write-Host "Capture complete: $OutputPath"