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/Swakappears inExternSwak_x86strings.https://confluence.nvidia.com/display/RMPER/PERFDEBUGappears inperfdebugstrings.GetNcpSecretKeyappears innet132/net164symbol 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
| Category | APIs |
|---|---|
| PerfLib | PerfStartProviderEx, PerfCreateInstance, PerfSetULongCounterValue, PerfSetCounterSetInfo, PerfStopProvider |
| SCM | OpenSCManagerW, OpenServiceW, QueryServiceConfigW |
| File/Module | CreateFileW, GetModuleFileNameW/A, LoadLibraryExW, GetProcAddress |
| CRT | MSVC C++ (.?AVGpuCounter@@, standard library RTTI) |
Build path: D:\sw\pvt\jhutchins\nvtopps-wmi64\x64\Release\nvtopps-wmi64.pdb
PE metadata (readpe / radare2)
| Field | Value |
|---|---|
| Path | gridperf/nvtopps-wmi64.exe |
| Format | PE32+ console x86-64 |
| Size | 303,104 bytes |
| SHA-256 | ac1a0e9f5889b1a9b23f2a986f1696c69c4bd715c2dc6b0d33806773edcf53fa |
| Compiled | Thu Feb 16 16:15:42 2023 |
| Entry | 0x14000d850 |
| Subsystem | Windows CUI |
| Signed | No |
Counter manifest (nvPerfProvider.man)
| ID | URI | Metric |
|---|---|---|
| 1 | NVIDIA.GPU0.Temperature | Temperature (°C) |
| 2 | NVIDIA.GPU0.GraphicsClock | Graphics clock (MHz) |
| 3 | NVIDIA.GPU0.MemoryClock | Memory clock (MHz) |
| 4 | NVIDIA.GPU0.GraphicsUtilization | Graphics util (%) |
| 5 | NVIDIA.GPU0.FrameBufferUtilization | FB util (%) |
| 6 | NVIDIA.GPU0.VideoUtilization | Video util (%) |
| 7 | NVIDIA.GPU0.FanCooler | Fan cooler (%) |
| 8 | NVIDIA.GPU0.FanSpeed | Fan speed (RPM) |
| 9 | NVIDIA.GPU0.Power | Power (mW) |
Collector template: gridperf/GridPerfMonTemplate.xml → output C:\perflogs\xen\GridPerf\ (1s sample interval).
Deployment and references
| Item | Evidence |
|---|---|
| Manifest | gridperf/nvPerfProvider.man — applicationIdentity="nvtopps-wmi64.exe" |
| Collector | gridperf/GridPerfMonTemplate.xml, GridPerfMonTemplate-4080.xml |
| Pandora | modify_gridperf queries logman query GridPerf |
| Sysmon allowlist | CommandLine contains GridPerf; TargetFilename contains GridPerf |
| Log upload | aws_log_uploader.py → logman stop GridPerf before backup |
Runtime timeline
| Time (UTC) | Event | Source |
|---|---|---|
| 18:42:46 | Pandora [modify_gridperf] No GridPerf modification needed | logs/startup/startup.log |
| 18:42:47 | logman query GridPerf rc=0 | logs/startup/startup.log |
| 18:48:42 | Sysmon: 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,stringsongridperf/nvtopps-wmi64.exegridperf/nvPerfProvider.man,GridPerfMonTemplate.xmllogs/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
| DLL | APIs |
|---|---|
| USER32.dll | SystemParametersInfo (SPI_SETMOUSE, SPI_GETMOUSE) |
| KERNEL32.dll | GetLastError, heap/time APIs |
| MSVCP120/MSVCR120 | C++ iostream error handling |
Deep extract winapi: GetLastError, GetProcessHeap, QueryPerformanceCounter, GetSystemTimeAsFileTime.
| r2 confirmed | SystemParametersInfoW (USER32.dll) |
Pandora invocation
| Step | Command | Result |
|---|---|---|
disable_mouse_precision | C:\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.txtlogs/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_Initialize → NvAPI_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 failureBuild path: C:\Users\gprusak.NVIDIA.COM\nv_repo\sw\gcomp\dev\src\OSL\CountVisibleGPUs\Release\CountVisibleGPUs.pdb
External interfaces
| Interface | Role |
|---|---|
| CLI | No args observed in strings; likely zero-argument invocation |
| NVAPI | NvAPI_Initialize, NvAPI_EnumPhysicalGPUs (dynamic) |
| PnP | SetupAPI device enumeration, CFGMGR32 devnode status |
| COM | ole32.dll imported (purpose not recovered) |
| Stdout | Console output via WriteConsoleW / WriteFile |
No network, registry, or service surface.
PE metadata
| Field | Value |
|---|---|
| SHA-256 | 59365617f5f3c25f0b745da3e6b32dbdc250276e39aa01e1165805f8c336198e |
| Size | 494,592 bytes |
| Format | PE32 console i386, MSVC, compiled 2013-10-01 |
| Subsystem | Windows CUI |
| Canary | enabled (/GS) |
| Exports | none |
Notable strings
| String | Meaning |
|---|---|
NvAPI_Initialize | NVAPI entry |
NvAPI_EnumPhysicalGPUs | GPU enumeration |
nvapi.dll / nvpowerapi.dll | Dynamically loaded |
ERROR | Failure label on stdout |
iostream stream error | C++ iostream error path |
Runtime timeline
| Source | Finding |
|---|---|
logs/startup/startup.log | Not invoked. Pandora check_gpu_script uses devcon.exe, ForceDisp.exe, and registry reads instead |
| Workspace grep | No other log references in this snapshot |
Failure modes
| Condition | Behavior (inferred) |
|---|---|
nvapi.dll missing / NvAPI_Initialize fail | Prints ERROR, non-zero exit (not verified) |
| Zero GPUs enumerated | Likely prints 0 (not verified) |
| PnP enumeration mismatch | SetupAPI path may supplement NVAPI count |
Relationships
| Component | Interaction |
|---|---|
devcon.exe | Pandora's primary GPU validation tool at boot |
ForceDisp.exe | Used in same check_gpu_script step for resolution forcing |
| NVAPI stack | Same 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.dllis used on the hot path or linked incidentally. - Any scheduled task or manual ops playbook referencing this binary.
Evidence
strings/ radare2 ontools/CountVisibleGPUs.exe_analysis/CountVisibleGPUs.strings_filtered.txtlogs/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 settingPDK logging framework embedded.
Windows API surface
| Category | APIs |
|---|---|
| NVAPI/DRS | Dynamic NVAPI driver settings session |
| Process | CreateProcessAsUserW, CreateThread, CreateMutexA |
| Sync | Mutex 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:
0xprefix → 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.swkarchive
Windows API surface
| Category | APIs |
|---|---|
| Graphics | OPENGL32, d3d9, CreateDXGIFactory |
| Display | EnumDisplayDevicesA/W |
| Process | EnumProcesses, EnumProcessModules, CreateRemoteThread |
| Setup | SETUPAPI.dll |
| Network | WS2_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:
| Invocation | Meaning |
|---|---|
echo y | ForceDisp.exe f <hexfile> 0 100 | Force EDID from hex onto GPU 0, output 100 → out=action f |
echo e 0 100 q | ForceDisp.exe | Enumerate GPU 0 output 100, then quit |
Action letters: f (force), e (enumerate), q (quit). Wiki reference in strings: FakeDisp tool docs.
Windows API surface
| Category | APIs |
|---|---|
| NVAPI | Dynamic nvapi_QueryInterface; NvAPI_GPU_SetEDID, NvAPI_GPU_GetEDID, NvAPI_EnumPhysicalGPUs, NvAPI_GPU_GetAllOutputs |
| Unwind | RtlLookupFunctionEntry (x64 SEH) |
PE32+ CUI x64 (2022). KERNEL32 + dynamic NVAPI.
| r2 confirmed | GetProcAddress (KERNEL32.dll) | LoadLibraryExW (KERNEL32.dll) | CreateFileW (KERNEL32.dll) |
Pandora invocations
| Step | Command | Result |
|---|---|---|
check_gpu_script | echo y | "c:\asgard\tools\forcedisp\ForceDisp.exe" f "c:\asgard\tools\forcedisp\NvidiaVGX_custom_all_resolutions.hex" 0 100 | rc=0, out=action f |
check_gpu_script | echo 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
echofor automation. action fstring emission confirms force-EDID code path taken.- NVAPI GPU/output index args map to
NvAPI_GPU_GetAllOutputsenumeration.
Evidence
docs/reverse-engineering/_analysis/ForceDisp.strings_filtered.txtlogs/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— helpf,e,q— force, enumerate, quit
Windows API surface
| Category | APIs |
|---|---|
| NVAPI | nvapi_QueryInterface, nvapi_pepQueryInterface |
| Power API | nvpowerapi.dll dynamic load |
| Process | CreateProcessAsUserW (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— additionalnvpowerapi.dllload path. CreateProcessAsUserWsuggests 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 useAlso sets perf strings: PS_FRAMERATE_LIMITER_*, P-state performance mode.
Windows API surface
| Category | APIs |
|---|---|
| Display config | GetDisplayConfigBufferSizes, QueryDisplayConfig, SetDisplayConfig |
| GDI | EnumDisplayDevicesA |
| SCM | OpenSCManagerW |
| NVAPI | Dynamic 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-displaystring. - 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 renderingWindows API surface
| Category | APIs |
|---|---|
| Windowing | CreateWindowExW, RegisterClassExW, SetWindowPos, SetForegroundWindow |
| Shell | RegisterShellHookWindow, SHELL32.dll |
| GDI | GDI32.dll (background rendering) |
| Desktop | GetDesktopWindow |
MSVC 14 runtime imports. PE32+ GUI x64.
| r2 confirmed | LoadLibraryW (KERNEL32.dll) | GetProcAddress (KERNEL32.dll) | SystemParametersInfoW (USER32.dll) |
Install / runtime timeline
| Event | Source |
|---|---|
WAR replacement to C:\Asgard\Tools and C:\Windows | smithySoftwareInstall.log |
| Smithy V1 attempts explorer → gfndesktop swap | Smithy.log |
CLI: smithy.exe -s on -p default | enablegfndesktop.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_DISPLAYCHANGEhandler for resolution change propagation.
Evidence
docs/reverse-engineering/_analysis/gfndesktop.strings_filtered.txtlogs/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
MainWindowclass. - 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 entriesTypes: 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/-lflags. - Protobuf types from
NVIDIA.Grid.Messages.dll— traceGameLaunchInfoserialize path. LaunchData.datbinary 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
| Interface | Role |
|---|---|
| CLR host | Loaded by LaunchDataEditor.exe, GS2 managed components |
| Import | Sole PE import: mscoree.dll!_CorDllMain |
| Protobuf wire | Binary serialization for MessageBus / TCP peers |
| TCP | TcpSocketConnector for PM packet transport |
No direct Win32 API — pure managed library.
PE metadata
| Field | Value |
|---|---|
| SHA-256 | 6c68398451444c0c6ca29b75e017c7228910a66190ffde8ce79bd7981c6b2ff6 |
| Size | 134,656 bytes |
| Format | PE32 Mono/.NET assembly i386, compiled 2013-06-12 |
| Subsystem | Windows CUI |
| Exports | none (managed) |
| Entry | _CorDllMain thunk @ 0x100221ee |
Notable strings (sample)
| Type / string | Purpose |
|---|---|
GameLaunchInfo | Game launch persistence (LaunchData.dat) |
PmPacketFactory | Platform Manager packet factory |
GameSessionErrorCode | Session error enumeration |
ServerResolution / ScreenResolution | Display resolution messages |
NotifyError, QueryStatus | PM action verbs |
protobuf-net / ProtoBuf | Serialization framework |
Runtime timeline
| Source | Finding |
|---|---|
logs/startup/startup.log | No direct invocation (library only) |
LaunchDataEditor.exe | Primary consumer in tools/LaunchDataEditor/ |
| GS2 / Bifrost stack | Message types referenced by seat services (indirect) |
Failure modes
| Condition | Behavior (managed) |
|---|---|
| Deserialization mismatch | ErrorOccurredEventArgs<T> pattern in type names |
| Invalid packet | Factory methods return error packets (CreateNotifyFailedPacket) |
| Missing extension | IExtensible.GetExtensionObject for protobuf extensions |
Relationships
| Component | Interaction |
|---|---|
LaunchDataEditor.exe | CLI tool for reading/writing LaunchData.dat |
protobuf-net.dll | Bundled serializer dependency |
mb-repeater | Forwards Bifrost/Grid messages on MessageBus |
| GS2 / NGS stack | Session 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
stringsontools/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.StartThis Release build lacks ExecuteCommandSync, ChangeUserPassword, and k_username/x_username/k_password/x_password strings present in the sas2 Debug build.
Windows API surface
| Layer | APIs |
|---|---|
| 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)
| Field | Value |
|---|---|
| Path | tools/LaunchProcessAsUser.exe |
| Format | PE32 CUI, Mono/.NET assembly |
| Architecture | x86 (32-bit) |
| Size | 6,144 bytes |
| SHA-256 | 21633bf70dc2af1fc68659e7715b5b4c1a639580abfa08b8936cefdc7e1d35c1 |
| Compiled | Thu Mar 26 2015 |
| .NET target | .NET Framework 4 Client Profile |
| Entry | Native 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,cmpvs.sas2/bin/LaunchProcessAsUser.exedocs/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.DLLfor 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.
SetSystemTimeimport suggestsnet timesubcommand 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
| DLL | Role |
|---|---|
| NETAPI32.dll | NetUserAdd/Del/Enum, NetServiceEnum/Control/Install, NetShare* |
| SAMLIB.dll | SAM database access |
| NTDSAPI.dll | AD directory services |
| dsrole.dll | Domain role queries |
| logoncli.dll | Logon CLI |
| ADVAPI32 | OpenSCManagerW, 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. RtlNtStatusToDosErrorfor 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 stubservices/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
| Category | APIs |
|---|---|
| Registry | ADVAPI32 registry writes under NvFBCEnable + nvlddmkm service keys |
| NVAPI | Dynamic nvapi_QueryInterface via nvapi.dll |
| Event log | OpenEventLogA |
| r2 confirmed | LoadLibraryA (KERNEL32.dll) | GetProcAddress (KERNEL32.dll) | CreateFileA (KERNEL32.dll) | RegQueryInfoKeyA (ADVAPI32.dll) |
Pandora invocation
| Step | Command | Result |
|---|---|---|
enable_nvfbc | C:\Asgard\tools\nvfbcenable.exe -enable | rc=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.
-noresetflag skips display driver reset IOCTL path.
Evidence
docs/reverse-engineering/_analysis/NvFBCEnable.strings_filtered.txtlogs/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:
| Flag | Behavior |
|---|---|
--x, --y | Target resolution (Pandora: 1920×1080) |
--help, --version | Usage / version |
--all, --single | Multi/single display scope |
displayLess, multiDisplay, nvapi-allDisplays | Mode keywords |
Internal action string: doChangeres W H bpp Hz (observed: doChangeres 1920 1080 32 60).
Custom exports: SetDisplayLessMode, SetCustomResolutionVgx, SetEdid.
Windows API surface
| Category | APIs |
|---|---|
| GDI | EnumDisplayDevices, EnumDisplayMonitors, EnumDisplaySettingsA |
| Desktop | OpenInputDesktop, CreateProcessAsUserW |
| NVAPI | Dynamic 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
| Step | Command | Result |
|---|---|---|
set_native_resolution | c:\asgard\tools\nvDisplayRes.exe --x 1920 --y 1080 | rc=0, out=doChangeres 1920 1080 32 60 |
logs/startup/startup.log 18:42:46 UTC.
Disassembly hints
- Boost options table near
--x/--ystring refs. doChangeresformat string → central resolution change routine.- Export
SetCustomResolutionVgxfor VGX-specific NVAPI path.
Evidence
docs/reverse-engineering/_analysis/nvDisplayRes.strings_filtered.txtlogs/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\nvkblayoutBehavior
CSfxExtractEngine/CSfxDialog_*7-Zip SFX- NVIDIA
RegistryKeylogging 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.
-ignorepnpflag 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 interfacesGoogle Test framework embedded (unit test RTTI). External wiki/Confluence docs referenced in strings.
Windows API surface
| Category | APIs |
|---|---|
| NVAPI | nvapi_QueryInterface, nvapi_pepQueryInterface |
| Process | CreateProcessA, OpenProcess, CreateThread |
| SCM | OpenSCManagerW, 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
CommandRootconstructor. - 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 windowSetTimer— likely countdown or auto-dismissGetMessageA/TranslateAcceleratorA— message loopLoadAcceleratorsA— keyboard shortcuts
Windows API surface
| DLL | APIs |
|---|---|
| USER32.dll | Window creation, message pump, timer, accelerators |
| KERNEL32.dll | Process 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.
SetTimercallback likely triggersExitWindowsExorInitiateSystemShutdownEx.
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
| Category | APIs |
|---|---|
| Network | WS2_32, gRPC TCP |
| Crypto | CRYPT32, bcrypt |
| Debug | dbghelp, 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 (
PmPacketFactorypattern 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.exechild process - LZMA decoder stack
HelpText,-overwriteextraction behaviorWow64DisableWow64FsRedirectionfor x64 payload on WoW64
Windows API surface
| Category | APIs |
|---|---|
| UI | CreateWindowExW, CreateThread, COMCTL32 |
| Filesystem | CreateFileW, SHLWAPI, SHELL32 |
| Registry | RegistryKey logging framework (NVIDIA PDK) |
| WOW64 | Wow64DisableWow64FsRedirection |
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.
CSfxExtractEnginevtable → LZMA decode → file write loop.- Child
setup.exespawn after extraction completes.
Evidence
docs/reverse-engineering/_analysis/NvTensorRTSetup.strings_filtered.txtdocs/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
| Category | APIs |
|---|---|
| Hooks | SetWindowsHookExW (via WinKillHook.dll exports) |
| Shell | Shell_NotifyIcon, CreatePopupMenu, TrackPopupMenu |
| Display | EnumDisplayDevicesW, EnumDisplayMonitors |
| Window | GetForegroundWindow, GetWindowTextW, HtmlHelpW |
| Accessibility | OLEACC imports |
| r2 confirmed | CreateFileA (KERNEL32.dll) |
Pandora invocation
| Step | Action | Result |
|---|---|---|
start_winkill | tasklist … findstr winkill | rc=1 (not running) |
start_winkill | Launch WinKill | pid 4300 |
start_winkill | net start WlanSvc | rc=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.dllload — tracewinkill_install_hookexport. - Tray icon path via
Shell_NotifyIcon+ message pump.
Evidence
docs/reverse-engineering/_analysis/WinKill.strings_filtered.txtlogs/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
| Export | Signature | Purpose |
|---|---|---|
keyboard_proc | long __stdcall (int nCode, uint wParam, long lParam) | Hook callback — filters keys |
winkill_install_hook | bool __cdecl (HWND*) | Install hook via SetWindowsHookExW |
winkill_remove_hook | bool __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 → CallNextHookExHook 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
| DLL | API | Role |
|---|---|---|
| USER32.dll | SetWindowsHookExW | Install LL keyboard hook |
| USER32.dll | UnhookWindowsHookEx | Remove hook |
| USER32.dll | CallNextHookEx | Chain unfiltered keys |
| KERNEL32.dll | GetVersionExA | OS version check at init |
| KERNEL32.dll | Heap/CRT | Legacy MSVC runtime |
| r2 confirmed | SetWindowsHookExW (USER32.dll) | GetProcAddress (KERNEL32.dll) | LoadLibraryA (KERNEL32.dll) |
PE metadata
| Field | Value |
|---|---|
| SHA-256 | b9a29d11152ac5174f60b0074dc2af0e151cf13a1739c45b393d5cc4252eb9bc |
| Size | 53,248 bytes |
| Format | PE32 DLL i386, compiled 2009-03-26 |
| Subsystem | Windows GUI (legacy artifact) |
| NX | disabled |
| Exports | 3 |
Runtime timeline (from logs/startup/startup.log)
| Time (local) | Event |
|---|---|
| 18:42:45.247 | Pandora start_winkill step begins |
| 18:42:45.275 | WinKill.exe launched — PID 4300 |
| 18:42:45.441 | Step completes; WlanSvc start attempted (rc=2, tolerated) |
Pandora: Indirect — WinKill.exe loads this DLL at runtime; Pandora only starts the parent process.
Failure modes
| Condition | Behavior |
|---|---|
SetWindowsHookExW fails | winkill_install_hook returns false |
| Hook already installed | Early return without re-installing |
| NULL HWND passed | Install skipped (test ecx, ecx @ 0x1000106f) |
Relationships
| Component | Interaction |
|---|---|
WinKill.exe | Parent process; calls install/remove exports |
Pandora start_winkill | Boot step launches WinKill |
| Kiosk stack | Complements gfndesktop, shell restrictions |
Not verified
- Whether
winkill_remove_hookis 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_procandwinkill_install_hook _analysis/WinKillHook.strings_filtered.txtlogs/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
| DLL | Role |
|---|---|
| xs.dll | XenStore protocol (12 exports) |
| KERNEL32.dll | GetModuleHandleA, process APIs |
| msvcrt.dll | C 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/removestrings. - 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.txtdocs/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)
| Export | Purpose |
|---|---|
xs_domain_open | Open XenStore connection |
xs_daemon_close | Close daemon connection |
xs_read | Read key value |
xs_write | Write string value |
xs_write_bin | Write binary value |
xs_remove | Delete key |
xs_directory | List directory children |
xs_watch | Register watch on key |
xs_unwatch | Cancel watch |
xs_transaction_start | Begin transaction |
xs_transaction_end | Commit/abort transaction |
xs_free | Free 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_* exportBuild path: c:\remote-ops-tmp\rops8vffrf\windows\build\i386\xs.pdb
Windows API surface
| DLL | APIs |
|---|---|
| KERNEL32.dll | CreateMutexA, WaitForSingleObject, ReleaseMutex, CloseHandle, LoadLibraryA, GetProcAddress |
| ADVAPI32.dll | RegOpenKeyExA, RegQueryValueExA, RegCloseKey |
| msvcrt.dll | malloc, free, calloc, memcpy, CRT init |
| r2 confirmed | LoadLibraryA (KERNEL32.dll) | GetProcAddress (KERNEL32.dll) | RegQueryValueExA (ADVAPI32.dll) | RegOpenKeyExA (ADVAPI32.dll) |
PE metadata
| Field | Value |
|---|---|
| SHA-256 | 63ab7648939e92f688e13dda17d7e5f712b1a5da39e5d4fa6aacd12dba385e0d |
| Size | 11,776 bytes |
| Format | PE32 DLL i386, compiled 2012-02-10 |
| Subsystem | Windows GUI (Citrix legacy) |
| Exports | 12 (ordinal base 1) |
Runtime timeline
| Source | Finding |
|---|---|
logs/startup/startup.log | Not invoked at Pandora boot |
tools/setHostname.py | subprocess.Popen('.\xenstore_client.exe read name') |
xenstore_client.exe | Imports all 12 xs_* exports explicitly |
Failure string (xenstore_client): cannot open xenstore interface → xs_domain_open failure.
Failure modes
| Condition | Behavior |
|---|---|
| XenStore daemon unreachable | xs_domain_open fails; CLI prints error |
| Mutex contention | WaitForSingleObject blocks concurrent access |
| Missing Citrix XenTools registry | RegOpenKeyExA failure path |
| Invalid key path | XenStore protocol error returned to caller |
Relationships
| Component | Interaction |
|---|---|
xenstore_client.exe | Sole direct consumer in Asgard tree |
setHostname.py | Reads VM hostname via xenstore |
| Citrix XenTools | Registry 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
| Category | APIs |
|---|---|
| Process exit | ExitProcess, TerminateProcess |
| CRT startup | Standard MSVC 14.35 init (GetStartupInfoW, heap, TLS) |
| Console | GetStdHandle, WriteFile, WriteConsoleW (unused in normal path) |
Only KERNEL32.dll imported. No USER32, SHELL32, or networking.
PE metadata (readpe / radare2)
| Field | Value |
|---|---|
| Path | IETemp/32/Noop.exe |
| Format | PE32+ console x86-64 |
| Size | 121,456 bytes |
| SHA-256 | 27b5fbbf36d763a9cb45d40ca6fddeafe3abc1ddf35611eedf2334fd37ae41bc |
| Compiled | Tue May 5 01:29:39 2026 |
| Linker | MSVC 14.35 |
| Entry | 0x140001264 → main @ 0x140001000 (3 bytes) |
| Signed | Yes (NVIDIA Corporation) |
Deployment and references
| Item | Evidence |
|---|---|
| Source | tools/Smithy/Smithy/Noop.exe (identical SHA-256) |
| Staging | Smithy backs up to C:\Asgard\IETemp\32\Noop.exe |
| Overwrite target | C:\Windows\SysWOW64\OpenWith.exe |
| Original backup | IETemp/32/openwith.exe (separate Microsoft binary) |
Runtime timeline
| Time (UTC) | Event | Source |
|---|---|---|
| 18:43:09.269 | Backing up ...Noop.exe to C:\Asgard\IETemp\32\Noop.exe | logs/startup/smithySoftwareInstall.log |
| 18:43:10.054 | Overwriting C:\Windows\SysWOW64\OpenWith.exe from C:\Asgard\IETemp\32\Noop.exe | Smithy log |
| 18:43:10.071 | icacls grant xen:F on SysWOW64 OpenWith — rc=0 | Smithy 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,cmpvs.IETemp/64/Noop.exelogs/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.exeThis backup is not deployed at runtime — it exists for potential restore/deprovision.
Windows API surface
Extensive Windows shell stack (100+ import DLLs):
| Category | DLLs |
|---|---|
| Shell | SHELL32, SHLWAPI, SHCORE |
| UI | USER32, GDI32, UxTheme, dwmapi |
| COM/OLE | OLEAUT32, PROPSYS |
| Core | KERNEL32, ntdll, api-ms-win-* forwarders |
| Platform | AEPIC, TWINAPI, dxgi |
Export: g_trayTriageBlock (Explorer-specific diagnostic hook).
PE metadata (readpe / radare2)
| Field | Value |
|---|---|
| Path | IETemp/32/explorer.exe |
| Format | PE32 GUI, Intel 80386 |
| Size | 4,990,552 bytes (~4.76 MiB) |
| SHA-256 | 987ced27192b4c1bb5a6fc50732b054161af29e4e9db8d02885d060b971469d0 |
| Timestamp | Reproducible-build hash (2096f0c1) |
| OS | Windows 10+ (MajorSubsystemVersion=10) |
| Entry | 0x00536440 |
| Signed | Yes (Microsoft) |
| PDB | explorer.pdb |
Notable strings
pcshell\shell\explorer\trayanimations.cpp,startmnu.cpp,shellexperiencehelpers.cppExplorerBoot,immersiveShellHangEncountered- No NVIDIA/custom branding
Deployment and references
| Item | Evidence |
|---|---|
| Role | 32-bit backup of stock explorer |
| Smithy | Skipping C:\Asgard\IETemp\32\explorer.exe since already backed up |
| Live replacement | gfndesktop.exe overwrites live explorer (not this backup) |
| Restore script | tools/gfndesktop/enabledefaultexplorer.bat starts C:\Windows\explorer.exe |
Runtime timeline
| Time (UTC) | Event | Source |
|---|---|---|
| 18:43:09.269 | Skip backup — already present | smithySoftwareInstall.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.exeon deprovision.
Evidence
readpe,r2_analyze.sh,strings,objdump -plogs/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
| Category | DLLs |
|---|---|
| Shell | SHELL32 (execute item / open-with UI) |
| UI | USER32 |
| Core | KERNEL32, api-ms-win-core-, api-ms-win-shcore- |
Source paths in strings: shell\ext\openwith\openwith.cpp
PE metadata (readpe / radare2)
| Field | Value |
|---|---|
| Path | IETemp/32/openwith.exe |
| Format | PE32 GUI, Intel 80386 |
| Size | 121,000 bytes (~118 KiB) |
| SHA-256 | ce0576515d7289f01e742353e8220be710f85071fa25270c3171dc5431687e31 |
| Timestamp | Reproducible-build hash |
| OS | Windows 10+ |
| Signed | Yes (Microsoft Windows Production PCA 2011) |
Manifest: name="Microsoft.OpenWith.PROGRAM", <description>OpenWith</description>
Deployment and references
| Item | Evidence |
|---|---|
| Role | Backup of original 32-bit OpenWith |
| Smithy | Skipping C:\Asgard\IETemp\32\OpenWith.exe since already backed up |
| Live replacement | Overwriting C:\Windows\SysWOW64\OpenWith.exe from IETemp\32\Noop.exe |
| Active stub | IETemp/32/Noop.exe |
Runtime timeline
| Time (UTC) | Event | Source |
|---|---|---|
| 18:43:09.269 | Skip OpenWith backup — already present | smithySoftwareInstall.log |
| 18:43:10.054 | Overwrite SysWOW64 OpenWith with Noop stub | Smithy log |
Not verified
- Automated restore from this backup on Smithy uninstall/deprovision.
- Exact Windows build of backed-up OpenWith.
Evidence
readpe,r2_analyze.sh,stringslogs/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
| Category | APIs |
|---|---|
| Process exit | ExitProcess |
| CRT | MSVC 14.35 startup (KERNEL32 only) |
No USER32, SHELL32, or file operations beyond PE load.
PE metadata (readpe / radare2)
| Field | Value |
|---|---|
| Path | IETemp/64/Noop.exe |
| Format | PE32+ console x86-64 |
| Size | 121,456 bytes |
| SHA-256 | 27b5fbbf36d763a9cb45d40ca6fddeafe3abc1ddf35611eedf2334fd37ae41bc |
| Compiled | Tue May 5 01:29:39 2026 |
| Entry | 0x140001264 |
| Signed | Yes (NVIDIA Corporation) |
Deployment and references
| Item | Evidence |
|---|---|
| Staging | Backing up ...Noop.exe to C:\Asgard\IETemp\64\Noop.exe |
| Overwrite | C:\Windows\system32\OpenWith.exe ← IETemp\64\Noop.exe |
| Original backup | IETemp/64/openwith.exe (Microsoft OpenWith, separate file) |
Runtime timeline
| Time (UTC) | Event | Source |
|---|---|---|
| 18:43:09.270 | Backup Noop.exe to IETemp\64 | smithySoftwareInstall.log |
| 18:43:09.496 | Overwriting C:\Windows\system32\OpenWith.exe from C:\Asgard\IETemp\64\Noop.exe | Smithy log |
| 18:43:09.514 | icacls on system32 OpenWith — rc=0 | Smithy log |
Evidence
readpe,r2_analyze.sh,cmpidentical toIETemp/32/Noop.exelogs/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
| Category | DLLs |
|---|---|
| Shell | SHELL32, SHLWAPI, SHCORE |
| UI | USER32, GDI32, UxTheme, dwmapi |
| Session | WTSAPI32, PROPSYS |
| Network | WININET |
| Core | KERNEL32, ntdll, RPCRT4, api-ms-win-* |
PE metadata (readpe / radare2)
| Field | Value |
|---|---|
| Path | IETemp/64/explorer.exe |
| Format | PE32+ GUI x86-64 |
| Size | 5,596,280 bytes (~5.34 MiB) |
| SHA-256 | 6981ccee742819613d24e0b7b53ba58112ed62240d76585ef41dec2d0bf5a3ce |
| Timestamp | Reproducible-build hash |
| OS | Windows 10+ |
| Signed | Yes (Microsoft) |
Notable strings
Spcshell\shell\explorer\tray.cpp,initcab.cpp,trayshowdesktop.cppWaitOnShellStartup,WaitForImmersiveShell,ExplorerBootTerminateShellApplications- No NVIDIA identifiers
Deployment and references
| Item | Evidence |
|---|---|
| Role | 64-bit backup of stock explorer |
| Smithy | Skipping C:\Asgard\IETemp\64\explorer.exe since already backed up |
| Live swap | Overwriting C:\Windows\explorer.exe from gfndesktop.exe |
| Restore | tools/gfndesktop/enabledefaultexplorerkiosk.bat |
Runtime timeline
| Time (UTC) | Event | Source |
|---|---|---|
| 18:43:09.268 | Skip backup — already present | smithySoftwareInstall.log |
| 18:43:09.536 | First explorer overwrite attempt — Permission denied, retried with takeown | Smithy log |
Relationships
| Component | Relationship |
|---|---|
| IETemp/32/explorer.exe | 32-bit counterpart — different SHA-256 |
| gfndesktop.exe | Kiosk shell substituted for live explorer |
| Smithy | Orchestrates backup/skip/overwrite |
Evidence
readpe,r2_analyze.sh,stringslogs/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.exeWindows API surface
| Category | DLLs |
|---|---|
| Shell | SHELL32 (open-with dialog / execute item) |
| UI | USER32 |
| Core | KERNEL32, api-ms-win-*, onecore shell APIs |
Source paths: shell\ext\openwith\openwith.cpp, onecoreuap\shell\lib\executeitem\executeitem.cpp
PE metadata (readpe / radare2)
| Field | Value |
|---|---|
| Path | IETemp/64/openwith.exe |
| Format | PE32+ GUI x86-64 |
| Size | 158,560 bytes (~155 KiB) |
| SHA-256 | 11087185d089bcf1a57be895af6e9ff736dbe7cf53392ca48dbc76fe05eb890b |
| Timestamp | Reproducible-build hash |
| OS | Windows 10+ |
| Signed | Yes (Microsoft) |
Deployment and references
| Item | Evidence |
|---|---|
| Role | Backup of original 64-bit OpenWith |
| Smithy | Skipping C:\Asgard\IETemp\64\OpenWith.exe since already backed up |
| Live replacement | Overwriting C:\Windows\system32\OpenWith.exe from IETemp\64\Noop.exe |
| Active stub | IETemp/64/Noop.exe |
Runtime timeline
| Time (UTC) | Event | Source |
|---|---|---|
| 18:43:09.267 | Skip OpenWith backup — already present | smithySoftwareInstall.log |
| 18:43:09.496 | Overwrite system32 OpenWith with Noop stub | Smithy log |
| 18:43:09.514 | takeown/icacls on system32 OpenWith — success | Smithy log |
Relationships
| Component | Relationship |
|---|---|
| IETemp/32/openwith.exe | 32-bit OpenWith backup (different SHA-256) |
| IETemp/64/Noop.exe | Stub deployed over live OpenWith |
| Smithy | Provisioning orchestrator |
Evidence
readpe,r2_analyze.sh,stringslogs/startup/smithySoftwareInstall.log