param( [Parameter(Mandatory = $true)] [string]$Name, [Parameter(Mandatory = $true)] [string[]]$HarnessArgs, [switch]$NoLoopback ) $ErrorActionPreference = 'Stop' $Root = Resolve-Path (Join-Path $PSScriptRoot '..\..') $Dumpcap = 'C:\Program Files\Wireshark\dumpcap.exe' $Harness = Join-Path $Root 'src\MxTraceHarness\bin\Release\net481\MxTraceHarness.exe' $ClientFridaScript = Join-Path $Root 'analysis\frida\mx-nmx-trace.js' $ServiceFridaScript = Join-Path $Root 'analysis\frida\nmxsvc-trace.js' $CaptureDir = Join-Path $Root "captures\$Name" New-Item -ItemType Directory -Force $CaptureDir | Out-Null $Pcap = Join-Path $CaptureDir 'loopback.pcapng' $HarnessLog = Join-Path $CaptureDir 'harness.log' $ClientFridaOut = Join-Path $CaptureDir 'client-frida.stdout.jsonl' $ClientFridaErr = Join-Path $CaptureDir 'client-frida.stderr.txt' $ServiceFridaOut = Join-Path $CaptureDir 'service-frida.stdout.jsonl' $ServiceFridaErr = Join-Path $CaptureDir 'service-frida.stderr.txt' $DumpOut = Join-Path $CaptureDir 'dumpcap.stdout.txt' $DumpErr = Join-Path $CaptureDir 'dumpcap.stderr.txt' $CommandFile = Join-Path $CaptureDir 'command.txt' foreach ($Path in @($Pcap, $HarnessLog, $ClientFridaOut, $ClientFridaErr, $ServiceFridaOut, $ServiceFridaErr, $DumpOut, $DumpErr)) { if (Test-Path $Path) { Remove-Item -LiteralPath $Path -Force } } $NmxSvc = Get-Process NmxSvc -ErrorAction Stop | Select-Object -First 1 $Frida = (Get-Command frida.exe -ErrorAction Stop).Source $FullHarnessArgs = @($HarnessArgs + @("--log=$HarnessLog", "--client=MxBoundary-$Name")) $ClientFridaArguments = @('-f', $Harness, '-l', $ClientFridaScript, '--') + $FullHarnessArgs $ServiceFridaArguments = @('-p', "$($NmxSvc.Id)", '-l', $ServiceFridaScript) "nmxsvc_pid=$($NmxSvc.Id)" | Out-File -Encoding UTF8 $CommandFile "nmxsvc_path=$($NmxSvc.Path)" | Out-File -Encoding UTF8 -Append $CommandFile "dumpcap=$Dumpcap" | Out-File -Encoding UTF8 -Append $CommandFile "frida=$Frida" | Out-File -Encoding UTF8 -Append $CommandFile "harness=$Harness" | Out-File -Encoding UTF8 -Append $CommandFile ("service_args=" + ($ServiceFridaArguments -join ' ')) | Out-File -Encoding UTF8 -Append $CommandFile ("client_args=" + ($ClientFridaArguments -join ' ')) | Out-File -Encoding UTF8 -Append $CommandFile $Dump = $null $ServiceFrida = $null try { $ServiceFrida = Start-Process -FilePath $Frida ` -ArgumentList $ServiceFridaArguments ` -PassThru ` -WindowStyle Hidden ` -RedirectStandardOutput $ServiceFridaOut ` -RedirectStandardError $ServiceFridaErr Start-Sleep -Seconds 3 if (-not $NoLoopback -and (Test-Path $Dumpcap)) { $Dump = Start-Process -FilePath $Dumpcap ` -ArgumentList @('-i', '\Device\NPF_Loopback', '-w', $Pcap, '-q') ` -PassThru ` -WindowStyle Hidden ` -RedirectStandardOutput $DumpOut ` -RedirectStandardError $DumpErr Start-Sleep -Seconds 2 } $ClientFrida = Start-Process -FilePath $Frida ` -ArgumentList $ClientFridaArguments ` -Wait ` -PassThru ` -NoNewWindow ` -RedirectStandardOutput $ClientFridaOut ` -RedirectStandardError $ClientFridaErr "client_exit_code=$($ClientFrida.ExitCode)" | Out-File -Encoding UTF8 (Join-Path $CaptureDir 'client-frida-exit.txt') } finally { if ($ServiceFrida -ne $null -and -not $ServiceFrida.HasExited) { Stop-Process -Id $ServiceFrida.Id -Force -ErrorAction SilentlyContinue } if ($Dump -ne $null -and -not $Dump.HasExited) { Stop-Process -Id $Dump.Id -Force -ErrorAction SilentlyContinue } if ($ServiceFrida -ne $null) { Wait-Process -Id $ServiceFrida.Id -Timeout 10 -ErrorAction SilentlyContinue | Out-Null } if ($Dump -ne $null) { Wait-Process -Id $Dump.Id -Timeout 10 -ErrorAction SilentlyContinue | Out-Null } } Get-ChildItem $CaptureDir | Select-Object Name, Length, LastWriteTime