Skip to content

Seat Tools and Utilities

Seat utility binaries, IE/kiosk placeholders, GPU/display helpers, LaunchDataEditor, XenStore helpers, and diagnostics are consolidated here. Raw r2 report references are intentionally omitted; only useful imports, strings, URLs, and behavioral notes are retained.

Deep-only retained findings

  • https://wiki.nvidia.com/engwiki/index.php/Swak appears in ExternSwak_x86 strings.
  • https://confluence.nvidia.com/display/RMPER/PERFDEBUG appears in perfdebug strings.
  • GetNcpSecretKey appears in net132 / net164 symbol extraction; no literal key value was present.

2026-05-19 application notes

nvtopps-wmi64.exe

What this program actually does

nvtopps-wmi64.exe is a user-mode Windows Performance Counter provider that exposes NVIDIA GPU telemetry via the PerfLib API. It registers provider GUID {c2443ae9-f9bc-43ac-999d-27c7e9f67e9e} (manifest: gridperf/nvPerfProvider.man) and publishes counters for temperature, clocks, utilization, fan, and power under counter set NVIDIA.GPU0.

Windows Performance Monitor / logman data collectors (e.g. GridPerf) consume these counters. aws_log_uploader.py stops GridPerf (logman stop GridPerf) before session log upload.


Architecture / control flow

unlodctr/lodctr registration (nvPerfProvider.man)
  └─ nvtopps-wmi64.exe (PerfLib callback provider)
        ├─ PerfStartProviderEx
        ├─ PerfCreateInstance ("NVIDIA GPU #0")
        ├─ GpuCounter (RTTI class) — poll NVAPI/driver for each metric
        │     ├─ Temperature (°C)
        │     ├─ Graphics/Memory Clock (MHz)
        │     ├─ Graphics/FB/Video Utilization (%)
        │     ├─ Fan Cooler (%), Fan Speed (RPM)
        │     └─ Power (mW)
        ├─ PerfSetULongCounterValue (per counter update)
        └─ PerfStopProvider (shutdown)

Graceful degradation: strings like thermal counter not supported, gpu clock counter not supported indicate per-metric fallback when hardware/driver lacks a counter.


Windows API surface

CategoryAPIs
PerfLibPerfStartProviderEx, PerfCreateInstance, PerfSetULongCounterValue, PerfSetCounterSetInfo, PerfStopProvider
SCMOpenSCManagerW, OpenServiceW, QueryServiceConfigW
File/ModuleCreateFileW, GetModuleFileNameW/A, LoadLibraryExW, GetProcAddress
CRTMSVC C++ (.?AVGpuCounter@@, standard library RTTI)

Build path: D:\sw\pvt\jhutchins\nvtopps-wmi64\x64\Release\nvtopps-wmi64.pdb


PE metadata (readpe / radare2)

FieldValue
Pathgridperf/nvtopps-wmi64.exe
FormatPE32+ console x86-64
Size303,104 bytes
SHA-256ac1a0e9f5889b1a9b23f2a986f1696c69c4bd715c2dc6b0d33806773edcf53fa
CompiledThu Feb 16 16:15:42 2023
Entry0x14000d850
SubsystemWindows CUI
SignedNo

Counter manifest (nvPerfProvider.man)

IDURIMetric
1NVIDIA.GPU0.TemperatureTemperature (°C)
2NVIDIA.GPU0.GraphicsClockGraphics clock (MHz)
3NVIDIA.GPU0.MemoryClockMemory clock (MHz)
4NVIDIA.GPU0.GraphicsUtilizationGraphics util (%)
5NVIDIA.GPU0.FrameBufferUtilizationFB util (%)
6NVIDIA.GPU0.VideoUtilizationVideo util (%)
7NVIDIA.GPU0.FanCoolerFan cooler (%)
8NVIDIA.GPU0.FanSpeedFan speed (RPM)
9NVIDIA.GPU0.PowerPower (mW)

Collector template: gridperf/GridPerfMonTemplate.xml → output C:\perflogs\xen\GridPerf\ (1s sample interval).


Deployment and references

ItemEvidence
Manifestgridperf/nvPerfProvider.manapplicationIdentity="nvtopps-wmi64.exe"
Collectorgridperf/GridPerfMonTemplate.xml, GridPerfMonTemplate-4080.xml
Pandoramodify_gridperf queries logman query GridPerf
Sysmon allowlistCommandLine contains GridPerf; TargetFilename contains GridPerf
Log uploadaws_log_uploader.pylogman stop GridPerf before backup

Runtime timeline

Time (UTC)EventSource
18:42:46Pandora [modify_gridperf] No GridPerf modification neededlogs/startup/startup.log
18:42:47logman query GridPerf rc=0logs/startup/startup.log
18:48:42Sysmon: logman.exe process create (GridPerf query/stop context)logs/GCIS/ElmPluginOld.log

No direct log line naming nvtopps-wmi64.exe; provider runs as PerfLib host process when counters are collected.


Not verified

  • Exact NVAPI/driver entry points used inside GpuCounter (requires dynamic analysis on Windows with GPU present).
  • Whether provider auto-starts as a service or is loaded on-demand by PerfLib.

Evidence

  • readpe, r2_analyze.sh, strings on gridperf/nvtopps-wmi64.exe
  • gridperf/nvPerfProvider.man, GridPerfMonTemplate.xml
  • logs/startup/startup.log, services/SeatUpdater/aws_log_uploader.py

accelSwitch.exe

What this program actually does

accelSwitch.exe toggles Windows mouse acceleration / enhanced pointer precision via SystemParametersInfo (SPI_SETMOUSE / SPI_GETMOUSE). Called with no arguments during Pandora bootstrap to disable pointer precision for consistent cloud-gaming input.

Deployed: C:\Asgard\tools\accelSwitch.exe. Size: 22,016 bytes. PE32 CUI i386, MSVC 2013.


Behavior

String evidence:

  • No argument will toggle mouse acceleration / enhance pointer precision.
  • Usage: / SPI_SETMOUSE or SPI_GETMOUSE
  • PDB: C:\projects\accelswitch\Release\accelSwitch.pdb

No-args invocation toggles acceleration off (Pandora step disable_mouse_precision logs "Successfully disabled mouse accel").


Windows API surface

DLLAPIs
USER32.dllSystemParametersInfo (SPI_SETMOUSE, SPI_GETMOUSE)
KERNEL32.dllGetLastError, heap/time APIs
MSVCP120/MSVCR120C++ iostream error handling

Deep extract winapi: GetLastError, GetProcessHeap, QueryPerformanceCounter, GetSystemTimeAsFileTime.

| r2 confirmed | SystemParametersInfoW (USER32.dll) |


Pandora invocation

StepCommandResult
disable_mouse_precisionC:\Asgard\tools\accelSwitch.exe (no args)rc=0

logs/startup/startup.log 18:42:44 UTC.


Disassembly hints

  • Entry 0x3411 (objdump); small CUI with USER32 SPI call in main path.
  • iostream error strings (bad conversion) on invalid CLI args.
  • No registry writes confirmed — SPI-only path.

Evidence

  • docs/reverse-engineering/_analysis/accelSwitch.strings_filtered.txt
  • logs/startup/startup.log

CountVisibleGPUs.exe

Repository path: tools/CountVisibleGPUs.exe
Deployed path: C:\Asgard\tools\CountVisibleGPUs.exe

What this program actually does

CountVisibleGPUs.exe is a legacy OSL console utility (2013) that counts NVIDIA GPUs visible to NVAPI on a Windows seat. It dynamically loads nvapi.dll / nvpowerapi.dll, calls NvAPI_InitializeNvAPI_EnumPhysicalGPUs, and uses SetupAPI + Config Manager (SETUPAPI.dll, CFGMGR32.dll) as a secondary PnP enumeration path. Output is written to the console (stdout); exit code semantics not observed in this snapshot.

It is not invoked by Pandora boot (startup.log uses devcon.exe for GPU checks instead). Present on the seat image as a diagnostic / manual ops tool.


Architecture / control flow (recovered)

main @ 0x004014f0
  ├─ CRT / SEH init (entry0 @ 0x00457b6c)
  ├─ LoadLibrary("nvapi.dll") via GetProcAddress
  │     └─ nvapi_QueryInterface → NvAPI_Initialize, NvAPI_EnumPhysicalGPUs
  ├─ Optional nvpowerapi.dll load
  ├─ SetupDiGetClassDevsW / SetupDiEnumDeviceInfo (display adapters)
  ├─ CM_Get_DevNode_Status / CMP_WaitNoPendingInstallEvents
  └─ Print count + "ERROR" path on NVAPI failure

Build path: C:\Users\gprusak.NVIDIA.COM\nv_repo\sw\gcomp\dev\src\OSL\CountVisibleGPUs\Release\CountVisibleGPUs.pdb


External interfaces

InterfaceRole
CLINo args observed in strings; likely zero-argument invocation
NVAPINvAPI_Initialize, NvAPI_EnumPhysicalGPUs (dynamic)
PnPSetupAPI device enumeration, CFGMGR32 devnode status
COMole32.dll imported (purpose not recovered)
StdoutConsole output via WriteConsoleW / WriteFile

