NDC and GSP
GSP, GSConfigurator, MessageBus, NDC, PipsController, and NDC plugin notes are consolidated here from the 2026-05-19 snapshot.
2026-05-19 application notes
NvContainerGSP.exe
What this program actually does
NvContainerGSP.exe is the GameSeat Platform (GSP) NvContainer host process on an Asgard/GFN gameseat. It runs as a Windows service, loads mandatory plugins from %AG_HOME%\services\GSP\plugins, and provides the local configuration authority (GSConfigurator) and cross-session message bus broadcast infrastructure that all other seat services depend on.
Container version: v1.49. Unlike GCIS, GSP succeeded and remained running throughout the captured session.
Architecture / control flow
NvContainerGSP.exe (ServiceHost / HostWin32)
├─ NvcPluginManager — mandatory plugin lifecycle
├─ NvMessageBusBroadcast.dll — no Start transition (Initialized → Started immediately)
│ └─ IMessageBusBroadcastServer, reads messagebus.conf
└─ GSConfigurator/GSConfiguratorPlugin.dll
├─ ConfigManager — ZoneConfig, SeatConfig, GcisConfigData, ContentConfig, ...
├─ HandleGetConfiguration — MB RPC handler
└─ TAS telemetry sessionCore RTTI (nvc::): ServiceHost, HostWin32, PluginManager, RegistryStorage, DirectoryEnumerator, DefaultContainerConfig.
PE: x86-64, MSVC 14.39, no CLR. PDB: NvContainer.pdb from Perforce build tree.
External interfaces
Plugin directory scan
| Path | Loaded as |
|---|---|
plugins/messagebus.conf | Processed by DirectoryEnumerator (config for broadcast plugin) |
plugins/NvMessageBusBroadcast.dll | Mandatory plugin v3.22.3719.8856 |
plugins/GSConfigurator/GSConfiguratorPlugin.dll | Mandatory plugin v2.0.0.0 |
Windows service
- Reports
Start-pending→Running→ staysRunning - DACL adjustment with privilege
0x00100000for process - Quit forbiddance: GSConfigurator sets
quit disabledat session start (18:48:42)
Registry
RegistryStorageper plugin load (same pattern as GCIS)
Message Bus (indirect)
- Does not embed MessageBus client itself; plugins connect to broadcast server started by NvMessageBusBroadcast
Runtime timeline
| Time (UTC) | Event | Source |
|---|---|---|
| 18:42:47.400 | Container main v1.49, telemetry init | NvContainerGsp.log |
| 18:42:47.474 | NvMessageBusBroadcast secure-loaded (62 ms) | NvContainerGsp.log |
| 18:42:47.530 | GSConfiguratorPlugin secure-loaded (32 ms) | NvContainerGsp.log |
| 18:42:47.534 | NvMessageBusBroadcast → Initialized (no explicit Start) | NvContainerGsp.log |
| 18:42:47.578 | GSConfiguratorPlugin Initialized | NvContainerGsp.log |
| 18:42:47.579 | Container Running; Starting GSConfiguratorPlugin | NvContainerGsp.log |
| 18:42:47.596 | Both plugins Started; total load ~213 ms | NvContainerGsp.log |
| 18:42:48–18:43:25 | NvMessageBusBroadcast receives system messages (peer joins) | NvContainerGsp.log |
| 18:43:01 | GSConfigurator serves GcisConfigData to first GCIS run (success) | GSConfiguratorPluginCurrent.log |
| 18:48:42.755 | GSConfigurator sets quit forbiddance true (active session) | NvContainerGsp.log |
| 19:04:52–19:04:53 | Second GCIS run: ZoneConfig/SeatConfig OK, GcisConfigData fails | GSConfiguratorPluginCurrent.log |
Failure modes
| Condition | Log / behavior |
|---|---|
| Mandatory plugin init/start failure | Same pattern as GCIS: mandatory plugin X has failed, container exit |
| Dynamic plugin load attempted | Dynamic loading of plugins is disabled |
| Core failure | Core failed → unload all plugins |
| Plugin config disabled | Plugin %s is now disabled in config (string present; not seen in log) |
GSP did not fail in this snapshot — failure mode documented from shared NvContainer strings and GCIS counterpart.
Not verified
- GSP acronym expansion (not in binary strings).
- Whether GSP container reloads config without restart.
- Exact service name registered with SCM.
- Relationship between GSP quit forbiddance and session manager teardown.
Evidence
strings/ RTTI onservices/GSP/NvContainerGSP.exelogs/GSP/NvContainerGsp.loglogs/GSP/GSConfiguratorPluginCurrent.log- Comparison with
logs/GCIS/NvContainerGcis.log(v1.45, exit 14109)
GSConfiguratorPlugin.dll
What this program actually does
GSConfiguratorPlugin.dll is the seat configuration server for GeForce NOW gameseats. It loads zone/seat/content config files at startup, exposes them via GetConfiguration RPC on the NVIDIA Message Bus (endpoint GSConfigurator), and serves as the single source of truth for GCIS plugins (GcisConfigData), AutoOnboarder (ContentConfig, SasConfigData), CLI tools, and other seat services.
Build: version 2.0 2026-05-12-d72d50d. DLL version 2.0.0.0.
Architecture / control flow
NvContainerGSP.exe
└─ GSConfiguratorPlugin.dll
├─ GspPluginTaskQueue / GspDeferredTaskQ
├─ ConfigManager
│ ├─ Load configs at PluginStart (profile '[REDACTED_PROFILE]', environment '[REDACTED_BASE_ENV]')
│ ├─ GetConfiguration(config, property) → protobuf response
│ └─ Access control / metrics (GSConfiguratorMetrics)
├─ HandleGetConfiguration — async via MessageProcessorQueue
├─ GSConfiguratorServiceAPI (protobuf)
│ ├─ Request.GetConfiguration
│ └─ Response.GetConfigurationResponse
└─ GSConfiguratorTa — TAS telemetry sessionKey RTTI: ConfigManager, GsConfiguratorPlugin, GSConfiguratorServiceAPI_Request_GetConfiguration, AttributesSchemaVersion1Validator, AccessDeniedEvent@GSConfiguratorMetrics.
External interfaces
GSConfigurator Service API (Message Bus RPC)
| RPC | Request | Response |
|---|---|---|
| GetConfiguration | config + optional property path | Full config blob or property subtree |
Observed config keys in logs:
| Config key | Typical consumer |
|---|---|
ZoneConfig | All GCIS plugins, nvctmtsvc, CLI |
SeatConfig | All GCIS plugins, seat identity |
GcisConfigData | All GCIS plugins at PluginStart (mandatory) |
ContentConfig | AutoOnboarder / content tools |
SasConfigData | SAS onboarding |
Message Bus
- Endpoint:
GSConfigurator - Peer naming:
GSPrerequisites:GSConfigClient_<pid>_... - Logs caller PID, user, service list, executable path for each request
Files / paths
- Config loaded from seat-local files (exact paths not in logs;
ConfigManager: Successfully loaded configs) - Reference string:
messagebus.confpath under NvContainer install dir
Runtime timeline
| Time (UTC) | Event | Source |
|---|---|---|
| 18:42:47.559 | Module GSConfigurator, TAS session initiated | GSConfiguratorPluginCurrent.log |
| 18:42:47.587 | ConfigManager: Successfully loaded configs | GSConfiguratorPluginCurrent.log |
| 18:42:47.596 | Started on '[REDACTED_BASE_ENV]' Seat with profile '[REDACTED_PROFILE]' | GSConfiguratorPluginCurrent.log |
| 18:42:48.139 | GetConfiguration ZoneConfig from gsconfiguratorcli (OK) | GSConfiguratorPluginCurrent.log |
| 18:42:58.647 | GetConfiguration SeatConfig from nvctmtsvc (OK) | GSConfiguratorPluginCurrent.log |
| 18:43:01.777–18:43:01.913 | Seven GcisConfigData requests from GCIS PID 4940 — all OK | GSConfiguratorPluginCurrent.log |
| 19:04:52.326–19:04:52.785 | Second GCIS init: ZoneConfig + SeatConfig OK (14 requests) | GSConfiguratorPluginCurrent.log |
| 19:04:53.024–19:04:53.051 | Seven GcisConfigData requests — all fail: property not found | GSConfiguratorPluginCurrent.log |
| 18:48:42.755 | Quit forbiddance set (session active) | NvContainerGsp.log |
Critical finding: GcisConfigData present at 18:43, absent at 19:04 — ConfigManager state changed between GCIS restarts; not a GSConfiguratorPlugin crash.
Failure modes
| Condition | Log / error |
|---|---|
| Property not in config | OBJECT_NOT_FOUND (0x80ec0006): Property 'GcisConfigData' not found at path 'GcisConfigData' |
| Config load failure | ConfigManager load errors (not seen — load succeeded) |
| Access denied | AccessDeniedEvent@GSConfiguratorMetrics (RTTI; not seen in log) |
| Terminated by CC | SRC_TerminatedByContentController (string in binary) |
| Fail-safe config | CreateFailSafeConfig API present for degraded mode |
Not verified
- On-disk config file paths and format (JSON/XML/protobuf).
- Why
GcisConfigDatadisappeared between 18:43 and 19:04 (session teardown side effect? config reload?). - Full list of config keys beyond those seen in logs.
- GetConfiguration access control rules per caller service.
Evidence
strings/ RTTI onservices/GSP/plugins/GSConfigurator/GSConfiguratorPlugin.dlllogs/GSP/GSConfiguratorPluginCurrent.loglogs/GSP/NvContainerGsp.loglogs/GCIS/GciPluginCurrent.log,GciPluginOld.log(consumer side)
MessageBus.dll
What this program actually does
MessageBus.dll (x64) is the v3 NVIDIA Message Bus client library loaded by seat services and GCIS/GSP plugins at runtime. It connects to the NvMessageBusBroadcast pipe server, implements peer registration/JOIN protocol, serializes BusMessage protobuf packets, and delivers messages to BusObserver listeners in-process.
Deployed at services/GSP/Messagebus/x64/MessageBus.dll (7.5 MB). A separate x86 build exists for 32-bit clients. Plugins link against NvMessageBus.dll which wraps this core transport.
Architecture / control flow
Consumer process (plugin, service, CLI)
└─ NvMessageBus.dll (facade)
└─ MessageBus.dll
├─ MessageBusImpl — core client
├─ PipeEndpoint
│ ├─ Connect / Accept to Broadcast process
│ ├─ OnPipeRead → parse BusMessage protobuf
│ └─ OnPipeWrite — outbound queue
├─ BusObserver / BusObserverInterface_v2/v3
├─ BusPeer — local peer identity (SystemName:ModuleName)
└─ Poco networking + protobuf serializationKey RTTI: BusMessage, BusMessage_Peer, BusMessage_Generic, BusObserver, BusPeer, Bus_Peer, MessageBusImpl, PipeEndpoint, Poco Application, Context, SSL types.
External interfaces
Connection to broadcast server
| Step | Behavior |
|---|---|
| Load config | Path from {variables} in v3 schema; reads messagebus.conf |
| Connect pipe | PipeEndpoint::Connect on handle → broadcast process PID |
| JOIN | Sends peer identity; receives JOIN broadcast from other peers |
| Message dispatch | OnPipeRead: Locking observers before notifying via OnBusMessage |
BusMessage types
| Type | Purpose |
|---|---|
BusMessage.Peer | Peer join/leave/status |
BusMessage.Generic | Application RPC/notification payload |
BusMessage.Status | Error/ack status |
BusMessage.EncryptedBusMessage | Encrypted payload wrapper |
BusMessage.EncryptionSetup | Session key setup |
Configuration schema (embedded JSON)
MessageBusPort,DefaultPeerConfig,Peers[],CrossSessionPeersAllowCrossSessionCommunication: truedefault in seat config
Logging
MessageBus_*.log,MessageBus_*.log_backuprotation pattern
Runtime timeline
| Time (UTC) | Event | Evidence |
|---|---|---|
| 18:42:47.596 | GSP plugins started; broadcast server listening | NvContainerGsp.log |
| 18:42:48+ | Multiple services connect (system message storm on broadcast plugin) | NvContainerGsp.log |
| 18:43:01.362 | GCIS GSConfigClient: Listener connected to message bus with 21 peers | GciPluginOld.log |
| 18:43:01.796 | GciPlugin Start fetch: bus grows to 29 peers | GciPluginOld.log |
| 19:04:52.419 | Second GCIS: SslmSubscriptionTracker sees 76→94 peers | GciPluginCurrent.log |
Peer count growth in logs confirms active MessageBus.dll clients across seat services.
Failure modes
| Error string | Meaning |
|---|---|
MessageBusImpl::post endpoint is NULL | Send before connect |
Cannot create an instance of MessageBusImpl | Factory/init failure |
transportFactory cannot be null | Transport layer missing |
OnPipeRead: received invalid protobuf packet | Deserialize failure |
PipeEndpoint Accept failed ... error %u | Pipe connect failure |
Pipe Disconnect (%u) from Broadcaster | Server-side disconnect |
Not verified
- Exact DLL load path resolution (
{ProgramFiles}/{ProgramData}variables). - SSL/TLS usage for encrypted bus messages on localhost pipes.
- v2 vs v3 client compatibility (
BusObserverInterface_v2present).
Evidence
strings/ RTTI onservices/GSP/Messagebus/x64/MessageBus.dllservices/GSP/Messagebus/x64/messagebus.conflogs/GSP/NvContainerGsp.log- GCIS plugin logs (
GSConfigClientpeer connection lines)
NvMessageBus.dll
What this program actually does
NvMessageBus.dll (x64) is the public Message Bus client facade used by GCIS/GSP plugins and seat services. It wraps MessageBus.dll transport, exposes IMessageBus / IMessageBusListener interfaces (via MessageBusClient namespace), and provides the get_shared_message_bus_peer factory used throughout gsprerequisites (GSConfigClient, plugin stubs).
Deployed at services/GSP/Messagebus/x64/NvMessageBus.dll (3.5 MB). x86 build at Messagebus/x86/NvMessageBus.dll for WoW64 clients.
Architecture / control flow
Plugin / service (e.g. GciPlugin, GSConfigurator)
└─ gsprerequisites::get_shared_message_bus_peer(address, config_path, listener)
└─ NvMessageBus.dll
├─ IMessageBus / IMessageBusListener (MessageBusClient)
├─ IMessageBusConfig — config path + peer address
├─ MessageBusImpl (delegates to MessageBus.dll)
└─ BusObserverInterface_v3 — callback dispatchAll seven GCIS plugins and GSConfiguratorPlugin import this stack (RTTI: UIMessageBus@MessageBusClient, UIMessageBusListener@MessageBusClient, UIBusMessage@MessageBusClient).
External interfaces
Factory API (inferred from logs + RTTI)
| Function | Purpose |
|---|---|
get_shared_message_bus_peer | Create or reuse peer by address + config path |
| Peer naming | {SystemName}:{ModuleName} e.g. GSPrerequisites:GSConfigClient_<pid>_... |
| Listener callbacks | OnConnected, message delivery via IBusMessage |
Configuration
- Reads
IMessageBusConfig— typically points tomessagebus.conf - JSON schema embedded in MessageBus.dll (CrossSessionPeers, DefaultPeerConfig)
Protobuf integration
BusMessage@MessageBusClientwraps payload bytes- Plugins serialize domain protobuf into Generic bus messages
Runtime timeline
| Time (UTC) | Event | Source |
|---|---|---|
| 18:42:47.578 | GSConfigurator initializes MB listener | GSConfiguratorPluginCurrent.log |
| 18:43:01.338 | GciPlugin: Creating new peer GSConfigClient_4940_... | GciPluginOld.log |
| 18:43:01.362 | Listener connected to message bus with 21 peers | GciPluginOld.log |
| 18:43:01.362 | GSConfigurator joined the bus. Fetching requested configs | GciPluginOld.log |
| 19:04:52.395 | Second run: new peer GSConfigClient_12224_..., 76 peers | GciPluginCurrent.log |
| 19:04:52.419 | GSConfigurator joined the bus — init fetch OK | GciPluginCurrent.log |
| 19:04:53.010 | Start fetch peer connects with 90 peers — GcisConfigData fails | GciPluginCurrent.log |
MB connectivity succeeded in both GCIS attempts; failure was GSConfigurator config content.
Failure modes
| Condition | Impact |
|---|---|
| Broadcast server not running | Waiting for the connection with message bus (blocks until GSP up) |
| GSConfigurator not on bus | Waiting for GSConfigurator to join the message bus |
| Config path invalid | IMessageBusConfig load failure (not seen) |
| Peer address collision | Re-use path: Re-using existing peer (normal) |
Not verified
- Exported symbol names beyond gsprerequisites wrappers.
- Thread-safety model for shared peer reuse.
- Whether x64 NvMessageBus.dll is loaded by GCIS from GSP Messagebus path or copied locally.
Evidence
strings/ RTTI onservices/GSP/Messagebus/x64/NvMessageBus.dll- All GCIS plugin logs (
GSConfigClientUtlines) logs/GSP/GSConfiguratorPluginCurrent.log- Cross-ref:
MessageBus.dlltransport doc in same folder
NvMessageBusBroadcast.dll
What this program actually does
This document covers the Messagebus deployment copy at services/GSP/Messagebus/x64/NvMessageBusBroadcast.dll. It is byte-identical (MD5 eb32aacdf75a7d03e19179639618870f) to the NvContainer plugin copy at services/GSP/plugins/NvMessageBusBroadcast.dll.
The DLL implements the cross-session Message Bus broadcast server — named-pipe hub that relays BusMessage protobuf traffic between SYSTEM-session services (GCIS, GSP, AutoOnboarder) and user-session streaming components (SSAU/AppSensor, NvStreamControl).
Version 3.22.3719.8856. Loaded at runtime by NvContainerGSP from the plugins path; this Messagebus copy is the canonical redistributable for other installers referencing {InstallPath}.
Architecture / control flow
NvMessageBusBroadcast.dll
├─ IMessageBusBroadcastServer — plugin/server entry
├─ FileMessageBusConfig → messagebus.conf (co-located in Messagebus/x64/)
├─ PipeServer (CreateNamedPipeW)
│ └─ PipeServerConnection × N clients
├─ Session router
│ ├─ ANY_SESSION broadcasts
│ ├─ Target session filtering
│ └─ CrossSessionPeers ACL from config
└─ BusMessage protobuf codecSee also: plugin-path doc at services/GSP/plugins/NvMessageBusBroadcast.md (same binary, plugin lifecycle context).
External interfaces
Files
| File | Role |
|---|---|
Messagebus/x64/messagebus.conf | Identical to plugins/messagebus.conf (6839 bytes) |
MessageBusBroadcast.log | Server-side log (string reference) |
Named pipes
PipeServer/CreateNamedPipeW— multi-client accept loop- Clients: MessageBus.dll
PipeEndpointin each connecting process
Config highlights (messagebus.conf)
"DefaultPeerConfig": { "AllowCrossSessionCommunication": true }
"CrossSessionPeers": [
{ "SystemName": "SSAU", "ModuleName": "AppSensor" } →
{ "SystemName": "GCIS", "ModuleName": "UadPlugin" | "UadMLPlugin" }
]RTTI interfaces
IMessageBusBroadcastServer, IMessageBusConfig, DefaultMessageBusConfig, FileMessageBusConfig, IMessageTransport, IPipeEndpointObserver.
Runtime timeline
| Time (UTC) | Event | Source |
|---|---|---|
| 18:42:47.404 | NvContainerGSP reads plugins/messagebus.conf before load | NvContainerGsp.log |
| 18:42:47.474 | Broadcast plugin loaded from plugins/ path (uses same binary) | NvContainerGsp.log |
| 18:42:48–18:48:43 | Continuous peer JOIN system messages | NvContainerGsp.log |
| 18:43:01 | GCIS plugins connect; peer count 21→29 on bus | GciPluginOld.log |
| 19:04:52 | Second GCIS connect; peer count 76→94 | GciPluginCurrent.log |
The Messagebus/x64 copy is not separately loaded in this snapshot — NvContainer uses plugins/ copy. Both paths exist for packaging.
Failure modes
| Error string | Meaning |
|---|---|
CreateNamedPipeW failed | Server cannot start — all MB clients fail to connect |
Failed to accept pipe connection | Client connect error |
Peer is not allowed to send message to non-default session | Cross-session ACL violation |
without SharedService role! | Peer missing role for join notifications |
OnPipeRead: received invalid protobuf packet | Wire format error |
Failed to print session statistics | Diagnostics only |
If broadcast server fails, all GSConfigClient peers block at Waiting for the connection with message bus.
Not verified
- Why two deploy paths (plugins vs Messagebus/x64) if identical — likely installer vs dev layout.
- Pipe naming convention and max concurrent clients.
- Hot reload of messagebus.conf without container restart.
Evidence
services/GSP/Messagebus/x64/NvMessageBusBroadcast.dll(MD5 matches plugins copy)services/GSP/Messagebus/x64/messagebus.conflogs/GSP/NvContainerGsp.logstringsextraction (IMessageBusBroadcastServer, cross-session strings)
NvMessageBusBroadcast.dll
What this program actually does
NvMessageBusBroadcast.dll is an NvContainer mandatory plugin (not a standalone EXE) that implements the cross-session NVIDIA Message Bus broadcast server. It reads messagebus.conf, creates named-pipe endpoints, and relays BusMessage protobuf packets between peers in different Windows sessions (SYSTEM services vs user streaming session).
Loaded by NvContainerGSP.exe at plugins/NvMessageBusBroadcast.dll. Version 3.22.3719.8856. Identical binary also deployed at Messagebus/x64/NvMessageBusBroadcast.dll.
Architecture / control flow
NvContainerGSP.exe
└─ NvMessageBusBroadcast.dll (plugin entry)
├─ IMessageBusBroadcastServer
├─ DefaultMessageBusConfig / FileMessageBusConfig
│ └─ reads messagebus.conf (JSON schema)
├─ PipeServer
│ ├─ CreateNamedPipeW — accept client connections
│ └─ PipeServerConnection — per-client IO
├─ Message routing
│ ├─ JOIN broadcast on peer connect
│ ├─ Session-aware delivery (ANY_SESSION, target session)
│ └─ CrossSessionPeers filter enforcement
└─ Logging → MessageBusBroadcast.logKey RTTI: IMessageBusBroadcastServer, IMessageBusConfig, DefaultMessageBusConfig, FileMessageBusConfig, PipeServer, PipeServerConnection, BusMessage_*.
External interfaces
Configuration file
messagebus.conf— JSON schema with:MessageBusPort,DefaultPeerConfig.AllowCrossSessionCommunicationPeers[]withAddress.SystemName/ModuleNameandCrossSessionPeers[]ACLs- Example: SSAU
AppSensor→ GCISUadPlugin/UadMLPlugin(SYSTEM user S-1-5-18)
Named pipes
| Component | API | Purpose |
|---|---|---|
PipeServer | CreateNamedPipeW | Listen for MessageBus client connections |
PipeServerConnection | Overlapped IO | Per-connection read/write |
| Client library | Connect to broadcast process | Pipe connected to Broadcast process %u |
BusMessage protobuf types
BusMessage.Peer, BusMessage.Generic, BusMessage.Status, BusMessage.EncryptedBusMessage, BusMessage.EncryptionSetup.
Role enforcement
SharedServicerole required for cross-session join notificationsPeer is not allowed to send message to non-default session— ACL violation
Runtime timeline
| Time (UTC) | Event | Source |
|---|---|---|
| 18:42:47.404 | DirectoryEnumerator processes messagebus.conf | NvContainerGsp.log |
| 18:42:47.474 | Secure-load NvMessageBusBroadcast (62 ms) | NvContainerGsp.log |
| 18:42:47.534 | Initialized → Started immediately (StartProcTime = 0) | NvContainerGsp.log |
| 18:42:48.189+ | Plugin NvMessageBusBroadcast received system message (peer join storm) | NvContainerGsp.log |
| 18:43:01 | Burst of system messages as GCIS plugins join bus | NvContainerGsp.log |
| 18:48:23–18:48:43 | Heavy system message activity during session start | NvContainerGsp.log |
| 19:04:52 | System messages as second GCIS attempt joins (then fails) | NvContainerGsp.log |
Broadcast server remained healthy throughout — GCIS failure was config-side, not bus-side.
Failure modes
| Error string | Meaning |
|---|---|
CreateNamedPipeW failed: %u | Pipe server cannot bind |
Failed to accept pipe connection | Client connect error |
OnPipeRead: received invalid protobuf packet | Corrupt bus message |
Peer is not allowed to send message to non-default session | Cross-session ACL deny |
without SharedService role! ... peer not receiving join notifications | Misconfigured peer role |
Failed to destroy PipeServerConnection / PipeServer | Cleanup errors on shutdown |
Not verified
- Exact pipe name pattern (likely seat-specific or port-derived from
MessageBusPort: 1). - Encryption setup handshake (
BusMessage.EncryptionSetup) key exchange details. - Whether broadcast plugin hot-reloads
messagebus.conf.
Evidence
strings/ RTTI onservices/GSP/plugins/NvMessageBusBroadcast.dllservices/GSP/plugins/messagebus.conflogs/GSP/NvContainerGsp.log- MD5 match with
services/GSP/Messagebus/x64/NvMessageBusBroadcast.dll
NvContainerNDC.exe
What it does
NvContainerNDC.exe is the Windows service host for NDC (NVIDIA Data Collector) on a GeForce NOW gameseat. It implements NVIDIA NvContainer v1.45, loads the optional _NdcPlugin.dll from services/NDC/plugins/, and manages plugin lifecycle: secure load → initialize → start → stop → unload.
Unlike sibling containers (e.g. GCIS), this host has dynamic plugin load/unload enabled and uses JsonFileStorage with _NdcPlugin.json (ModuleMap) instead of registry-only config. It does not implement capture policy itself; it is the process supervisor for the NDC plugin stack.
Architecture
Windows Service "NDC" (WIN32_OWN_PROCESS, PID 5608 in install log)
└─ NvContainer main v1.45
└─ nvc::ServiceHost / NvcServiceHost
└─ nvc::HostWin32 (dynamic plugin load/unload ENABLED)
└─ nvc::PluginManager
├─ JsonFileStorage (_NdcPlugin.json ModuleMap)
├─ Secure plugin load (NvcPluginLoadHel)
├─ DirectoryListenerWin32 (plugins/ hot-reload)
└─ State machine: Unloaded → Initializing → Initialized → Starting → StartedRTTI classes (deep extract): ServiceHost, HostWin32, PluginConfig, JsonFileStorage, MessageQueue, DirectoryListenerWin32, DefaultContainerConfig, DirectoryEnumerator.
Export: NvOptimusEnablement (sole export; Optimus-related; seat usage Not verified).
Build path (PDB string): C:\dvs\p4\build\sw\gcomp\rel\src\NvContainer\_out\x86_64\release\container\NvContainer.pdb
External interfaces
| Interface | Role |
|---|---|
Windows Service NDC | Created by NDC installer (logs/startup/ndcSoftwareInstall.log); stopped/removed via services/NDC/Uninstall.bat |
| Plugin directory | %AG_HOME%\services\NDC\plugins\ — loads _NdcPlugin.dll (optional) |
| ModuleMap JSON | plugins/_NdcPlugin.json maps NvMessageBus.dll path for plugin runtime |
| NvContainerLS junction | Uninstall.bat references %ProgramFiles%\NVIDIA Corporation\NvContainer\plugins\LocalSystem\NDC — install path Not verified in workspace |
| Logs | %AG_LOGS%\NDC\NvContainerNDC.log |
| DACL adjustment | On start: Created new DACL with added privileges 0x00100000 for child process (PID 5608) |
| Message bus | Indirect — _NdcPlugin uses NvMessageBus.dll from ModuleMap |
No direct network/RPC surface in this binary — all external I/O is via loaded plugins.
API table
| Function / component | Behavior |
|---|---|
NvcPluginManager::Load | Secure-load DLL, query NvPluginGetInfo, mark optional/mandatory |
Initiate transition to Initializing | Async plugin init; notification 1 = success |
Initiate transition to Starting | PluginStart task in plugin |
NvcPluginLoadStats | Per-plugin load/init/start timing telemetry |
DirectoryListenerWin32 | Watches plugins/ for add/remove (dynamic reload) |
JsonFileStorage | Loads _NdcPlugin.json ModuleMap before plugin secure-load |
Base host: mandatory plugin %s has failed. Exit | Fatal path for mandatory plugins (not triggered — plugin is optional) |
AllowDynamicPluginLoad / AllowDynamicPluginUnload | Enabled on NDC seat (Dynamic loading of plugins is enabled) |
Runtime from logs
Install (logs/startup/ndcSoftwareInstall.log)
| Time / event | Detail |
|---|---|
| Branch | 2026-4-29, commit 84989db54ca1897b315d85562b70f0dfd3edc824 |
| Files copied | _NdcPlugin.dll, PipsController.exe, NvContainerNDC.exe, NvMessageBus.dll |
| Service | NDC created (WIN32_OWN_PROCESS), PID 5608, START_PENDING |
Container boot (logs/NDC/NvContainerNDC.log)
| Time (local) | Event |
|---|---|
| 18:43:07.732 | Container main v1.45, telemetry API init |
| 18:43:07.733 | Dynamic plugin load/unload enabled |
| 18:43:07.735 | DACL adjusted for PID 5608 |
| 18:43:07.735 | Load plugins from C:\Asgard\services\NDC\plugins |
| 18:43:07.736 | JsonFileStorage loads _NdcPlugin.json |
| 18:43:07.858 | Secure-load _NdcPlugin.dll 1.0.0.0 (~98 ms) |
| 18:43:07.859 | Loaded optional plugin _NdcPlugin, version 1 |
| 18:43:07.859 | Directory listener on plugins\ started |
| 18:43:07.886 | Plugin Initialized (notification 1) |
| 18:43:07.886 | Service reports Running |
| 18:43:08.758 | Plugin Started (StartProcTime ~872 ms total) |
| 18:43:08.758 | Container started, state normal |
Plugin map: single optional _NdcPlugin — Active, Started.
Failure modes
| String / condition | Meaning |
|---|---|
Failed to load plugins. Exiting | Plugin directory load failure |
Failed to complete transition to Started | Plugin failed Starting phase |
Base host: mandatory plugin %s has failed. Exit | Fatal mandatory plugin failure |
Async state transition failure is detected for %s plugin | Plugin reported async failure |
Plugin count exceeded maximum allowed %u | Too many plugins configured |
Exit due to dynamic plugin load failure | Hot-reload of plugin failed |
Failed to allocate plugin entry for '%ls' | Plugin registry entry allocation failure |
Observed in snapshot: none — clean startup, service remained Running.
Evidence
| Source | Path |
|---|---|
| Container log | logs/NDC/NvContainerNDC.log |
| Plugin log | logs/NDC/_NdcPluginCurrent.log |
| Install log | logs/startup/ndcSoftwareInstall.log |
| Uninstall script | services/NDC/Uninstall.bat |
| ModuleMap | services/NDC/plugins/_NdcPlugin.json |
| readpe | PE32+ AMD64, 8 sections, entry 0x69740, timestamp 2025-05-07 |
Radare2 summary
| Item | Value |
|---|---|
| Format | PE32+ GUI x86-64, 1,342,496 bytes, signed |
| Export | NvOptimusEnablement (sole export) |
| Imports (notable) | FindFirstChangeNotificationW, CreateProcessW, Process32FirstW/NextW, vectored exception handlers, VirtualProtect |
| Strings | Full NvContainer plugin lifecycle messages; Container main v%s; dynamic load paths |
| Functions | entry0 only in filtered afl (no symbolized main) |
Not verified
- Exact NDC acronym expansion beyond log string "Nvidia Data Collector" (from
_NdcPluginlog). - Service install registry keys / SCM start type / service account.
- Whether NvContainerLS junction is created at install (referenced only in Uninstall.bat).
- Post-session container shutdown behavior (log ends at Running).
NvMessageBus.dll
What it does
NvMessageBus.dll is the NVIDIA Message Bus client library bundled with the NDC stack at services/NDC/NvMessageBus.dll. It provides the in-process transport for NvContainer plugins and child processes (_NdcPlugin, PipsController.exe) to register as named peers, send/receive protobuf-framed BusMessage packets, and connect to the seat-wide bus fabric (ultimately bridged by GSP's NvMessageBusBroadcast and mb-repeater).
The NDC copy is referenced via _NdcPlugin.json ModuleMap; GSP installs separate copies under services/GSP/Messagebus/ with symlinks to %ProgramFiles%\NVIDIA Corporation\NvContainer\.
Architecture
getMessageBusInterface[WithConfig]() / getSharedMessageBusInterface[WithConfig]()
└─ MessageBusImpl
├─ MessageBusInterface_v1 / v2 / v3 (RTTI)
├─ Config: FileMessageBusConfig / RegistryMessageBusConfig / DefaultMessageBusConfig
├─ Local transport: named pipes + IO completion ports
└─ Protobuf packet framing (validates non-empty, valid protobuf)Config schema (embedded JSON string): defines MessageBusPort, LogPath, LogLevel, LocalConnectionSuffix, peer filters (SystemName + ModuleName + AllowedUsers), cross-session options, log pruning, and PerSessionTransportDirectory.
Registry path (string): SOFTWARE\NVIDIA Corporation\NvContainer\MessageBus → MessageBusPort
Broadcaster pipe (string): \\.\pipe\NvMessageBusBroadcast
External interfaces
| Interface | Role |
|---|---|
| C exports | Factory/release for IMessageBus instances (see API table) |
| Named pipes | CreateFileW, ConnectNamedPipe, WaitNamedPipeW, IOCP |
| Registry | MessageBusPort and related NvContainer keys |
| Logs | MessageBus_<pid>.log, rotation via ClientLogSizeLimit |
| RPC UUIDs | UuidCreate / UuidToStringA for peer IDs |
| WS2_32 | Socket support for transport variants |
| NDC consumers | _NdcPlugin.dll (endpoint NDC:NdcPlugin); PipsController.exe waits for PIPS GSBE, Clover peers |
Relationship to GSP bus: GSP install creates symlinks from %ProgramFiles%\NVIDIA Corporation\NvContainer\NvMessageBus.dll to GSP's x64 build. NDC ships its own copy in services/NDC/ — byte-level diff vs GSP copy Not verified.
API table
| Export | Purpose |
|---|---|
generateMessageBusUniqueId | Generate unique bus identifier |
getMessageBusInterface | Create per-process MessageBus client |
getMessageBusInterfaceWithConfig | Create client with explicit config |
getSharedMessageBusInterface | Shared singleton client |
getSharedMessageBusInterfaceWithConfig | Shared client with config |
releaseMessageBusInterface | Release client instance |
Internal classes (RTTI / strings):
| Class | Role |
|---|---|
MessageBusImpl | Core client/server implementation |
MessageBusInterface_v1/v2/v3 | Versioned API surfaces |
DefaultMessageBusConfig | Default seat config |
FileMessageBusConfig | File-based config loader |
RegistryMessageBusConfig | Registry-based config loader |
Protobuf fields (strings): source_session, target_session, session, domain
Runtime from logs
Direct NvMessageBus.dll logs are not present in logs/NDC/ for this snapshot. Indirect runtime evidence:
| Source | Evidence |
|---|---|
_NdcPluginCurrent.log | Subscribed to Message Bus; GSConfigClient connects with 38 peers; TAS init via bus |
logs/GSP/NvContainerGsp.log | GSP loads NvMessageBusBroadcast.dll — seat bus broadcaster |
logs/GSP/GSConfiguratorPluginCurrent.log | NDC container (PID 5608) fetches NdcConfigData via GSConfigClient on bus |
logs/startup/gspSoftwareInstall.log | Symlinks GSP MessageBus DLLs to %ProgramFiles%\NVIDIA Corporation\NvContainer\ |
logs/startup/ndcSoftwareInstall.log | Copies NDC-local NvMessageBus.dll to services\NDC\ |
PipsController strings indicate runtime dependency: peers must join MessageBus within timeout or capture init fails (Not observed — PipsController never launched in snapshot).
Failure modes
| String | Meaning |
|---|---|
Cannot create an instance of MessageBusImpl | Factory/allocator failure |
MessageBusImpl: received an empty packet | Framing error |
MessageBusImpl: received invalid protobuf packet | Deserialization failure |
session id, error | Session routing failure |
Skipping obtaining process information for Broadcaster process | Security info disabled path |
Plugin-side bus failures (from _NdcPlugin strings, not observed at runtime):
| String | Meaning |
|---|---|
messageBus must be not null | Client not initialized before use |
Message to {}/{} failed. Error: {} | Send failure |
Failed to post NDC response, Error: {} | Response post failure |
Evidence
| Source | Path |
|---|---|
| Binary | services/NDC/NvMessageBus.dll (3,529,264 bytes) |
| ModuleMap | services/NDC/plugins/_NdcPlugin.json |
| readpe | PE32+ DLL AMD64, 7 sections, entry 0x21ba80, timestamp 2025-06-03 |
| strings | Embedded JSON config schema; MessageBusPort; pipe path |
| Plugin log | logs/NDC/_NdcPluginCurrent.log (bus subscription) |
| Install logs | logs/startup/ndcSoftwareInstall.log, logs/startup/gspSoftwareInstall.log |
Radare2 summary
| Item | Value |
|---|---|
| Format | PE32+ DLL GUI x86-64, 3,529,264 bytes, signed, stack canary |
| Exports | 6 (generateMessageBusUniqueId … releaseMessageBusInterface) |
| Imports (notable) | Named pipes, IOCP, RPC UUID, registry/file APIs, WS2_32 |
| Strings | Full MessageBus config JSON schema; NvMessageBus logging initialized; MessageBus Client version |
| PDB | C:\dvs\p4\build\sw\gcomp\dev\src\MessageBus\_build\X64\Release\messagebus\NvMessageBus.pdb |
Not verified
- Whether NDC processes load this copy vs the GSP symlinked
%ProgramFiles%copy at runtime. - Wire port number used by NDC peers on this seat (config not in workspace).
- Byte-level identity vs
services/GSP/Messagebus/x64/NvMessageBus.dll. - Direct MessageBus client log files (
MessageBus_*.log) — not captured inlogs/NDC/.
PipsController.exe
What it does
PipsController.exe is a native C++ console subprocess (16,029,296 bytes) deployed at services/NDC/PipsController/. _NdcPlugin.dll spawns it for GenericCapture configurations when session/CMS/user conditions match CSR allowlists.
It operates in two capture modes:
--pips— capture input/feature telemetry and relay to PIPS GSBE over Message Bus + gRPC (SsiDataSink).--file— write captured payloads to a seat file (e.g.C:\ProgramData\NVIDIA\user-input.json) with optional RSA encryption.
Duration is capped by -duration (21600 s = 6 h in observed CSR configs). In this snapshot PipsController was never launched — active session CMS/user IDs did not match configured allowlists.
PDB (strings): C:\builds\gfn\security\ndc\out\x64-windows-release\PipsController\PipsController.pdb
Architecture
main (CLI11 / Poco)
└─ PipsController
├─ SsiDataSinkServer — gRPC service: /SsiDataSink/sendData
├─ StreamCaptureController — Start/Stop/Pause/Resume (protobuf)
├─ MessageBusClient — waits for PIPS GSBE, Clover peers
├─ PipsControllerTelemetry — TAS connector
├─ PipsControllerTasConnector
└─ spdlog → PipsController.logProtobuf types (strings):
| Proto / message | Role |
|---|---|
SsiDataSink.proto | VSsiMessage, SsiResponse, PIPSDataMessage, PIPSAggregateMessage |
SsiStreamCaptureControllerDef.proto | StreamCaptureRequest/Response, Start/Stop/Pause/Resume payloads |
StreamCaptureControlMessage | Capture control envelope |
gRPC stack: grpc++ 1.71 (vcpkg x64-windows-v143-static-mt); build paths under C:\builds\gfn\security\ndc\out\.
Default capture path (string): Capture via gRPC relay to PIPS GSBE (default)
External interfaces
| Interface | Role |
|---|---|
| Parent process | _NdcPlugin.dll via CreateProcessW with assembled GenericCapture command line |
| CLI | --pips, --file, -duration, -grpc-port, -fi/--flush-interval |
| gRPC server | SsiDataSinkServer on configurable port [1024, 65535] |
| gRPC client | Start/Stop capture requests to remote {}:{} peers |
| Message Bus | Posts aggregate messages to PIPS GSBE; requires Clover + PIPS peers within timeout |
| File I/O | --file mode writes to CSR-specified path; reads file:///C:/ProgramData/NVIDIA/user-input.json |
| Logs | PipsController.log (string); parent logs stdout to commandOnStartCaptureOutput.log / commandOnStopCaptureOutput.log |
Observed remote PIPS peers (mb-repeater / Smithy logs): PIPS:PIPS, PIPS:PIPS-InputFeatures, PIPS:PIPSTasConnector, PIPS:PIPSAnybrainTasConnector — seat join details Not verified for NDC spawn (no launch in snapshot).
API table
| Symbol / component | Type | Notes |
|---|---|---|
main | Function | Entry; r2 afl at 0x140040a80 (~14k bytes) |
| (none) | Exports | No DLL exports — standalone EXE |
SsiDataSinkServer | gRPC service | /SsiDataSink/sendData |
StreamCaptureControllerMessage | Protobuf | Start/Stop/Pause/Resume |
PIPSAggregateMessage.capture_id | Protobuf field | Aggregate telemetry envelope |
PipsController::Start | Method | Init; failure → PipsController::Start failed during initialization |
SendStopCapture | Method | Requires non-empty capture ID |
CLI -p,--pips | Flag | PIPS relay mode |
CLI --file | Flag | File capture mode |
CLI -grpc-port | Flag | gRPC server port (with --pips) |
| CLI capture duration | Flag | Capture duration in seconds |
Runtime from logs
Install (logs/startup/ndcSoftwareInstall.log)
Copy PipsController contents to C:\Asgard\services\NDC\PipsController
.\PipsController\PipsController.exe
1 File(s) copiedOrchestration (logs/NDC/_NdcPluginCurrent.log)
Config parsed at boot (18:43:08):
| Config | Command line (from log) |
|---|---|
| CMS allowlist (~90 IDs) | PipsController.exe --pips -duration 21600 echo GenericCapture: CommandOnStopCapture xen false false |
| User allowlist #1 | PipsController.exe --file -duration 21600 echo … C:\ProgramData\NVIDIA\user-input.json true (encrypted) |
| User allowlist #2 | Same --file template with encryption cert loaded |
Session evaluation (18:48:43) — no spawn:
| Field | Value |
|---|---|
| Session ID | [REDACTED_SESSION_ID] |
| User ID | [REDACTED_USER_ID] |
| CMS IDs seen | [REDACTED_CMS_ID], 100207711, 18761111, 100192311 |
| Outcome | Capture is not configured for CMS IDs = … and Capture is not configured for user IDs = … |
Conclusion: Binaries and triggers ready; no CreateProcessW for PipsController in this log window.
Failure modes
| String | Condition |
|---|---|
PipsController::Start failed during initialization | Startup failure |
PIPS GSBE peer ({}:{}) did not join MessageBus within {} seconds | Bus peer timeout |
Clover peer ({}:{}) did not join MessageBus within {} seconds | Clover plugin timeout |
Failed to start gRPC data sink server on port {} | gRPC bind failure |
Cannot flush SSI data to PIPS GSBE: MessageBus not available | Bus unavailable at flush |
Failed to post aggregate message to PIPS GSBE ({}:{}): {} | Bus send failure |
StartCapture request to {}:{} failed with error_code={} | Remote start failure |
StopCapture request to {}:{} failed with error_code={} | Remote stop failure |
SendStopCapture called with empty capture ID | Invalid stop call |
Protobuf serialization of aggregate message failed, capture_id={} | Serialize error |
PIPS_CONTROLLER_UNKNOWN_WARNING | Telemetry warning bucket |
SsiDataSinkServer: port must be in range [1024, 65535], got | Invalid port |
Parent-side failures (_NdcPlugin strings, not observed for PipsController):
| String | Condition |
|---|---|
Failed to execute command: {} | CreateProcess failure |
commandOnStartCapture terminated gracefully / forcing termination | Stop-capture cleanup |
Evidence
| Source | Path |
|---|---|
| Binary | services/NDC/PipsController/PipsController.exe |
| readpe | PE32+ console AMD64, 7 sections, entry 0xa4df40, signed, timestamp 2026-04-30 |
| strings | PIPS, gRPC, SsiDataSink, CLI flags, MessageBus peer names |
| Plugin log | logs/NDC/_NdcPluginCurrent.log (command templates, no spawn) |
| Install log | logs/startup/ndcSoftwareInstall.log |
Radare2 summary
| Item | Value |
|---|---|
| Format | PE32+ console x86-64, 16,029,296 bytes, signed |
| Exports | None |
| Entry | entry0 @ 0x140a4df40 → jumps to init |
main | 0x140040a80 (362 blocks, ~14k bytes) |
| Imports (notable) | CreateProcessW, file I/O, console, synchronization, OutputDebugStringW |
| Strings | PIPS, gRPC 1.71 paths, CloverCapturePlugin, Forward SSI stream to PIPS, CLI help text |
Not verified
- Default
-grpc-portnumeric value. - Kernel vs user-mode capture mechanism for
--pips. - Exact bind address for
SsiDataSinkServerwhen run as NDC child. - Runtime
PipsController.log— not present inlogs/NDC/(process never started). - Post-capture file upload / TAS payload contents.
_NdcPlugin.dll
What it does
_NdcPlugin.dll is the NVIDIA Data Collector (NDC) NvContainer plugin loaded by NvContainerNDC.exe. Log banner: Welcome to the re-written Nvidia Data Collector!
It orchestrates conditional telemetry capture on a gameseat:
- Fetches
NdcConfigDatafrom GSConfigurator via GSConfigClient. - Parses
CaptureConfigurations(GenericCapture,NetworkCapturesymbols present). - Evaluates conditions (CMS IDs, user IDs, percentage rollout, session/VM time windows).
- Spawns
PipsController.exewhen conditions match at session start. - Registers on Message Bus as
NDC:NdcPlugin, subscribes to AIN (app install) and session lifecycle messages. - Initializes TAS (Telemetry Aggregator Service) with schema
gfn-team.open.ndc-test:1.
Version: 1.0.0.0 (optional plugin). Export: NvPluginGetInfo.
Architecture
NvPluginGetInfo → NvContainer plugin host
└─ NdcPluginTaskQueue (deferred tasks)
├─ PluginInitialization
│ ├─ MessageBus subscribe (endpoint NdcPlugin)
│ └─ AIN subscription via Content Controller (CC)
└─ PluginStart
├─ TAS init (GameseatTelemetry → TelemetryAggregator:SeatConnector)
├─ GSConfigClient → NdcConfigData
├─ NdcGenericCapture / NdcNetworkDataCollector parsers
├─ NdcCondition evaluator
├─ NdcCrypto (RSA encryption for --file captures)
└─ CreateProcessW → PipsController.exe (on match)Log component tags: NdcPlugin, NdcPluginTaskQue, NdcDeferredTaskQ, NdcGenericCaptur, NdcCondition, NdcCrypto, GameseatTelemetr, GSConfigClientUt.
Protobuf namespaces (deep extract): NdcServiceAPI, GsServiceApi, GCISCommunication, ContentControllerAPI, NVIDIA.Bifrost.*.
Framework: Poco, protobuf, OpenSSL/crypto (RSA-SHA3, RSASSA-PSS), MessageBusClient v3, GSConfigClient (gsprerequisites).
External interfaces
| Interface | Role |
|---|---|
| NvContainer host | Loaded by NvContainerNDC.exe; lifecycle Init/Start/Stop via deferred task queue |
| GSConfigurator | Config key NdcConfigData (CSR); fetched at PluginStart |
| Message Bus | Endpoint NDC:NdcPlugin; ModuleMap loads NvMessageBus.dll from _NdcPlugin.json |
| Content Controller (CC) | AIN (App Install Notification) subscription; ContentController messages ignored at runtime |
CtMT (nvctmtsvc.exe) | Delivers app-install notifications; plugin posts Notify::AppInstall ACKs |
| GsServiceApi | Session ID + user ID for condition matching |
| TAS | TelemetryAggregator:SeatConnector:0 — init protobuf with serviceName: "NDC", resourceName: "gfn-team.open.ndc" |
| PipsController.exe | GenericCapture subprocess (--pips / --file) |
| Logs | %AG_LOGS%\NDC\_NdcPluginCurrent.log; capture stdout → commandOnStartCaptureOutput.log, commandOnStopCaptureOutput.log |
ModuleMap (_NdcPlugin.json):
{ "ModuleMap\\NvMessageBus.dll": "C:\\Asgard\\services\\NDC\\NvMessageBus.dll" }Message bus config path (string): C:/Program Files/NVIDIA Corporation/NvContainer/plugins/LocalSystem/messagebus.conf
API table
| Symbol / task | Type | Notes |
|---|---|---|
NvPluginGetInfo | Export | Standard NvContainer plugin entry; r2 @ 0x18019b970 |
PluginInitialization | Deferred task | Bus subscribe + AIN CC subscription |
PluginStart | Deferred task | TAS init, config fetch, capture setup |
PluginStop | Deferred task | String present; stop path Not verified in logs |
NdcServiceAPI | Protobuf domain | NDC service messages (handler strings) |
GsServiceApi | Protobuf domain | Session/user identification |
GenericCaptureConfig.* | CSR fields | CommandOnStartCapture, CommandOnStopCapture, User, RestartUponCrash, CapturedFile, EncryptCapture, EncryptionKey |
NetworkCaptureControl | Component | Start/stop network capture via NCC (symbols only; not in CSR snapshot) |
Notify::AppInstall | Bus message | Posted when CMS IDs added from CtMT |
| TAS init request | Protobuf | serviceName: "NDC", schemaId: "gfn-team.open.ndc-test:1" |
GenericCapture CSR command template (log-assembled):
<PipsController.exe> <mode> -duration <sec> <CommandOnStartCapture> <CommandOnStopCapture> <User> <EncryptCapture> [<CapturedFile>] [<EncryptFile>]Runtime from logs
Container load (logs/NDC/NvContainerNDC.log)
| Time | Event |
|---|---|
| 18:43:07.858 | Secure-load 1.0.0.0 (~98 ms), optional plugin |
| 18:43:07.886 | Initialized |
| 18:43:08.758 | Started (StartTimeTotal ~872 ms) |
Plugin boot (logs/NDC/_NdcPluginCurrent.log)
| Time | Event |
|---|---|
| 18:43:07.885 | Module _NdcPlugin, MB-endpoint NdcPlugin |
| 18:43:07.885 | Subscribed to Message Bus |
| 18:43:07.886 | AIN subscription posted to CC → success |
| 18:43:07.887 | Attemping to initialize NDC <---> TAS |
| 18:43:07.908 | TAS peer visibility; init protobuf sent |
| 18:43:08.491 | Welcome to the re-written Nvidia Data Collector! |
| 18:43:08.744 | NdcConfigData fetched; 3 CaptureConfigurations, 3 conditions loaded |
| 18:43:08.750 | Config 1: CMS allowlist, --pips, session time [0–21610], percentage 100 |
| 18:43:08.753 | Config 2–3: user allowlists, --file → user-input.json, RSA cert loaded (451-byte key) |
| 18:43:08.758 | PluginStart finished |
Session runtime
| Time | Event |
|---|---|
| 18:43:08–18:48:23 | Ignore ContentController message (repeated) |
| 18:48:23.507 | Session ID [REDACTED_SESSION_ID], user [REDACTED_USER_ID] |
| 18:48:40.587–41.737 | CMS IDs added: 18761111, 100192311, [REDACTED_CMS_ID], 100207711; Posting Notify::AppInstall response |
| 18:48:43.114 | Session is starting → Capture is not configured (CMS + user mismatch) |
CtMT (logs/AutoOnboarder/ctmt.log)
| Time | Event |
|---|---|
| 18:43:07.887 | Subscribe request from NDC:NdcPlugin |
| 18:48:40–41 | Notify/ack cycles for app install notifications |
GSConfigurator (logs/GSP/GSConfiguratorPluginCurrent.log)
GetConfiguration … Services=["NDC"] Exe='c:\asgard\services\ndc\nvcontainerndc.exe' | config='NdcConfigData'Failure modes
| String / condition | Meaning |
|---|---|
Failed to open NDC Service Config, exiting. | GSConfigurator config fetch failure |
Failed to parse config. Error {} | CSR parse error |
Invalid Capture Configuration Type {}, skipping | Unknown capture type |
Failed to load encryption certificate. | RSA cert parse failure |
Failed to execute command: {} | PipsController spawn failure |
Failed to encrypt file: {} | Post-capture encryption failure |
NetworkCaptureControl returned an error | Network capture path failure (Not observed) |
START_CAPTURE_FAILED / STOP_CAPTURE_FAILED | Network capture control errors |
Null parameters received from NvContainer during plugin initialization | Host init contract violation |
Capture is not configured for CMS IDs = … | Condition mismatch (observed) |
Capture is not configured for user IDs = … | Condition mismatch (observed) |
Session range is invalid | Time window config error |
Mandatory plugin failure: N/A — plugin marked optional; container would not exit on plugin failure.
Evidence
| Source | Path |
|---|---|
| Binary | services/NDC/plugins/_NdcPlugin.dll (13,304,944 bytes) |
| ModuleMap | services/NDC/plugins/_NdcPlugin.json |
| readpe | PE32+ DLL AMD64, 7 sections, signed, timestamp 2026-04-30 |
| strings | NdcPlugin, GenericCapture, NetworkCapture, Bifrost, crypto, CreateProcessW |
| Plugin log | logs/NDC/_NdcPluginCurrent.log |
| Container log | logs/NDC/NvContainerNDC.log |
| CtMT log | logs/AutoOnboarder/ctmt.log |
| GSConfigurator log | logs/GSP/GSConfiguratorPluginCurrent.log |
| Install log | logs/startup/ndcSoftwareInstall.log |
Radare2 summary
| Item | Value |
|---|---|
| Format | PE32+ DLL GUI x86-64, 13,304,944 bytes, signed, stack canary |
| Export | NvPluginGetInfo @ 0x18019b970 |
| Imports (notable) | CreateProcessW, CreateProcessAsUserW/A, CRYPT32, WS2_32, dbghelp, IPHLPAPI |
| Strings | Welcome to the re-written Nvidia Data Collector!; GenericCapture/NetworkCapture; Bifrost protobuf types; log paths under C:\Asgard\logs\NDC\ |
| PDB | C:\builds\gfn\security\ndc\out\x64-windows-release\NdcPlugin\NdcPlugin.pdb |
Not verified
NetworkCaptureconfiguration type — symbols present; onlyGenericCaptureobserved in CSR/logs.- Exact protobuf schemas for
NdcServiceAPIrequest/response fields. - Capture stop/teardown on session end (no session-end log in snapshot).
- Whether
--pipscapture would succeed if conditions matched (PipsController never spawned). - Full list of ContentController message types (all ignored in sampled runtime).