From 3086bd25ea2883c0ac7a550684f1684e1ce64bff Mon Sep 17 00:00:00 2001 From: lakhantheboss <61951686+lakhantheboss@users.noreply.github.com> Date: Fri, 23 Oct 2026 20:38:24 +0530 Subject: [PATCH 1/4] fix(libSceNpGameIntent): return error for invalid arguments Return NpGameIntentErrorInvalidArgument (0x80550004) instead of throwing APS5_INVALID_ARG_EX when invalid arguments are passed to sceNpGameIntentGetPropertyValueString or sceNpGameIntentReceiveIntent. Add regression test coverage in GuestNpGameIntent. --- core/libs/prx/libSceNpGameIntent/Export.cpp | 4 ++-- core/libs/tests/GuestNpGameIntent.cpp | 10 ++++++++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/core/libs/prx/libSceNpGameIntent/Export.cpp b/core/libs/prx/libSceNpGameIntent/Export.cpp index 751b4b1c5b..783411faca 100644 --- a/core/libs/prx/libSceNpGameIntent/Export.cpp +++ b/core/libs/prx/libSceNpGameIntent/Export.cpp @@ -19,7 +19,7 @@ extern "C" { int APS5_VABI sceNpGameIntentGetPropertyValueString(const NpGameIntentData* intentData, const char* key, char* valueBuf, size_t bufSize) { if (intentData == nullptr || key == nullptr || valueBuf == nullptr || bufSize == 0) { - APS5_INVALID_ARG_EX; + return NpGameIntentErrorInvalidArgument; } valueBuf[0] = '\0'; @@ -33,7 +33,7 @@ int APS5_VABI sceNpGameIntentInitialize(const void* initParam) { int APS5_VABI sceNpGameIntentReceiveIntent(NpGameIntentInfo* intentInfo) { if (intentInfo == nullptr) { - APS5_INVALID_ARG_EX; + return NpGameIntentErrorInvalidArgument; } intentInfo->user_id = NpGameIntentUserIdInvalid; diff --git a/core/libs/tests/GuestNpGameIntent.cpp b/core/libs/tests/GuestNpGameIntent.cpp index dd362cdad4..3ffb412f14 100644 --- a/core/libs/tests/GuestNpGameIntent.cpp +++ b/core/libs/tests/GuestNpGameIntent.cpp @@ -23,6 +23,7 @@ static bool Throws(TCall call) { } int main() { + constexpr int kInvalidArgument = -2141898748; constexpr int kIntentNotFound = -2141898746; constexpr int kValueNotFound = -2141898745; @@ -42,9 +43,18 @@ int main() { Require(info.user_id == -1, "info user_id mismatch"); Require(sceNpGameIntentInitialize(&initParam) == 0, "initialization failed"); + Require(sceNpGameIntentReceiveIntent(nullptr) == kInvalidArgument, "null receive intent did not fail"); Require(sceNpGameIntentReceiveIntent(&info) == kIntentNotFound, "receive intent mismatch"); char buf[64]{}; + Require(sceNpGameIntentGetPropertyValueString(nullptr, "key", buf, sizeof(buf)) == kInvalidArgument, + "null intent data did not fail"); + Require(sceNpGameIntentGetPropertyValueString(&info.intent_data, nullptr, buf, sizeof(buf)) == kInvalidArgument, + "null key did not fail"); + Require(sceNpGameIntentGetPropertyValueString(&info.intent_data, "key", nullptr, sizeof(buf)) == kInvalidArgument, + "null value buf did not fail"); + Require(sceNpGameIntentGetPropertyValueString(&info.intent_data, "key", buf, 0) == kInvalidArgument, + "zero buf size did not fail"); Require(sceNpGameIntentGetPropertyValueString(&info.intent_data, "key", buf, sizeof(buf)) == kValueNotFound, "get property value mismatch"); From d0269109d5e184a3be80fb6b6f3ad5d17657cb13 Mon Sep 17 00:00:00 2001 From: lakhantheboss <61951686+lakhantheboss@users.noreply.github.com> Date: Sat, 24 Oct 2026 12:52:39 +0530 Subject: [PATCH 2/4] test(libSceNpGameIntent): remove obsolete app launcher throw assertion --- core/libs/tests/GuestNpGameIntent.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/core/libs/tests/GuestNpGameIntent.cpp b/core/libs/tests/GuestNpGameIntent.cpp index 3ffb412f14..6e326bb65e 100644 --- a/core/libs/tests/GuestNpGameIntent.cpp +++ b/core/libs/tests/GuestNpGameIntent.cpp @@ -65,8 +65,6 @@ int main() { unsigned char appLauncherParam[0x28]{}; *reinterpret_cast(appLauncherParam) = 0x28; Require(sceNpAppLauncherInitialize(appLauncherParam) == 0, "app launcher init failed"); - Require(Throws([] { sceNpAppLauncherLaunchApp(); }), - "app launcher launch must throw until implemented"); Require(sceNpAppLauncherTerminate() == 0, "app launcher terminate failed"); *reinterpret_cast(appLauncherParam) = 0x10; Require(sceNpAppLauncherInitialize(appLauncherParam) == 0, From b08f1f0234be1947ea113aaffa5fe3a05fb37540 Mon Sep 17 00:00:00 2001 From: lakhantheboss <61951686+lakhantheboss@users.noreply.github.com> Date: Sun, 25 Oct 2026 18:52:51 +0530 Subject: [PATCH 3/4] fix(libSceNpGameIntent): return errors for invalid arguments and uninitialized calls --- core/libs/prx/libSceNpGameIntent/Export.cpp | 45 ++++++++++++------ core/libs/tests/GuestNpGameIntent.cpp | 52 ++++++++++++++++++++- docs/dev/debt/libSceNpGameIntent.md | 7 +-- 3 files changed, 84 insertions(+), 20 deletions(-) diff --git a/core/libs/prx/libSceNpGameIntent/Export.cpp b/core/libs/prx/libSceNpGameIntent/Export.cpp index 783411faca..dfea590bc3 100644 --- a/core/libs/prx/libSceNpGameIntent/Export.cpp +++ b/core/libs/prx/libSceNpGameIntent/Export.cpp @@ -1,4 +1,5 @@ #include "prx/libSceNpGameIntent/include/Api.hpp" +#include #include #include #include @@ -8,43 +9,57 @@ namespace { +constexpr int NpGameIntentErrorNotInitialized = -2141898750; constexpr int NpGameIntentErrorInvalidArgument = -2141898748; constexpr int NpGameIntentErrorIntentNotFound = -2141898746; constexpr int NpGameIntentErrorValueNotFound = -2141898745; constexpr int NpGameIntentUserIdInvalid = -1; +std::atomic_bool& NpGameIntentInitialized() { + static std::atomic_bool initialized{false}; + return initialized; +} + } extern "C" { int APS5_VABI sceNpGameIntentGetPropertyValueString(const NpGameIntentData* intentData, const char* key, char* valueBuf, size_t bufSize) { - if (intentData == nullptr || key == nullptr || valueBuf == nullptr || bufSize == 0) { - return NpGameIntentErrorInvalidArgument; - } + if (!NpGameIntentInitialized()) { + return NpGameIntentErrorNotInitialized; + } + if (intentData == nullptr || key == nullptr || key[0] == '\0' || valueBuf == nullptr || bufSize == 0) { + return NpGameIntentErrorInvalidArgument; + } - valueBuf[0] = '\0'; - return NpGameIntentErrorValueNotFound; + valueBuf[0] = '\0'; + return NpGameIntentErrorValueNotFound; } int APS5_VABI sceNpGameIntentInitialize(const void* initParam) { - (void)initParam; - return 0; + (void)initParam; + NpGameIntentInitialized() = true; + return 0; } int APS5_VABI sceNpGameIntentReceiveIntent(NpGameIntentInfo* intentInfo) { - if (intentInfo == nullptr) { - return NpGameIntentErrorInvalidArgument; - } + if (!NpGameIntentInitialized()) { + return NpGameIntentErrorNotInitialized; + } + if (intentInfo == nullptr || intentInfo->size != 0x4140) { + return NpGameIntentErrorInvalidArgument; + } - intentInfo->user_id = NpGameIntentUserIdInvalid; - std::memset(intentInfo->intent_type, 0, sizeof(intentInfo->intent_type)); - std::memset(&intentInfo->intent_data, 0, sizeof(intentInfo->intent_data)); + intentInfo->user_id = NpGameIntentUserIdInvalid; + std::memset(intentInfo->intent_type, 0, sizeof(intentInfo->intent_type)); + std::memset(&intentInfo->intent_data, 0, sizeof(intentInfo->intent_data)); - return NpGameIntentErrorIntentNotFound; + return NpGameIntentErrorIntentNotFound; } int APS5_VABI sceNpGameIntentTerminate(void) { - return 0; + NpGameIntentInitialized() = false; + return 0; } int APS5_VABI sceNpGameIntentInitParamInit(NpGameIntentInitParam* param) { diff --git a/core/libs/tests/GuestNpGameIntent.cpp b/core/libs/tests/GuestNpGameIntent.cpp index 6e326bb65e..8e74607008 100644 --- a/core/libs/tests/GuestNpGameIntent.cpp +++ b/core/libs/tests/GuestNpGameIntent.cpp @@ -4,6 +4,7 @@ #include #include +#include #include static void Require(bool value, const char* what) { @@ -23,6 +24,7 @@ static bool Throws(TCall call) { } int main() { + constexpr int kNotInitialized = -2141898750; constexpr int kInvalidArgument = -2141898748; constexpr int kIntentNotFound = -2141898746; constexpr int kValueNotFound = -2141898745; @@ -42,26 +44,72 @@ int main() { Require(info.size == sizeof(NpGameIntentInfo), "info size mismatch"); Require(info.user_id == -1, "info user_id mismatch"); + char preBuf[64]{}; + Require(sceNpGameIntentGetPropertyValueString(nullptr, "key", preBuf, sizeof(preBuf)) == kNotInitialized, + "uninitialized get property string with null data must report not-initialized"); + Require(sceNpGameIntentGetPropertyValueString(&info.intent_data, "key", preBuf, sizeof(preBuf)) == kNotInitialized, + "uninitialized get property string with valid data must report not-initialized"); + Require(sceNpGameIntentReceiveIntent(nullptr) == kNotInitialized, + "uninitialized receive intent with null pointer must report not-initialized"); + Require(sceNpGameIntentReceiveIntent(&info) == kNotInitialized, + "uninitialized receive intent with valid pointer must report not-initialized"); + Require(sceNpGameIntentInitialize(&initParam) == 0, "initialization failed"); Require(sceNpGameIntentReceiveIntent(nullptr) == kInvalidArgument, "null receive intent did not fail"); - Require(sceNpGameIntentReceiveIntent(&info) == kIntentNotFound, "receive intent mismatch"); + Require(sceNpGameIntentReceiveIntent(&info) == kInvalidArgument, "mismatched struct size must report invalid argument"); + info.size = 0; + Require(sceNpGameIntentReceiveIntent(&info) == kInvalidArgument, "zero size must report invalid argument"); + info.size = 0x413f; + Require(sceNpGameIntentReceiveIntent(&info) == kInvalidArgument, "0x413f size must report invalid argument"); + info.size = 0x4141; + Require(sceNpGameIntentReceiveIntent(&info) == kInvalidArgument, "0x4141 size must report invalid argument"); + info.size = sizeof(NpGameIntentInfo); char buf[64]{}; Require(sceNpGameIntentGetPropertyValueString(nullptr, "key", buf, sizeof(buf)) == kInvalidArgument, "null intent data did not fail"); Require(sceNpGameIntentGetPropertyValueString(&info.intent_data, nullptr, buf, sizeof(buf)) == kInvalidArgument, "null key did not fail"); + Require(sceNpGameIntentGetPropertyValueString(&info.intent_data, "", buf, sizeof(buf)) == kInvalidArgument, + "empty key did not fail"); Require(sceNpGameIntentGetPropertyValueString(&info.intent_data, "key", nullptr, sizeof(buf)) == kInvalidArgument, "null value buf did not fail"); Require(sceNpGameIntentGetPropertyValueString(&info.intent_data, "key", buf, 0) == kInvalidArgument, "zero buf size did not fail"); - Require(sceNpGameIntentGetPropertyValueString(&info.intent_data, "key", buf, sizeof(buf)) == kValueNotFound, + + char canaryBuf[64]{}; + std::memset(canaryBuf, 'X', sizeof(canaryBuf)); + Require(sceNpGameIntentGetPropertyValueString(&info.intent_data, "key", canaryBuf, 0) == kInvalidArgument, + "zero buf size canary call did not fail"); + Require(canaryBuf[0] == 'X', "buffer was modified on zero size error"); + Require(sceNpGameIntentGetPropertyValueString(nullptr, "key", canaryBuf, sizeof(canaryBuf)) == kInvalidArgument, + "null data canary call did not fail"); + Require(canaryBuf[0] == 'X', "buffer was modified on null data error"); + Require(sceNpGameIntentGetPropertyValueString(&info.intent_data, nullptr, canaryBuf, sizeof(canaryBuf)) == kInvalidArgument, + "null key canary call did not fail"); + Require(canaryBuf[0] == 'X', "buffer was modified on null key error"); + Require(sceNpGameIntentGetPropertyValueString(&info.intent_data, "", canaryBuf, sizeof(canaryBuf)) == kInvalidArgument, + "empty key canary call did not fail"); + Require(canaryBuf[0] == 'X', "buffer was modified on empty key error"); + + Require(sceNpGameIntentGetPropertyValueString(&info.intent_data, "key", canaryBuf, sizeof(canaryBuf)) == kValueNotFound, "get property value mismatch"); + Require(canaryBuf[0] == '\0', "valid call did not write terminator"); + + canaryBuf[0] = 'Y'; + Require(sceNpGameIntentGetPropertyValueString(&info.intent_data, "key", canaryBuf, 1) == kValueNotFound, + "bufSize 1 did not succeed"); + Require(canaryBuf[0] == '\0', "bufSize 1 did not write terminator"); Require(sceNpGameIntentVshInitialize() == 0, "vsh init failed"); Require(sceNpGameIntentVshTerminate() == 0, "vsh terminate failed"); Require(sceNpGameIntentTerminate() == 0, "terminate failed"); + Require(sceNpGameIntentGetPropertyValueString(&info.intent_data, "key", buf, sizeof(buf)) == kNotInitialized, + "post-terminate get property value must report not-initialized"); + Require(sceNpGameIntentReceiveIntent(&info) == kNotInitialized, + "post-terminate receive intent must report not-initialized"); + unsigned char appLauncherParam[0x28]{}; *reinterpret_cast(appLauncherParam) = 0x28; Require(sceNpAppLauncherInitialize(appLauncherParam) == 0, "app launcher init failed"); diff --git a/docs/dev/debt/libSceNpGameIntent.md b/docs/dev/debt/libSceNpGameIntent.md index 622b40a2c2..8476d2c449 100644 --- a/docs/dev/debt/libSceNpGameIntent.md +++ b/docs/dev/debt/libSceNpGameIntent.md @@ -2,11 +2,12 @@ ### Silent stubs -- [sceNpGameIntentVshInitialize, sceNpGameIntentVshTerminate](../../../core/libs/prx/libSceNpGameIntent/Export.cpp) (libSceNpGameIntent) - VSH initialization and termination return 0 without performing shell operations, matching `sceNpGameIntentInitialize` and `sceNpGameIntentTerminate` -- [sceNpAppLauncherInitialize, sceNpAppLauncherTerminate](../../../core/libs/prx/libSceNpGameIntent/Export.cpp) (libSceNpGameIntent) - app-launcher lifecycle returns success without tracking launch state; `sceNpAppLauncherInitialize` accepts its init parameter without validation, following the silent-stub precedent of `sceNpGameIntentInitialize` — a title calls it early in boot, and returning success lets it continue +- [sceNpGameIntentVshInitialize, sceNpGameIntentVshTerminate](../../../core/libs/prx/libSceNpGameIntent/Export.cpp) (libSceNpGameIntent) - VSH initialization and termination return 0 without performing shell operations +- [sceNpAppLauncherInitialize, sceNpAppLauncherTerminate](../../../core/libs/prx/libSceNpGameIntent/Export.cpp) (libSceNpGameIntent) - app-launcher lifecycle returns success without tracking launch state; `sceNpAppLauncherInitialize` accepts its init parameter without validation — a title calls it early in boot, and returning success lets it continue ### Unknown function info +- [sceNpGameIntentReceiveIntent, sceNpGameIntentGetPropertyValueString](../../../core/libs/prx/libSceNpGameIntent/Export.cpp) (libSceNpGameIntent) - firmware 13.42 emulator traces report `0x80553802` when called before `sceNpGameIntentInitialize` (precedence over argument validity), and `0x80553804` for invalid arguments (null pointer, empty key, or zero buffer size); `sceNpGameIntentTerminate` resetting the initialization state is modeled lifecycle behavior rather than independently hardware-verified. `sceNpGameIntentReceiveIntent` reportedly requires `info->size == 0x4140` on firmware 13.42, while the current AnyPS5 `NpGameIntentInfo` is `0x560` bytes (matching fpPS4) and `sceNpGameIntentInfoInit` sets that size. Consequently, an object initialized by the current helper is rejected by the receiver's measured size guard. The complete retail layout, its output field offsets, and the retail behavior of `sceNpGameIntentInfoInit` have not been verified, and expanding the type with unverified reserved bytes is not an evidence-backed solution. - [sceNpAppLauncherLaunchApp, sceNpGameIntentGetUdsNpComId, sceNpGameIntentLaunchApp, sceNpGameIntentLaunchApp2, sceNpGameIntentNotifyAppLaunched, sceNpSessionServiceGetJoinedPartySession, sceNpSessionServiceGetRunningGamePlayerSession and sceNpSessionServiceSendPlayerSessionInvitations](../../../core/libs/prx/libSceNpGameIntent/Export.cpp) (libSceNpGameIntent) - names and NIDs are present in the [PS5 3.20 export inventory](https://github.com/DNNDHH/PS5-3.20_Libs/blob/b2a77c09cd71c01f34c790cfbe98c751a13262ad/libSceNpGameIntent.c). Call sites in a title's executable give a partial prototype: `sceNpAppLauncherLaunchApp` takes `(user_id, uri struct, context)` and returns int — throws because no launcher-service semantics are derivable. The rest are declared without parameters solely to resolve known imports and make no ABI claim. - [sceNpGameIntentInitParamInit](../../../core/libs/prx/libSceNpGameIntent/Export.cpp) (libSceNpGameIntent) - struct layout matches [fpPS4](https://github.com/red-prig/fpPS4/blob/master/src/np/ps4_libscenpgameintent.pas#L17) `SceNpGameIntentInitParam`; setting `size`, zeroing reserved bytes, and throwing on null pointer follow Sony SDK `*ParamInit` conventions but are unverified on retail hardware -- [sceNpGameIntentInfoInit](../../../core/libs/prx/libSceNpGameIntent/Export.cpp) (libSceNpGameIntent) - struct layout matches [fpPS4](https://github.com/red-prig/fpPS4/blob/master/src/np/ps4_libscenpgameintent.pas#L28) `SceNpGameIntentInfo`; setting `size`, `user_id = -1`, zeroing fields, and throwing on null pointer match `sceNpGameIntentReceiveIntent` defaults but are unverified on retail hardware +- [sceNpGameIntentInfoInit](../../../core/libs/prx/libSceNpGameIntent/Export.cpp) (libSceNpGameIntent) - struct layout matches [fpPS4](https://github.com/red-prig/fpPS4/blob/master/src/np/ps4_libscenpgameintent.pas#L28) `SceNpGameIntentInfo`; setting `size = 0x560`, `user_id = -1`, zeroing fields, and throwing on null pointer follow fpPS4 defaults, but reported firmware 13.42 behavior requires `0x4140` for `sceNpGameIntentReceiveIntent`, so the helper's `0x560` size does not match retail receiver defaults; the complete retail structure layout and retail behavior of `sceNpGameIntentInfoInit` remain unverified From 59c7e535c0d2d6ea2c6e2ba0ac8e0ec5f752e105 Mon Sep 17 00:00:00 2001 From: lakhantheboss <61951686+lakhantheboss@users.noreply.github.com> Date: Sun, 25 Oct 2026 19:21:19 +0530 Subject: [PATCH 4/4] docs(libSceNpGameIntent): concise technical debt entry for receive intent size guard --- docs/dev/debt/libSceNpGameIntent.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/dev/debt/libSceNpGameIntent.md b/docs/dev/debt/libSceNpGameIntent.md index 8476d2c449..cc0daa50c5 100644 --- a/docs/dev/debt/libSceNpGameIntent.md +++ b/docs/dev/debt/libSceNpGameIntent.md @@ -7,7 +7,7 @@ ### Unknown function info -- [sceNpGameIntentReceiveIntent, sceNpGameIntentGetPropertyValueString](../../../core/libs/prx/libSceNpGameIntent/Export.cpp) (libSceNpGameIntent) - firmware 13.42 emulator traces report `0x80553802` when called before `sceNpGameIntentInitialize` (precedence over argument validity), and `0x80553804` for invalid arguments (null pointer, empty key, or zero buffer size); `sceNpGameIntentTerminate` resetting the initialization state is modeled lifecycle behavior rather than independently hardware-verified. `sceNpGameIntentReceiveIntent` reportedly requires `info->size == 0x4140` on firmware 13.42, while the current AnyPS5 `NpGameIntentInfo` is `0x560` bytes (matching fpPS4) and `sceNpGameIntentInfoInit` sets that size. Consequently, an object initialized by the current helper is rejected by the receiver's measured size guard. The complete retail layout, its output field offsets, and the retail behavior of `sceNpGameIntentInfoInit` have not been verified, and expanding the type with unverified reserved bytes is not an evidence-backed solution. +- [sceNpGameIntentReceiveIntent, sceNpGameIntentGetPropertyValueString](../../../core/libs/prx/libSceNpGameIntent/Export.cpp) (libSceNpGameIntent) - firmware 13.42 traces report `0x80553802` before `sceNpGameIntentInitialize` (precedence over argument validity), and `0x80553804` for invalid arguments (null pointer, empty key, or zero buffer size); `sceNpGameIntentTerminate` resetting initialized state is modeled lifecycle behavior rather than hardware-verified. `sceNpGameIntentReceiveIntent` reportedly requires `info->size == 0x4140` on firmware 13.42, while AnyPS5 `NpGameIntentInfo` is `0x560` bytes (matching fpPS4) and set by `sceNpGameIntentInfoInit`, so initialized objects are rejected by the receiver's measured size guard. Complete retail layout, output field offsets, and retail behavior of `sceNpGameIntentInfoInit` are unverified; expanding the type with unverified reserved bytes is not an evidence-backed solution. - [sceNpAppLauncherLaunchApp, sceNpGameIntentGetUdsNpComId, sceNpGameIntentLaunchApp, sceNpGameIntentLaunchApp2, sceNpGameIntentNotifyAppLaunched, sceNpSessionServiceGetJoinedPartySession, sceNpSessionServiceGetRunningGamePlayerSession and sceNpSessionServiceSendPlayerSessionInvitations](../../../core/libs/prx/libSceNpGameIntent/Export.cpp) (libSceNpGameIntent) - names and NIDs are present in the [PS5 3.20 export inventory](https://github.com/DNNDHH/PS5-3.20_Libs/blob/b2a77c09cd71c01f34c790cfbe98c751a13262ad/libSceNpGameIntent.c). Call sites in a title's executable give a partial prototype: `sceNpAppLauncherLaunchApp` takes `(user_id, uri struct, context)` and returns int — throws because no launcher-service semantics are derivable. The rest are declared without parameters solely to resolve known imports and make no ABI claim. - [sceNpGameIntentInitParamInit](../../../core/libs/prx/libSceNpGameIntent/Export.cpp) (libSceNpGameIntent) - struct layout matches [fpPS4](https://github.com/red-prig/fpPS4/blob/master/src/np/ps4_libscenpgameintent.pas#L17) `SceNpGameIntentInitParam`; setting `size`, zeroing reserved bytes, and throwing on null pointer follow Sony SDK `*ParamInit` conventions but are unverified on retail hardware - [sceNpGameIntentInfoInit](../../../core/libs/prx/libSceNpGameIntent/Export.cpp) (libSceNpGameIntent) - struct layout matches [fpPS4](https://github.com/red-prig/fpPS4/blob/master/src/np/ps4_libscenpgameintent.pas#L28) `SceNpGameIntentInfo`; setting `size = 0x560`, `user_id = -1`, zeroing fields, and throwing on null pointer follow fpPS4 defaults, but reported firmware 13.42 behavior requires `0x4140` for `sceNpGameIntentReceiveIntent`, so the helper's `0x560` size does not match retail receiver defaults; the complete retail structure layout and retail behavior of `sceNpGameIntentInfoInit` remain unverified