No network, registry, or service surface.


PE metadata

FieldValue
SHA-25659365617f5f3c25f0b745da3e6b32dbdc250276e39aa01e1165805f8c336198e
Size494,592 bytes
FormatPE32 console i386, MSVC, compiled 2013-10-01
SubsystemWindows CUI
Canaryenabled (/GS)
Exportsnone

Notable strings

StringMeaning
NvAPI_InitializeNVAPI entry
NvAPI_EnumPhysicalGPUsGPU enumeration
nvapi.dll / nvpowerapi.dllDynamically loaded
ERRORFailure label on stdout
iostream stream errorC++ iostream error path

Runtime timeline

SourceFinding
logs/startup/startup.logNot invoked. Pandora check_gpu_script uses devcon.exe, ForceDisp.exe, and registry reads instead
Workspace grepNo other log references in this snapshot

Failure modes

ConditionBehavior (inferred)
nvapi.dll missing / NvAPI_Initialize failPrints ERROR, non-zero exit (not verified)
Zero GPUs enumeratedLikely prints 0 (not verified)
PnP enumeration mismatchSetupAPI path may supplement NVAPI count

Relationships

ComponentInteraction
devcon.exePandora's primary GPU validation tool at boot
ForceDisp.exeUsed in same check_gpu_script step for resolution forcing
NVAPI stackSame API family as GFE / driver tooling

Not verified

  • Exact stdout format (count only vs. per-GPU listing).
  • Exit codes for success / NVAPI failure / zero GPUs.
  • Whether ole32.dll is used on the hot path or linked incidentally.
  • Any scheduled task or manual ops playbook referencing this binary.

Evidence

  • strings / radare2 on tools/CountVisibleGPUs.exe
  • _analysis/CountVisibleGPUs.strings_filtered.txt
  • logs/startup/startup.log (absence of invocation)

drs_setting.exe

What this program actually does

drs_setting.exe is NVIDIA Driver Settings (DRS) CLI v1.5 — reads/writes/queries driver profile settings via the display driver session. Used for per-game and global driver tuning on seats.

Sysmon allowlist entry. Not invoked during Pandora bootstrap in captured snapshot.


CLI interface

drs_settings -h
drs_settings 0x1234           Display setting value
drs_settings 0x1234=5678      Write setting

PDK logging framework embedded.


Windows API surface

CategoryAPIs
NVAPI/DRSDynamic NVAPI driver settings session
ProcessCreateProcessAsUserW, CreateThread, CreateMutexA
SyncMutex for single-instance

PE32 CUI (2015). Single KERNEL32 import in filtered dump — NVAPI loaded dynamically.

| r2 confirmed | GetProcAddress (KERNEL32.dll) | LoadLibraryExW (KERNEL32.dll) | CreateProcessW (KERNEL32.dll) | CreateProcessA (KERNEL32.dll) | CreateFileW (KERNEL32.dll) |


Pandora invocation

None in logs/startup/startup.log.


Disassembly hints

  • Hex setting ID parse: 0x prefix → DRS setting ID lookup.
  • = separator → write path vs read-only display.
  • NVAPI DRS session init before any setting query.

Evidence

  • docs/reverse-engineering/_analysis/drs_setting.strings_filtered.txt

ExternSwak_x86.exe

What this program actually does

ExternSwak_x86.exe is NVIDIA SWAK (System Wide Assessment Kit) — a GUI diagnostic collector producing ExternSwak.swk support bundles. Collects GPU/display/config info via OpenGL, D3D9, and DXGI paths for NVIDIA support escalation.

Referenced in test/l1test.py. Not in Pandora bootstrap.


Behavior

  • GUI wizard workflow
  • Wiki reference: Describe Asgard Config Info
  • Error: Unable to find a Swak server
  • Output: ExternSwak.swk archive

Windows API surface

CategoryAPIs
GraphicsOPENGL32, d3d9, CreateDXGIFactory
DisplayEnumDisplayDevicesA/W
ProcessEnumProcesses, EnumProcessModules, CreateRemoteThread
SetupSETUPAPI.dll
NetworkWS2_32.dll

PE32 GUI i386 (2013). 14+ DLL imports. Large IAT (~0x87c entries).

| r2 confirmed | wglGetProcAddress (OPENGL32.dll) | VirtualProtect (KERNEL32.dll) | CreateProcessA (KERNEL32.dll) |


Pandora invocation

None in logs/startup/startup.log.


Disassembly hints

  • Multi-API graphics probe sequence: OpenGL → D3D9 → DXGI.
  • CreateRemoteThread → cross-process GPU state capture.
  • SWK file write at wizard completion.

Evidence

  • docs/reverse-engineering/_analysis/ExternSwak_x86.strings_filtered.txt

ForceDisp.exe

What this program actually does

ForceDisp.exe is NVIDIA's FakeDisp / forced-display tool for VGX/cloud GPU seats. It loads custom EDID .hex blobs onto GPU outputs, forcing resolution/mode tables independent of physical monitor EDID. Distinguishes FORCED vs REAL displays. Does not support DP 1.2 monitors (string warning).

Used by Pandora check_gpu_script to inject NvidiaVGX_custom_all_resolutions.hex at boot.


CLI interface (interactive/menu)

Pandora pipes commands via echo:

InvocationMeaning
echo y | ForceDisp.exe f <hexfile> 0 100Force EDID from hex onto GPU 0, output 100 → out=action f
echo e 0 100 q | ForceDisp.exeEnumerate GPU 0 output 100, then quit

Action letters: f (force), e (enumerate), q (quit). Wiki reference in strings: FakeDisp tool docs.


Windows API surface

CategoryAPIs
NVAPIDynamic nvapi_QueryInterface; NvAPI_GPU_SetEDID, NvAPI_GPU_GetEDID, NvAPI_EnumPhysicalGPUs, NvAPI_GPU_GetAllOutputs
UnwindRtlLookupFunctionEntry (x64 SEH)

PE32+ CUI x64 (2022). KERNEL32 + dynamic NVAPI.

| r2 confirmed | GetProcAddress (KERNEL32.dll) | LoadLibraryExW (KERNEL32.dll) | CreateFileW (KERNEL32.dll) |


Pandora invocations

StepCommandResult
check_gpu_scriptecho y | "c:\asgard\tools\forcedisp\ForceDisp.exe" f "c:\asgard\tools\forcedisp\NvidiaVGX_custom_all_resolutions.hex" 0 100rc=0, out=action f
check_gpu_scriptecho e 0 100 q | "c:\asgard\tools\forcedisp\ForceDisp.exe"rc=0

Also preceded by devcon.exe listclass Display and devcon.exe status PCI\VEN_10DE in same step.

logs/startup/startup.log 18:42:45 UTC.


Disassembly hints

  • Interactive menu reads stdin — Pandora uses piped echo for automation.
  • action f string emission confirms force-EDID code path taken.
  • NVAPI GPU/output index args map to NvAPI_GPU_GetAllOutputs enumeration.

Evidence

  • docs/reverse-engineering/_analysis/ForceDisp.strings_filtered.txt
  • logs/startup/startup.log

Win10-ForceDispx64.exe

What this program actually does

Win10-ForceDispx64.exe is the Windows 10+ x64 variant of NVIDIA FakeDisp/ForceDisp. Same NVAPI EDID forcing semantics as ForceDisp.exe, with additional nvpowerapi.dll support and internal name FakeDisplay.exe.

Not invoked by Pandora in this seat snapshot — Pandora uses ForceDisp.exe instead.


CLI interface

Interactive/menu-driven (same action letters as ForceDisp):

  • h — help
  • f, e, q — force, enumerate, quit

Windows API surface

CategoryAPIs
NVAPInvapi_QueryInterface, nvapi_pepQueryInterface
Power APInvpowerapi.dll dynamic load
ProcessCreateProcessAsUserW (can spawn child processes)

PE32+ CUI x64. Minimal RTTI (3 types). KERNEL32-heavy imports.

| r2 confirmed | GetProcAddress (KERNEL32.dll) | LoadLibraryExW (KERNEL32.dll) | CreateProcessW (KERNEL32.dll) | CreateProcessA (KERNEL32.dll) | CreateFileW (KERNEL32.dll) | LoadLibraryW (KERNEL32.dll) |


Pandora invocation

None in logs/startup/startup.log. Present in tools/forcedisp/ as Win10+ alternative.


Disassembly hints

  • Compare IAT with ForceDisp.exe — additional nvpowerapi.dll load path.
  • CreateProcessAsUserW suggests optional child-process spawn for elevated EDID ops.

Evidence

  • docs/reverse-engineering/_analysis/Win10-ForceDispx64.strings_filtered.txt

GameSeatDisplay.exe

What this program actually does

GameSeatDisplay.exe is a console utility for cloud seat display/GPU head management. Activates NVIDIA display head, checks NV display attachment, sets P-state perf mode, and disables frame limiters via NVAPI/SetDisplayConfig.

Used during session setup or display troubleshooting — not in Pandora bootstrap in captured snapshot.


CLI interface

GameSeatDisplay.exe [OPTIONS]
  --help
  --activate-display        Switch to GPU display head
  --is-nvdisplay-attached   Returns true if NVIDIA GPU display in use

Also sets perf strings: PS_FRAMERATE_LIMITER_*, P-state performance mode.


Windows API surface

CategoryAPIs
Display configGetDisplayConfigBufferSizes, QueryDisplayConfig, SetDisplayConfig
GDIEnumDisplayDevicesA
SCMOpenSCManagerW
NVAPIDynamic load

PE32+ CUI x64. CRT/iostream error handling.

| r2 confirmed | GetProcAddress (KERNEL32.dll) | CreateFileW (KERNEL32.dll) | LoadLibraryExW (KERNEL32.dll) |


Pandora invocation

None in logs/startup/startup.log.


Disassembly hints

  • Boost/options or manual argv parse near --activate-display string.
  • NVAPI init before display head activation.
  • --is-nvdisplay-attached → stdout true/false for scripting.

Evidence

  • docs/reverse-engineering/_analysis/GameSeatDisplay.strings_filtered.txt

gfndesktop.exe

What this program actually does

gfndesktop.exe is the GFN kiosk desktop shell that replaces explorer.exe on cloud gaming seats. Creates fake tray/taskbar windows (Shell_TrayWnd, MSTaskSwWClass), handles WM_DISPLAYCHANGE, and manages GFN desktop background updates. Data paths under C:\ProgramData\NVIDIA Corporation\nvstreamsvc\.

Invoked by Smithy V1: smithy.exe -s on -p default (via enablegfndesktop.bat). Also WAR-replaced during smithy install.


Architecture

gfndesktop.exe (PE32+ GUI x64, 2026 build)
  └─ RegisterClassExW / CreateWindowExW
  └─ RegisterShellHookWindow (shell integration)
  └─ RegisterWindowMessageW (custom GFN messages)
  └─ SetForegroundWindow / SetWindowPos / GetDesktopWindow
  └─ WM_DISPLAYCHANGE handler (multi-monitor)
  └─ SHELL32 + GDI32 rendering

Windows API surface

CategoryAPIs
WindowingCreateWindowExW, RegisterClassExW, SetWindowPos, SetForegroundWindow
ShellRegisterShellHookWindow, SHELL32.dll
GDIGDI32.dll (background rendering)
DesktopGetDesktopWindow

MSVC 14 runtime imports. PE32+ GUI x64.

| r2 confirmed | LoadLibraryW (KERNEL32.dll) | GetProcAddress (KERNEL32.dll) | SystemParametersInfoW (USER32.dll) |


Install / runtime timeline

EventSource
WAR replacement to C:\Asgard\Tools and C:\WindowssmithySoftwareInstall.log
Smithy V1 attempts explorer → gfndesktop swapSmithy.log
CLI: smithy.exe -s on -p defaultenablegfndesktop.bat

Pandora: No direct run_cmd in startup.log.


Disassembly hints

  • Window class names Shell_TrayWnd / MSTaskSwWClass — fake shell chrome.
  • RegisterShellHookWindow → intercept shell events.
  • WM_DISPLAYCHANGE handler for resolution change propagation.

Evidence

  • docs/reverse-engineering/_analysis/gfndesktop.strings_filtered.txt
  • logs/startup/smithySoftwareInstall.log

LatencyTest.exe

What this program actually does

LatencyTest.exe is a Qt 4.8 GUI application (~21 MB) for measuring input/display latency. Bundled with QtCore4.dll, QtGui4.dll, QtOpenGL4.dll, msvcr100.dll, msvcp100.dll. No GFN-specific strings in filtered output — general diagnostic tool shipped with seat tools.


Architecture

Qt widget app: MainWindow / QMainWindow. GUI-only — no CLI usage strings recovered.


Windows API surface

Minimal direct Win32: GetCommandLineW, QueryPerformanceCounter, GetTickCount. Timing via QPC for latency measurement. Rest delegated to Qt4 DLLs.

PE32 GUI i386. Subsystem 2 (Windows GUI).


Pandora invocation

None in logs/startup/startup.log.


Disassembly hints

  • Qt4 MOC strings for MainWindow class.
  • OpenGL path via QtOpenGL4.dll — likely render timing measurement.
  • Entry through Qt event loop, not console main.

Evidence

  • docs/reverse-engineering/_analysis/LatencyTest.strings_filtered.txt

LaunchDataEditor.exe

What this program actually does

LaunchDataEditor.exe is a .NET CLI tool for editing LaunchData.dat — game launch persistence metadata on GFN seats. Manages save-point folders and registry snapshot locations used by the game launch pipeline. Uses protobuf-net + NVIDIA.Grid.Messages.dll for serialization.


CLI interface (NDesk.Options-style)

-a [Save point folder path]     Add save point
-d [Save point folder path]     Remove save point
-ar [Registry location] -rf [Temp reg file]   Add registry location
-dr [Temp .reg file]            Remove registry location
-l                             List entries

Types: GameLaunchInfo, protobuf serialization via NVIDIA.Grid.Messages.


Windows API surface

CLR via mscoree.dll. File I/O through .NET (OpenRead, stream APIs). No direct Win32 imports in PE table.

PE32 .NET CUI.

| r2 confirmed | _CorExeMain (mscoree.dll) |


Pandora invocation

None in logs/startup/startup.log.


Disassembly hints

  • Decompile with ILSpy — option parser maps -a/-d/-ar/-dr/-l flags.
  • Protobuf types from NVIDIA.Grid.Messages.dll — trace GameLaunchInfo serialize path.
  • LaunchData.dat binary format = protobuf blob.

Evidence

  • docs/reverse-engineering/_analysis/LaunchDataEditor.strings_filtered.txt

NVIDIA.Grid.Messages.dll

Repository path: tools/LaunchDataEditor/NVIDIA.Grid.Messages.dll
Deployed path: C:\Asgard\tools\LaunchDataEditor\NVIDIA.Grid.Messages.dll

What this program actually does

NVIDIA.Grid.Messages.dll is a .NET / CIL protobuf message library from the Grid Bifrost stack (grid\r01_50\src\Bifrost\Common\Messages). It defines wire-format types for seat↔cloud communication: game launch metadata, Platform Manager (PM) packets, session errors, display resolution, and TCP transport helpers.

Consumed by LaunchDataEditor.exe, GS2 services, and mb-repeater — not executed standalone. Serialization via protobuf-net (ProtoBuf, ProtoContract attributes in metadata).


Architecture / key types (strings + metadata)

NVIDIA.Grid.Messages
  ├─ NVIDIA.Grid.Messages.Actions.PmAction
  ├─ NVIDIA.Grid.Messages.Factories.PmPacketFactory / BifrostPacketFactory
  ├─ NVIDIA.Grid.Messages.Network
  │     ├─ ITcpSocketConnector<T>
  │     └─ TcpSocketConnector<T>
  ├─ NVIDIA.Bifrost.Messages
  │     ├─ GameLaunchInfo          — LaunchData.dat persistence
  │     ├─ BifrostPacket
  │     ├─ GameSessionErrorCode
  │     ├─ ScreenResolution / ServerResolution
  │     ├─ NetworkPerformanceCharacteristics
  │     └─ AuthenticationErrorCode / PerfClass
  └─ Factories: CreateSetupSessionPacket, CreateNotifyReadyPacket,
                CreateNotifyStatusPacket, CreateEndSessionPacket, ...

Build path: c:\nv\sw\gcomp\rel\src\grid\r01_50\src\Bifrost\Common\Messages\obj\Release\NVIDIA.Grid.Messages.pdb


External interfaces

InterfaceRole
CLR hostLoaded by LaunchDataEditor.exe, GS2 managed components
ImportSole PE import: mscoree.dll!_CorDllMain
Protobuf wireBinary serialization for MessageBus / TCP peers
TCPTcpSocketConnector for PM packet transport

No direct Win32 API — pure managed library.


PE metadata

FieldValue
SHA-2566c68398451444c0c6ca29b75e017c7228910a66190ffde8ce79bd7981c6b2ff6
Size134,656 bytes
FormatPE32 Mono/.NET assembly i386, compiled 2013-06-12
SubsystemWindows CUI
Exportsnone (managed)
Entry_CorDllMain thunk @ 0x100221ee

Notable strings (sample)

Type / stringPurpose
GameLaunchInfoGame launch persistence (LaunchData.dat)
PmPacketFactoryPlatform Manager packet factory
GameSessionErrorCodeSession error enumeration
ServerResolution / ScreenResolutionDisplay resolution messages
NotifyError, QueryStatusPM action verbs
protobuf-net / ProtoBufSerialization framework

Runtime timeline

SourceFinding
logs/startup/startup.logNo direct invocation (library only)
LaunchDataEditor.exePrimary consumer in tools/LaunchDataEditor/
GS2 / Bifrost stackMessage types referenced by seat services (indirect)

Failure modes

ConditionBehavior (managed)
Deserialization mismatchErrorOccurredEventArgs<T> pattern in type names
Invalid packetFactory methods return error packets (CreateNotifyFailedPacket)
Missing extensionIExtensible.GetExtensionObject for protobuf extensions

Relationships

ComponentInteraction
LaunchDataEditor.exeCLI tool for reading/writing LaunchData.dat
protobuf-net.dllBundled serializer dependency
mb-repeaterForwards Bifrost/Grid messages on MessageBus
GS2 / NGS stackSession and launch protocol consumers

Not verified

  • Complete protobuf field ID → message type mapping.
  • Which GS2 message IDs reference each type at runtime.
  • Version compatibility between this 2013 build and current Bifrost protocol.

Evidence

  • strings on tools/LaunchDataEditor/NVIDIA.Grid.Messages.dll
  • _analysis/NVIDIA.Grid.Messages.strings_filtered.txt

LaunchProcessAsUser.exe

What this program actually does

tools/LaunchProcessAsUser.exe is an older Release build of the OSL/Microsoft .NET console helper that launches a child process under a specified Windows user account. It shares the same project and assembly name as the deployed copy at sas2/bin/LaunchProcessAsUser.exe, but is a different binary (smaller, older, fewer methods).

Production path: sas2/bin/LaunchProcessAsUser.exe — invoked by sas2/start/startup.bat. This tools/ copy is not referenced by any script in this workspace.


Architecture / control flow

Native PE stub (_CorExeMain)
  └─ LaunchProcessAsUser.Main
        ├─ RunAs(path, username, password, args, WorkingDirectory)
        └─ MakeSecureString → ProcessStartInfo → Process.Start

This Release build lacks ExecuteCommandSync, ChangeUserPassword, and k_username/x_username/k_password/x_password strings present in the sas2 Debug build.


Windows API surface

LayerAPIs
Native stub_CorExeMain via mscoree.dll
.NET (inferred)ProcessStartInfo, Process, MakeSecureString, set_UserName, set_Password, set_UseShellExecute, set_CreateNoWindow, set_WorkingDirectory

| r2 confirmed | _CorExeMain (mscoree.dll) |


PE metadata (readpe / radare2)

FieldValue
Pathtools/LaunchProcessAsUser.exe
FormatPE32 CUI, Mono/.NET assembly
Architecturex86 (32-bit)
Size6,144 bytes
SHA-25621633bf70dc2af1fc68659e7715b5b4c1a639580abfa08b8936cefdc7e1d35c1
CompiledThu Mar 26 2015
.NET target.NET Framework 4 Client Profile
EntryNative stub → _CorExeMain
PDB...\vramadoss\...\obj\x86\Release\LaunchProcessAsUser.pdb

Deployment and references

None in this workspace. See docs/reverse-engineering/sas2/bin/LaunchProcessAsUser.md for the active deployment path.


Runtime evidence (logs)

None. Not referenced in logs/startup/startup.log or Pandora scripts.


Evidence

  • readpe, r2_analyze.sh, strings, cmp vs. sas2/bin/LaunchProcessAsUser.exe
  • docs/reverse-engineering/sas2/bin/LaunchProcessAsUser.md (deployed copy)

net132.exe

What this program actually does

net132.exe is the 64-bit variant of net164.exe — bundled Windows net.exe-style network administration utility using NetAPI32/SAM/AD APIs.


Windows API surface

Same NetAPI cluster as net164 (PE32+ x64):

  • NETAPI32.dll, SAMLIB.dll, NTDSAPI.dll, dsrole.dll, logoncli.dll
  • Additional: GetNcpSecretKey, OpenPrinterW, SetSystemTime
  • NTDLL.DLL for native API calls

Manifest version 5.1.0.0. HELP string.

| r2 confirmed | RegQueryValueExW (ADVAPI32.dll) | RegOpenKeyW (ADVAPI32.dll) | OpenSCManagerW (ADVAPI32.dll) | LoadLibraryW (KERNEL32.dll) | GetProcAddress (KERNEL32.dll) |


Pandora invocation

None in logs/startup/startup.log.


Disassembly hints

  • Compare with net164 — x64 calling conventions and expanded IAT.
  • SetSystemTime import suggests net time subcommand support.

Evidence

  • docs/reverse-engineering/_analysis/net132.strings_filtered.txt

net164.exe

What this program actually does

net164.exe is a 32-bit bundled net.exe-style Windows network administration utility. Provides NetAPI32 commands for user/service/share management — same surface as Windows net CLI.

Shipped for seat scripts that need network admin without relying on system net.exe path.


Windows API surface

DLLRole
NETAPI32.dllNetUserAdd/Del/Enum, NetServiceEnum/Control/Install, NetShare*
SAMLIB.dllSAM database access
NTDSAPI.dllAD directory services
dsrole.dllDomain role queries
logoncli.dllLogon CLI
ADVAPI32OpenSCManagerW, OpenServiceW, GetServiceDisplayNameW

PE32 CUI. Manifest version 5.1.0.0. HELP string present.

| r2 confirmed | RegQueryValueExW (ADVAPI32.dll) | RegOpenKeyW (ADVAPI32.dll) | OpenSCManagerW (ADVAPI32.dll) | GetProcAddress (KERNEL32.dll) | LoadLibraryW (KERNEL32.dll) |


Pandora invocation

None in logs/startup/startup.log. Available for seat automation scripts.


Disassembly hints

  • NetAPI import table mirrors Windows net.exe — compare IAT with system copy.
  • RtlNtStatusToDosError for NTSTATUS→Win32 error mapping.

Evidence

  • docs/reverse-engineering/_analysis/net164.strings_filtered.txt

Noop.exe (tools/)

What this program actually does

tools/Noop.exe is a minimal .NET 4.0 GUI stub from Bifrost/GameAgent that exits immediately. Used to replace or disable shell helpers where a valid executable path is required but no work should be done.

Distinct from:

  • tools/Smithy/NoOp.exe — native 121 KB OpenWith replacement stub
  • services/SmithyV2/Noop/NoOp.exe — native 21 KB V2 placeholder

Behavior

CLR application with no meaningful logic. Deep extract mentions GetProcessesByName (likely template/stub code). PE32 .NET GUI, mscoree.dll only import.


Windows API surface

CLR via mscoree.dll_CorExeMain. No direct Win32 imports.

| r2 confirmed | _CorExeMain (mscoree.dll) |


Pandora invocation

None directly. Smithy V1 copies its own NoOp variant, not this binary.


Disassembly hints

  • Decompile with ILSpy — likely empty Main() or immediate return.
  • Do not confuse with Smithy NoOp paths in RE docs.

Evidence

  • docs/reverse-engineering/_analysis/Noop.strings_filtered.txt

NvFBCEnable.exe

What this program actually does

NvFBCEnable.exe enables, disables, or checks NVIDIA Frame Buffer Capture (NvFBC) support by writing registry keys under SOFTWARE\NVIDIA Corporation\NvFBCEnable and invoking NVAPI (nvapi.dll dynamic load). Required for cloud seat screen capture pipeline.

Deployed: C:\Asgard\tools\nvfbcenable.exe. PE32 CUI i386 (2014).


CLI interface

NvFBCEnable <option>
  -enable      Enable NvFBC support
  -disable     Disable NvFBC support
  -checkstatus Check if enabled
  -noreset     No video device reset (reboot required)

Output strings: NvFBC is enabled / NvFBC is disabled.


Windows API surface

CategoryAPIs
RegistryADVAPI32 registry writes under NvFBCEnable + nvlddmkm service keys
NVAPIDynamic nvapi_QueryInterface via nvapi.dll
Event logOpenEventLogA

| r2 confirmed | LoadLibraryA (KERNEL32.dll) | GetProcAddress (KERNEL32.dll) | CreateFileA (KERNEL32.dll) | RegQueryInfoKeyA (ADVAPI32.dll) |


Pandora invocation

StepCommandResult
enable_nvfbcC:\Asgard\tools\nvfbcenable.exe -enablerc=0, out=NvFBC is enabled

logs/startup/startup.log 18:42:44–45 UTC.


Disassembly hints

  • Entry 0x26d2; ADVAPI32 + dynamic NVAPI load pattern.
  • Registry path strings near enable/disable branches.
  • -noreset flag skips display driver reset IOCTL path.

Evidence

  • docs/reverse-engineering/_analysis/NvFBCEnable.strings_filtered.txt
  • logs/startup/startup.log

nvDisplayRes.exe

What this program actually does

nvDisplayRes.exe sets display resolution and mode on NVIDIA cloud GPU seats, combining GDI enumeration (EnumDisplayDevices, EnumDisplaySettings) with NVAPI custom resolution APIs. Used by Pandora to force native seat resolution before session start.

Source path string: //sw/apps/gpu/drivers/common/nvDisplayRes/


CLI interface

Boost program_options parsing:

FlagBehavior
--x, --yTarget resolution (Pandora: 1920×1080)
--help, --versionUsage / version
--all, --singleMulti/single display scope
displayLess, multiDisplay, nvapi-allDisplaysMode keywords

Internal action string: doChangeres W H bpp Hz (observed: doChangeres 1920 1080 32 60).

Custom exports: SetDisplayLessMode, SetCustomResolutionVgx, SetEdid.


Windows API surface

CategoryAPIs
GDIEnumDisplayDevices, EnumDisplayMonitors, EnumDisplaySettingsA
DesktopOpenInputDesktop, CreateProcessAsUserW
NVAPIDynamic load for VGX custom resolution

PE32 CUI (2015), 6 DLL exports, ASLR enabled.

| r2 confirmed | RegQueryValueExA (ADVAPI32.dll) | RegSetKeyValueA (ADVAPI32.dll) | EnumDisplayMonitors (USER32.dll) | EnumDisplayDevicesA (USER32.dll) | EnumDisplaySettingsA (USER32.dll) | LoadLibraryW (KERNEL32.dll) |


Pandora invocation

StepCommandResult
set_native_resolutionc:\asgard\tools\nvDisplayRes.exe --x 1920 --y 1080rc=0, out=doChangeres 1920 1080 32 60

logs/startup/startup.log 18:42:46 UTC.


Disassembly hints

  • Boost options table near --x/--y string refs.
  • doChangeres format string → central resolution change routine.
  • Export SetCustomResolutionVgx for VGX-specific NVAPI path.

Evidence

  • docs/reverse-engineering/_analysis/nvDisplayRes.strings_filtered.txt
  • logs/startup/startup.log

NvKeyBoardLayoutSetup.exe

What this program actually does

NvKeyBoardLayoutSetup.exe (~4.4 MB) is a 7-Zip SFX installer for NVIDIA custom keyboard layout DLLs (Nimbus.KeyboardLayouts). Same SFX engine pattern as NvTensorRTSetup.exe.

Verified invocation in nvkblayout_install_verify.bat:

-s -n -ignorepnp -loglevel:9 -log:C:\asgard\logs\nvkblayout

Behavior

  • CSfxExtractEngine / CSfxDialog_* 7-Zip SFX
  • NVIDIA RegistryKey logging framework
  • Extracts keyboard layout payload to system directories

Windows API surface

Same SFX pattern: CreateWindowExW, CreateThread, CreateFileW, COMCTL32, SHLWAPI, SHELL32, ADVAPI32.

PE32 GUI i386.

| r2 confirmed | GetProcAddress (KERNEL32.dll) | LoadLibraryA (KERNEL32.dll) | CreateFileW (KERNEL32.dll) |


Pandora invocation

None in logs/startup/startup.log. Invoked via install verify batch script.


Disassembly hints

  • SFX config in resources — compare with NvTensorRTSetup structure.
  • -ignorepnp flag skips PnP device restart path.
  • Log path -log:C:\asgard\logs\nvkblayout → PDK logging init.

Evidence

  • docs/reverse-engineering/_analysis/NvKeyBoardLayoutSetup.strings_filtered.txt

perfdebug.exe

What this program actually does

perfdebug.exe (~11 MB) is NVIDIA RM perfdebug — GPU p-state/clock/perf debugging via NVAPI. Command-tree architecture for clock domain operations, perf limit queries, and driver state inspection.

Source: drivers/resman/board_solutions/perfdebug/src/perfdebug.cpp

Used by support/engineering for GPU perf diagnosis; not in Pandora bootstrap path.


Architecture

CommandRoot
  └─ Command (clock domain ops)
        ├─ GT_ClkDomainOc (overclock domains)
        └─ NVAPI perf interfaces

Google Test framework embedded (unit test RTTI). External wiki/Confluence docs referenced in strings.


Windows API surface

CategoryAPIs
NVAPInvapi_QueryInterface, nvapi_pepQueryInterface
ProcessCreateProcessA, OpenProcess, CreateThread
SCMOpenSCManagerW, OpenServiceW

PE32+ CUI x64.

Error strings: Failed to initialize NVAPIs, _perfdebugPreParseParams Failed.

| r2 confirmed | GetProcAddress (KERNEL32.dll) | CreateProcessA (KERNEL32.dll) | CreateFileW (KERNEL32.dll) | LoadLibraryExW (KERNEL32.dll) |


Pandora invocation

None in logs/startup/startup.log. Sysmon allowlist entry only.


Disassembly hints

  • Command tree registration in CommandRoot constructor.
  • NVAPI init failure path near Failed to initialize NVAPIs.
  • Clock domain RTTI (GT_ClkDomainOc) → domain-specific NVAPI calls.

Evidence

  • docs/reverse-engineering/_analysis/perfdebug.strings_filtered.txt

RebootHelper.exe

What this program actually does

RebootHelper.exe is a small GUI helper that prompts for post-change system restart. Creates a dialog with a "Restart Now" button and runs a standard Win32 message pump. Used when seat configuration changes require reboot confirmation.


Behavior

  • CreateWindowExA, RegisterClassExA — dialog window
  • SetTimer — likely countdown or auto-dismiss
  • GetMessageA / TranslateAcceleratorA — message loop
  • LoadAcceleratorsA — keyboard shortcuts

Windows API surface

DLLAPIs
USER32.dllWindow creation, message pump, timer, accelerators
KERNEL32.dllProcess APIs

PE32 GUI i386. Subsystem 2.

| r2 confirmed | LoadLibraryW (KERNEL32.dll) | GetProcAddress (KERNEL32.dll) |


Pandora invocation

None in logs/startup/startup.log.


Disassembly hints

  • Dialog template in resources — "Restart Now" button ID.
  • SetTimer callback likely triggers ExitWindowsEx or InitiateSystemShutdownEx.

Evidence

  • docs/reverse-engineering/_analysis/RebootHelper.strings_filtered.txt

SASPMConnectorExe.exe

What this program actually does

SASPMConnectorExe.exe (~13 MB) is the SAS Seat Agent ↔ Platform Manager connector. Long-running service/connector using gRPC, Bifrost protobuf messaging, and seat scheduler integration. Handles QuerySeatStatus, ProcessSchedulerServicesMessage, and related PM↔seat protocol.

Not invoked by Pandora directly — started by SAS2 seat services post-install.


Architecture (RTTI)

1100+ C++ types including:

  • NVIDIA.Bifrost.Messages.*
  • gRPC / event-engine stack
  • log4cpp logging
  • SchedulerServices, QuerySeatStatus

Windows API surface

CategoryAPIs
NetworkWS2_32, gRPC TCP
CryptoCRYPT32, bcrypt
Debugdbghelp, CreateMiniDump, CreateToolhelp32Snapshot

PE32+ CUI x64.

| r2 confirmed | GetProcAddress (KERNEL32.dll) | CreateFileA (KERNEL32.dll) |


Pandora invocation

None in logs/startup/startup.log.


Disassembly hints

  • gRPC service registration strings → method dispatch table.
  • Bifrost message factory (PmPacketFactory pattern in related DLLs).
  • MiniDump path for crash telemetry.

Evidence

  • docs/reverse-engineering/_analysis/SASPMConnectorExe.strings_filtered.txt

NvTensorRTSetup.exe

What this program actually does

NvTensorRTSetup.exe is a ~584 MB NVIDIA 7-Zip SFX self-extractor for the TensorRT runtime stack. Embeds CSfxExtractEngine, extracts bundled setup.exe and payload to disk, with NVIDIA logging/registry framework.

Shipped with seat tools for ML inference runtime installation (not invoked during Pandora bootstrap in captured snapshot).


Behavior

7-Zip SFX pattern:

  • CSfxExtractEngine, CSfxDialog_* RTTI classes
  • Embedded setup.exe child process
  • LZMA decoder stack
  • HelpText, -overwrite extraction behavior
  • Wow64DisableWow64FsRedirection for x64 payload on WoW64

Windows API surface

CategoryAPIs
UICreateWindowExW, CreateThread, COMCTL32
FilesystemCreateFileW, SHLWAPI, SHELL32
RegistryRegistryKey logging framework (NVIDIA PDK)
WOW64Wow64DisableWow64FsRedirection

PE32 GUI i386. Large resource section.

| r2 confirmed | GetProcAddress (KERNEL32.dll) | LoadLibraryA (KERNEL32.dll) | CreateFileW (KERNEL32.dll) |


Pandora invocation

None in logs/startup/startup.log.


Disassembly hints

  • SFX config block in resource section drives extraction path.
  • CSfxExtractEngine vtable → LZMA decode → file write loop.
  • Child setup.exe spawn after extraction completes.

Evidence

  • docs/reverse-engineering/_analysis/NvTensorRTSetup.strings_filtered.txt
  • docs/reverse-engineering/_analysis/NvTensorRTSetup.objdump_filtered.txt

WinKill.exe

What this program actually does

WinKill.exe is a legacy MFC tray application (2009, WinKillApp/WinKillDialog) that enforces kiosk lockdown on GFN seats. It loads WinKillHook.dll and installs a global low-level hook (SetWindowsHookExW) to block or kill disallowed UI (Alt+Tab, Windows key, etc.). Runs in system tray with display enumeration for multi-monitor awareness.


Architecture

WinKill.exe (MFC GUI, subsystem 2)
  └─ LoadLibrary(WinKillHook.dll)
  └─ SetWindowsHookExW → keyboard_proc in hook DLL
  └─ Shell_NotifyIcon (tray icon)
  └─ EnumDisplayDevicesW / EnumDisplayMonitors
  └─ GetForegroundWindow / GetWindowTextW (window filtering)

First import in objdump: WinKillHook.dll.


Windows API surface

CategoryAPIs
HooksSetWindowsHookExW (via WinKillHook.dll exports)
ShellShell_NotifyIcon, CreatePopupMenu, TrackPopupMenu
DisplayEnumDisplayDevicesW, EnumDisplayMonitors
WindowGetForegroundWindow, GetWindowTextW, HtmlHelpW
AccessibilityOLEACC imports

| r2 confirmed | CreateFileA (KERNEL32.dll) |


Pandora invocation

StepActionResult
start_winkilltasklist … findstr winkillrc=1 (not running)
start_winkillLaunch WinKillpid 4300
start_winkillnet start WlanSvcrc=2 (service absent or already running)

logs/startup/startup.log 18:42:45 UTC. Step in initial ready queue alongside enable_nvfbc.


Disassembly hints

  • MFC resource manifest + entry 0xe2a1.
  • Hook install immediately after WinKillHook.dll load — trace winkill_install_hook export.
  • Tray icon path via Shell_NotifyIcon + message pump.

Evidence

  • docs/reverse-engineering/_analysis/WinKill.strings_filtered.txt
  • logs/startup/startup.log

WinKillHook.dll

Repository path: tools/WinKillHook.dll
Deployed path: C:\Asgard\tools\WinKillHook.dll

What this program actually does

WinKillHook.dll is the low-level keyboard hook DLL loaded by WinKill.exe on GFN kiosk seats. It installs a WH_KEYBOARD_LL (hook id 13) global low-level keyboard hook and swallows Windows logo keys (VK_LWIN 0x5B, VK_RWIN 0x5C) to prevent users from breaking out of the kiosk shell (Start menu, Win+Tab, etc.).

Legacy build from 2009 — PE32 GUI subsystem, no ASLR (pic=false), no stack canary.


Exported API

ExportSignaturePurpose
keyboard_proclong __stdcall (int nCode, uint wParam, long lParam)Hook callback — filters keys
winkill_install_hookbool __cdecl (HWND*)Install hook via SetWindowsHookExW
winkill_remove_hookbool __cdecl (void)Remove hook via UnhookWindowsHookEx

Architecture / control flow (radare2 recovered)

winkill_install_hook(HWND* hwnd)
  ├─ Guard: skip if hook already installed (global @ 0x1000ace0)
  ├─ SetWindowsHookExW(WH_KEYBOARD_LL=13, keyboard_proc, hMod, 0)
  └─ Store hook handle + target HWND (@ 0x1000ace4)

keyboard_proc(nCode, wParam, lParam)
  ├─ if nCode != 0 (not HC_ACTION) → CallNextHookEx
  ├─ switch(wParam): WM_KEYDOWN family (256–261)
  │     └─ Read VK from KBDLLHOOKSTRUCT.vkCode
  │           if VK == 0x5B or 0x5C → return 1 (swallow)
  └─ default → CallNextHookEx

Hook type confirmed: push 0xd (13 = WH_KEYBOARD_LL) in winkill_install_hook @ 0x1000107d.

Blocked keys: VK_LWIN (0x5B) and VK_RWIN (0x5C) only — other kiosk keys (Alt+Tab, Escape) are not filtered in this DLL (may be handled by WinKill.exe itself).


Windows API surface

DLLAPIRole
USER32.dllSetWindowsHookExWInstall LL keyboard hook
USER32.dllUnhookWindowsHookExRemove hook
USER32.dllCallNextHookExChain unfiltered keys
KERNEL32.dllGetVersionExAOS version check at init
KERNEL32.dllHeap/CRTLegacy MSVC runtime

| r2 confirmed | SetWindowsHookExW (USER32.dll) | GetProcAddress (KERNEL32.dll) | LoadLibraryA (KERNEL32.dll) |


PE metadata

FieldValue
SHA-256b9a29d11152ac5174f60b0074dc2af0e151cf13a1739c45b393d5cc4252eb9bc
Size53,248 bytes
FormatPE32 DLL i386, compiled 2009-03-26
SubsystemWindows GUI (legacy artifact)
NXdisabled
Exports3

Runtime timeline (from logs/startup/startup.log)

Time (local)Event
18:42:45.247Pandora start_winkill step begins
18:42:45.275WinKill.exe launched — PID 4300
18:42:45.441Step completes; WlanSvc start attempted (rc=2, tolerated)

Pandora: Indirect — WinKill.exe loads this DLL at runtime; Pandora only starts the parent process.


Failure modes

ConditionBehavior
SetWindowsHookExW failswinkill_install_hook returns false
Hook already installedEarly return without re-installing
NULL HWND passedInstall skipped (test ecx, ecx @ 0x1000106f)

Relationships

ComponentInteraction
WinKill.exeParent process; calls install/remove exports
Pandora start_winkillBoot step launches WinKill
Kiosk stackComplements gfndesktop, shell restrictions

Not verified

  • Whether winkill_remove_hook is called on WinKill exit or only on uninstall.
  • Additional key filtering in WinKill.exe (outside this DLL).
  • Behavior on Windows 10/11 with hardened hook policies.

Evidence

  • Radare2 disassembly of keyboard_proc and winkill_install_hook
  • _analysis/WinKillHook.strings_filtered.txt
  • logs/startup/startup.log (start_winkill, PID 4300)

xenstore_client.exe

What this program actually does

xenstore_client.exe is a CLI accessor for the Citrix/Xen XenStore key-value store on Xen-hypervised seats. Reads/writes/lists/removes hypervisor configuration keys (hostname, feature flags, etc.).

Used by tools/setHostname.py: xenstore_client read name.

Depends on xs.dll (Citrix XenStore client library).


CLI interface

xenstore_client read {path}
xenstore_client write {path} {data}
xenstore_client dir {path}
xenstore_client remove {path}

Error: cannot open xenstore interface


Windows API surface

DLLRole
xs.dllXenStore protocol (12 exports)
KERNEL32.dllGetModuleHandleA, process APIs
msvcrt.dllC runtime

PE32 CUI (2012). Explicit import of xs.dll. Entry 0x18bc.

xs.dll: Registry key SOFTWARE\Citrix\XenTools. Exports ordinal base 1.

| r2 confirmed | FormatMessageA (KERNEL32.dll) | GetLastError (KERNEL32.dll) | UnhandledExceptionFilter (KERNEL32.dll) | GetCurrentProcess (KERNEL32.dll) | TerminateProcess (KERNEL32.dll) | GetSystemTimeAsFileTime (KERNEL32.dll) |


Pandora invocation

None in logs/startup/startup.log.


Disassembly hints

  • Command dispatch table keyed on read/write/dir/remove strings.
  • Failure path: cannot open xenstore interface → xs.dll init failure.
  • xs.dll: 12 exports — map to XenStore wire protocol.

Evidence

  • docs/reverse-engineering/_analysis/xenstore_client.strings_filtered.txt
  • docs/reverse-engineering/_analysis/xs.strings_filtered.txt

xs.dll

Repository path: tools/xs.dll
Deployed path: C:\Asgard\tools\xs.dll

What this program actually does

xs.dll is the Citrix/Xen XenStore userspace client library (2012). It implements the wire protocol to the XenStore daemon for reading, writing, listing, watching, and transactional updates of hypervisor configuration keys (hostname, feature flags, VM metadata).

Loaded by xenstore_client.exe, which exposes CLI commands (read, write, dir, remove). Used on Xen-hypervised GFN seats — e.g. tools/setHostname.py runs xenstore_client read name.

Registry integration reads SOFTWARE\Citrix\XenTools for XenTools configuration.


Exported API (12 functions)

ExportPurpose
xs_domain_openOpen XenStore connection
xs_daemon_closeClose daemon connection
xs_readRead key value
xs_writeWrite string value
xs_write_binWrite binary value
xs_removeDelete key
xs_directoryList directory children
xs_watchRegister watch on key
xs_unwatchCancel watch
xs_transaction_startBegin transaction
xs_transaction_endCommit/abort transaction
xs_freeFree XenStore-allocated buffer

Architecture / control flow

xs_domain_open
  ├─ CreateMutexA (singleton connection guard)
  ├─ RegOpenKeyExA("SOFTWARE\Citrix\XenTools") via ADVAPI32
  ├─ Dynamic LoadLibrary + GetProcAddress (daemon interface)
  └─ Return xs_handle

xs_read / xs_write / xs_directory / ...
  └─ Mutex-protected RPC to xenstored

xenstore_client.exe CLI
  └─ Dispatches argv[1] verb → xs_* export

Build path: c:\remote-ops-tmp\rops8vffrf\windows\build\i386\xs.pdb


Windows API surface

DLLAPIs
KERNEL32.dllCreateMutexA, WaitForSingleObject, ReleaseMutex, CloseHandle, LoadLibraryA, GetProcAddress
ADVAPI32.dllRegOpenKeyExA, RegQueryValueExA, RegCloseKey
msvcrt.dllmalloc, free, calloc, memcpy, CRT init

| r2 confirmed | LoadLibraryA (KERNEL32.dll) | GetProcAddress (KERNEL32.dll) | RegQueryValueExA (ADVAPI32.dll) | RegOpenKeyExA (ADVAPI32.dll) |


PE metadata

FieldValue
SHA-25663ab7648939e92f688e13dda17d7e5f712b1a5da39e5d4fa6aacd12dba385e0d
Size11,776 bytes
FormatPE32 DLL i386, compiled 2012-02-10
SubsystemWindows GUI (Citrix legacy)
Exports12 (ordinal base 1)

Runtime timeline

SourceFinding
logs/startup/startup.logNot invoked at Pandora boot
tools/setHostname.pysubprocess.Popen('.\xenstore_client.exe read name')
xenstore_client.exeImports all 12 xs_* exports explicitly

Failure string (xenstore_client): cannot open xenstore interfacexs_domain_open failure.


Failure modes

ConditionBehavior
XenStore daemon unreachablexs_domain_open fails; CLI prints error
Mutex contentionWaitForSingleObject blocks concurrent access
Missing Citrix XenTools registryRegOpenKeyExA failure path
Invalid key pathXenStore protocol error returned to caller

Relationships

ComponentInteraction
xenstore_client.exeSole direct consumer in Asgard tree
setHostname.pyReads VM hostname via xenstore
Citrix XenToolsRegistry config source
Hypervisor (Xen)xenstored daemon on host/dom0

Not verified

  • Exact XenStore socket/path used on GFN seats (vs. Citrix defaults).
  • Watch callback delivery mechanism (async thread vs. poll).
  • Whether xs.dll is loaded by any process other than xenstore_client.exe.

Evidence

  • Radare2 exports + imports on tools/xs.dll
  • tools/setHostname.py

Noop.exe (IETemp/32)

What this program actually does

IETemp/32/Noop.exe is a minimal NVIDIA-signed native stub (Smithy/NoOp) that immediately exits. Smithy copies it from tools/Smithy/Smithy/Noop.exe into IETemp/ during seat provisioning, then overwrites C:\Windows\SysWOW64\OpenWith.exe with this binary to disable the Windows "Open with" dialog on the kiosk shell.

Despite the 32/ directory name, the binary is PE32+ (x86-64) — byte-identical to IETemp/64/Noop.exe and tools/Smithy/Smithy/Noop.exe. Directory naming reflects the Windows overwrite target bitness, not PE architecture.


Architecture / control flow

Smithy DesktopModule
  ├─ Backup tools\Smithy\Smithy\Noop.exe → IETemp\32\Noop.exe
  └─ takeown/icacls C:\Windows\SysWOW64\OpenWith.exe
        └─ copy IETemp\32\Noop.exe → SysWOW64\OpenWith.exe
              └─ CRT init → ExitProcess(0)

No command-line parsing, no window creation, no file I/O beyond PE loader.


Windows API surface

CategoryAPIs
Process exitExitProcess, TerminateProcess
CRT startupStandard MSVC 14.35 init (GetStartupInfoW, heap, TLS)
ConsoleGetStdHandle, WriteFile, WriteConsoleW (unused in normal path)

Only KERNEL32.dll imported. No USER32, SHELL32, or networking.


PE metadata (readpe / radare2)

FieldValue
PathIETemp/32/Noop.exe
FormatPE32+ console x86-64
Size121,456 bytes
SHA-25627b5fbbf36d763a9cb45d40ca6fddeafe3abc1ddf35611eedf2334fd37ae41bc
CompiledTue May 5 01:29:39 2026
LinkerMSVC 14.35
Entry0x140001264main @ 0x140001000 (3 bytes)
SignedYes (NVIDIA Corporation)

Deployment and references

ItemEvidence
Sourcetools/Smithy/Smithy/Noop.exe (identical SHA-256)
StagingSmithy backs up to C:\Asgard\IETemp\32\Noop.exe
Overwrite targetC:\Windows\SysWOW64\OpenWith.exe
Original backupIETemp/32/openwith.exe (separate Microsoft binary)

Runtime timeline

Time (UTC)EventSource
18:43:09.269Backing up ...Noop.exe to C:\Asgard\IETemp\32\Noop.exelogs/startup/smithySoftwareInstall.log
18:43:10.054Overwriting C:\Windows\SysWOW64\OpenWith.exe from C:\Asgard\IETemp\32\Noop.exeSmithy log
18:43:10.071icacls grant xen:F on SysWOW64 OpenWith — rc=0Smithy log

Not verified

  • Exact exit code (typically 0 for minimal stubs).
  • Why an x64 PE is used for both 32/ and 64/ IETemp paths (WoW64 OpenWith accepts x64 replacement on 64-bit Windows).

Evidence

  • readpe, r2_analyze.sh, cmp vs. IETemp/64/Noop.exe
  • logs/startup/smithySoftwareInstall.log, logs/GSP/Smithy/Smithy.log

explorer.exe (IETemp/32)

What this program actually does

IETemp/32/explorer.exe is not an NVIDIA stub — it is a full Microsoft Windows Explorer binary (PE32, 32-bit) preserved as a rollback backup before Smithy replaces live explorer.exe with tools/gfndesktop/gfndesktop.exe for GFN kiosk desktop lockdown.

The IETemp/ tree stores original Windows shell binaries; this file is the WoW64-relevant (32-bit) explorer backup. Smithy skips re-backup if already present.


Architecture / control flow

Smithy provisioning
  ├─ Skip if IETemp\32\explorer.exe already exists (backup preserved)
  └─ Overwrite live explorer with gfndesktop.exe (not this file)
        ├─ C:\Windows\explorer.exe ← gfndesktop.exe
        └─ C:\Windows\SysWOW64\explorer.exe ← gfndesktop.exe

This backup is not deployed at runtime — it exists for potential restore/deprovision.


Windows API surface

Extensive Windows shell stack (100+ import DLLs):

CategoryDLLs
ShellSHELL32, SHLWAPI, SHCORE
UIUSER32, GDI32, UxTheme, dwmapi
COM/OLEOLEAUT32, PROPSYS
CoreKERNEL32, ntdll, api-ms-win-* forwarders
PlatformAEPIC, TWINAPI, dxgi

Export: g_trayTriageBlock (Explorer-specific diagnostic hook).


PE metadata (readpe / radare2)

FieldValue
PathIETemp/32/explorer.exe
FormatPE32 GUI, Intel 80386
Size4,990,552 bytes (~4.76 MiB)
SHA-256987ced27192b4c1bb5a6fc50732b054161af29e4e9db8d02885d060b971469d0
TimestampReproducible-build hash (2096f0c1)
OSWindows 10+ (MajorSubsystemVersion=10)
Entry0x00536440
SignedYes (Microsoft)
PDBexplorer.pdb

Notable strings

  • pcshell\shell\explorer\trayanimations.cpp, startmnu.cpp, shellexperiencehelpers.cpp
  • ExplorerBoot, immersiveShellHangEncountered
  • No NVIDIA/custom branding

Deployment and references

ItemEvidence
Role32-bit backup of stock explorer
SmithySkipping C:\Asgard\IETemp\32\explorer.exe since already backed up
Live replacementgfndesktop.exe overwrites live explorer (not this backup)
Restore scripttools/gfndesktop/enabledefaultexplorer.bat starts C:\Windows\explorer.exe

Runtime timeline

Time (UTC)EventSource
18:43:09.269Skip backup — already presentsmithySoftwareInstall.log
18:43:09.516+Overwrite live explorer with gfndesktop (permission retry with takeown)Smithy log

Not verified

  • Exact Windows 10/11 build of this explorer image (reproducible-build timestamp obscures compile date).
  • Automated restore from IETemp/32/explorer.exe on deprovision.

Evidence

  • readpe, r2_analyze.sh, strings, objdump -p
  • logs/startup/smithySoftwareInstall.log, logs/GSP/Smithy/Smithy.log

openwith.exe (IETemp/32)

What this program actually does

IETemp/32/openwith.exe is not an NVIDIA placeholder — it is a Microsoft Windows OpenWith.exe backup (PE32, 32-bit) stored under IETemp/ so Smithy can preserve the original before replacing live C:\Windows\SysWOW64\OpenWith.exe with Noop.exe.

At ~118 KiB with Microsoft shell strings and Authenticode metadata, this is the original system binary. The active stub deployed at runtime is IETemp/32/Noop.exe, not this file.


Architecture / control flow

Smithy provisioning
  ├─ Skip if IETemp\32\OpenWith.exe already backed up
  ├─ Preserve this file (original OpenWith backup)
  └─ Overwrite SysWOW64\OpenWith.exe ← IETemp\32\Noop.exe (stub)

User attempting "Open with" on the kiosk gets the Noop stub → immediate exit, no dialog.


Windows API surface

CategoryDLLs
ShellSHELL32 (execute item / open-with UI)
UIUSER32
CoreKERNEL32, api-ms-win-core-, api-ms-win-shcore-

Source paths in strings: shell\ext\openwith\openwith.cpp


PE metadata (readpe / radare2)

FieldValue
PathIETemp/32/openwith.exe
FormatPE32 GUI, Intel 80386
Size121,000 bytes (~118 KiB)
SHA-256ce0576515d7289f01e742353e8220be710f85071fa25270c3171dc5431687e31
TimestampReproducible-build hash
OSWindows 10+
SignedYes (Microsoft Windows Production PCA 2011)

Manifest: name="Microsoft.OpenWith.PROGRAM", <description>OpenWith</description>


Deployment and references

ItemEvidence
RoleBackup of original 32-bit OpenWith
SmithySkipping C:\Asgard\IETemp\32\OpenWith.exe since already backed up
Live replacementOverwriting C:\Windows\SysWOW64\OpenWith.exe from IETemp\32\Noop.exe
Active stubIETemp/32/Noop.exe

Runtime timeline

Time (UTC)EventSource
18:43:09.269Skip OpenWith backup — already presentsmithySoftwareInstall.log
18:43:10.054Overwrite SysWOW64 OpenWith with Noop stubSmithy log

Not verified

  • Automated restore from this backup on Smithy uninstall/deprovision.
  • Exact Windows build of backed-up OpenWith.

Evidence

  • readpe, r2_analyze.sh, strings
  • logs/startup/smithySoftwareInstall.log

Noop.exe (IETemp/64)

What this program actually does

IETemp/64/Noop.exe is a minimal NVIDIA-signed native stub (Smithy/NoOp) that immediately exits. Smithy stages it from tools/Smithy/Smithy/Noop.exe and uses it to replace C:\Windows\system32\OpenWith.exe (64-bit path), disabling the Windows "Open with" handler on the GFN kiosk shell.

Byte-identical to IETemp/32/Noop.exe and tools/Smithy/Smithy/Noop.exe (SHA-256 27b5fbbf…).


Architecture / control flow

Smithy DesktopModule
  ├─ Backup tools\Smithy\Smithy\Noop.exe → IETemp\64\Noop.exe
  └─ takeown/icacls C:\Windows\system32\OpenWith.exe
        └─ copy IETemp\64\Noop.exe → system32\OpenWith.exe
              └─ CRT init → ExitProcess(0)

Windows API surface

CategoryAPIs
Process exitExitProcess
CRTMSVC 14.35 startup (KERNEL32 only)

No USER32, SHELL32, or file operations beyond PE load.


PE metadata (readpe / radare2)

FieldValue
PathIETemp/64/Noop.exe
FormatPE32+ console x86-64
Size121,456 bytes
SHA-25627b5fbbf36d763a9cb45d40ca6fddeafe3abc1ddf35611eedf2334fd37ae41bc
CompiledTue May 5 01:29:39 2026
Entry0x140001264
SignedYes (NVIDIA Corporation)

Deployment and references

ItemEvidence
StagingBacking up ...Noop.exe to C:\Asgard\IETemp\64\Noop.exe
OverwriteC:\Windows\system32\OpenWith.exeIETemp\64\Noop.exe
Original backupIETemp/64/openwith.exe (Microsoft OpenWith, separate file)

Runtime timeline

Time (UTC)EventSource
18:43:09.270Backup Noop.exe to IETemp\64smithySoftwareInstall.log
18:43:09.496Overwriting C:\Windows\system32\OpenWith.exe from C:\Asgard\IETemp\64\Noop.exeSmithy log
18:43:09.514icacls on system32 OpenWith — rc=0Smithy log

Evidence

  • readpe, r2_analyze.sh, cmp identical to IETemp/32/Noop.exe
  • logs/startup/smithySoftwareInstall.log

explorer.exe (IETemp/64)

What this program actually does

IETemp/64/explorer.exe is not an NVIDIA stub — it is a full Microsoft Windows Explorer binary (PE32+, 64-bit) kept as a backup of the original system shell before Smithy replaces live C:\Windows\explorer.exe with tools/gfndesktop/gfndesktop.exe.

At ~5.3 MiB with extensive shell imports and Microsoft source-path strings, this is a complete Windows component stored for rollback, not deployed at runtime.


Architecture / control flow

Smithy provisioning
  ├─ Skip if IETemp\64\explorer.exe already exists
  └─ Overwrite C:\Windows\explorer.exe ← gfndesktop.exe
        (IETemp\64\explorer.exe remains as backup)

Windows API surface

CategoryDLLs
ShellSHELL32, SHLWAPI, SHCORE
UIUSER32, GDI32, UxTheme, dwmapi
SessionWTSAPI32, PROPSYS
NetworkWININET
CoreKERNEL32, ntdll, RPCRT4, api-ms-win-*

PE metadata (readpe / radare2)

FieldValue
PathIETemp/64/explorer.exe
FormatPE32+ GUI x86-64
Size5,596,280 bytes (~5.34 MiB)
SHA-2566981ccee742819613d24e0b7b53ba58112ed62240d76585ef41dec2d0bf5a3ce
TimestampReproducible-build hash
OSWindows 10+
SignedYes (Microsoft)

Notable strings

  • Spcshell\shell\explorer\tray.cpp, initcab.cpp, trayshowdesktop.cpp
  • WaitOnShellStartup, WaitForImmersiveShell, ExplorerBoot
  • TerminateShellApplications
  • No NVIDIA identifiers

Deployment and references

ItemEvidence
Role64-bit backup of stock explorer
SmithySkipping C:\Asgard\IETemp\64\explorer.exe since already backed up
Live swapOverwriting C:\Windows\explorer.exe from gfndesktop.exe
Restoretools/gfndesktop/enabledefaultexplorerkiosk.bat

Runtime timeline

Time (UTC)EventSource
18:43:09.268Skip backup — already presentsmithySoftwareInstall.log
18:43:09.536First explorer overwrite attempt — Permission denied, retried with takeownSmithy log

Relationships

ComponentRelationship
IETemp/32/explorer.exe32-bit counterpart — different SHA-256
gfndesktop.exeKiosk shell substituted for live explorer
SmithyOrchestrates backup/skip/overwrite

Evidence

  • readpe, r2_analyze.sh, strings
  • logs/startup/smithySoftwareInstall.log

openwith.exe (IETemp/64)

What this program actually does

IETemp/64/openwith.exe is not an NVIDIA placeholder — it is a Microsoft Windows OpenWith.exe backup (PE32+, 64-bit) preserved under IETemp/ before Smithy replaces live C:\Windows\system32\OpenWith.exe with the Noop.exe stub.

The active runtime replacement is IETemp/64/Noop.exe; this file is the original system binary kept for rollback.


Architecture / control flow

Smithy provisioning
  ├─ Skip if IETemp\64\OpenWith.exe already backed up
  ├─ Preserve this file (original 64-bit OpenWith)
  └─ Overwrite system32\OpenWith.exe ← IETemp\64\Noop.exe

Windows API surface

CategoryDLLs
ShellSHELL32 (open-with dialog / execute item)
UIUSER32
CoreKERNEL32, api-ms-win-*, onecore shell APIs

Source paths: shell\ext\openwith\openwith.cpp, onecoreuap\shell\lib\executeitem\executeitem.cpp


PE metadata (readpe / radare2)

FieldValue
PathIETemp/64/openwith.exe
FormatPE32+ GUI x86-64
Size158,560 bytes (~155 KiB)
SHA-25611087185d089bcf1a57be895af6e9ff736dbe7cf53392ca48dbc76fe05eb890b
TimestampReproducible-build hash
OSWindows 10+
SignedYes (Microsoft)

Deployment and references

ItemEvidence
RoleBackup of original 64-bit OpenWith
SmithySkipping C:\Asgard\IETemp\64\OpenWith.exe since already backed up
Live replacementOverwriting C:\Windows\system32\OpenWith.exe from IETemp\64\Noop.exe
Active stubIETemp/64/Noop.exe

Runtime timeline

Time (UTC)EventSource
18:43:09.267Skip OpenWith backup — already presentsmithySoftwareInstall.log
18:43:09.496Overwrite system32 OpenWith with Noop stubSmithy log
18:43:09.514takeown/icacls on system32 OpenWith — successSmithy log

Relationships

ComponentRelationship
IETemp/32/openwith.exe32-bit OpenWith backup (different SHA-256)
IETemp/64/Noop.exeStub deployed over live OpenWith
SmithyProvisioning orchestrator

Evidence

  • readpe, r2_analyze.sh, strings
  • logs/startup/smithySoftwareInstall.log

admindesk.top — Reversed & documented from Asgard rig backups and GCIS plugin binaries.