From cf0c0dab0abd98de90ffb2d7b07bbdaf4ca4649e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 5 Jan 2025 22:46:58 +0100 Subject: [PATCH 1/5] Add some known function hashes to the sceNpService table --- Core/HLE/sceNp.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Core/HLE/sceNp.cpp b/Core/HLE/sceNp.cpp index 3084766f04..540609c02b 100644 --- a/Core/HLE/sceNp.cpp +++ b/Core/HLE/sceNp.cpp @@ -610,6 +610,10 @@ const HLEFunction sceNpService[] = { {0X4E851B10, &WrapI_IUUUUUU, "sceNpRosterGetFriendListEntry", 'i', "ixxxxxx"}, {0X5F5E32AF, &WrapI_I, "sceNpRosterAbort", 'i', "i" }, {0X66C64821, &WrapI_I, "sceNpRosterDeleteRequest", 'i', "i" }, + {0X506C318D, nullptr, "sceNpService_506C318D", 'i', "" }, + {0X58251346, nullptr, "sceNpService_58251346", 'i', "" }, + {0X788F2B5E, nullptr, "sceNpService_788F2B5E", 'i', "" }, + {0XA01443AA, nullptr, "sceNpService_A01443AA", 'i', "" }, }; void Register_sceNpService() From 2edc3085a51a76fc2fc5219202a93dccba6a74a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 5 Jan 2025 22:49:17 +0100 Subject: [PATCH 2/5] PSPPointer<>: Replace some fiddly memsets with use of a new FillWithZero function. --- Core/HLE/sceNp.cpp | 10 +++++----- Core/MemMap.cpp | 4 +++- Core/MemMap.h | 4 ++++ 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/Core/HLE/sceNp.cpp b/Core/HLE/sceNp.cpp index 540609c02b..76f9682ee1 100644 --- a/Core/HLE/sceNp.cpp +++ b/Core/HLE/sceNp.cpp @@ -158,7 +158,7 @@ static int sceNpGetOnlineId(u32 idPtr) if (!id.IsValid()) return hleLogError(Log::sceNet, SCE_NP_ERROR_INVALID_ARGUMENT, "invalid arg"); - memset((SceNpOnlineId *)id, 0, sizeof(SceNpOnlineId)); + id.FillWithZero(); truncate_cpy(id->data, sizeof(id->data), npOnlineId.c_str()); id.NotifyWrite("NpGetOnlineId"); @@ -182,7 +182,7 @@ static int sceNpGetNpId(u32 idPtr) return hleLogError(Log::sceNet, SCE_NP_ERROR_INVALID_ARGUMENT, "invalid arg"); SceNpId dummyNpId{}; - memset((SceNpId *)id, 0, sizeof(SceNpId)); + id.FillWithZero(); int retval = NpGetNpId(id); if (retval < 0) return hleLogError(Log::sceNet, retval); @@ -205,9 +205,9 @@ static int sceNpGetAccountRegion(u32 countryCodePtr, u32 regionCodePtr) if (!countryCode.IsValid() || !regionCode.IsValid()) return hleLogError(Log::sceNet, SCE_NP_ERROR_INVALID_ARGUMENT, "invalid arg"); - memset((SceNpCountryCode *)countryCode, 0, sizeof(SceNpCountryCode)); + countryCode.FillWithZero(); memcpy(countryCode->data, npCountryCode, sizeof(countryCode->data)); - memset((SceNpCountryCode *)regionCode, 0, sizeof(SceNpCountryCode)); + regionCode.FillWithZero(); memcpy(regionCode->data, npRegionCode, sizeof(regionCode->data)); INFO_LOG(Log::sceNet, "%s - Country Code: %s", __FUNCTION__, countryCode->data); @@ -245,7 +245,7 @@ static int sceNpGetUserProfile(u32 profilePtr) if (!Memory::IsValidAddress(profilePtr)) return hleLogError(Log::sceNet, SCE_NP_ERROR_INVALID_ARGUMENT, "invalid arg"); - memset((SceNpUserInformation *)profile, 0, sizeof(SceNpUserInformation)); + profile.FillWithZero(); truncate_cpy(profile->userId.handle.data, sizeof(profile->userId.handle.data), npOnlineId.c_str()); truncate_cpy(profile->icon.data, sizeof(profile->icon.data), npAvatarUrl.c_str()); diff --git a/Core/MemMap.cpp b/Core/MemMap.cpp index 14b8e66d86..7b2bd955ab 100644 --- a/Core/MemMap.cpp +++ b/Core/MemMap.cpp @@ -497,7 +497,9 @@ void Memset(const u32 _Address, const u8 _iValue, const u32 _iLength, const char Write_U8(_iValue, (u32)(_Address + i)); } - NotifyMemInfo(MemBlockFlags::WRITE, _Address, _iLength, tag, strlen(tag)); + if (tag) { + NotifyMemInfo(MemBlockFlags::WRITE, _Address, _iLength, tag, strlen(tag)); + } } } // namespace diff --git a/Core/MemMap.h b/Core/MemMap.h index 03a77bc954..f802ead671 100644 --- a/Core/MemMap.h +++ b/Core/MemMap.h @@ -499,6 +499,10 @@ struct PSPPointer return Memory::IsValidRange(ptr, (u32)sizeof(T)); } + void FillWithZero() { + memset(Memory::GetPointerWrite(ptr), 0, sizeof(T)); + } + T *PtrOrNull() { if (IsValid()) return (T *)*this; From 3e98f16e6ba73373db6696d0806019f73ab6b50b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 5 Jan 2025 23:17:57 +0100 Subject: [PATCH 3/5] static-ify a bunch of functions --- Core/HLE/sceNp.cpp | 10 +++++----- Core/HLE/sceNp2.cpp | 4 ---- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/Core/HLE/sceNp.cpp b/Core/HLE/sceNp.cpp index 76f9682ee1..f044a210ac 100644 --- a/Core/HLE/sceNp.cpp +++ b/Core/HLE/sceNp.cpp @@ -53,7 +53,7 @@ std::map npAuthHandlers; // Tickets data are in big-endian based on captured packets -int writeTicketParam(u8* buffer, const u16_be type, const char* data = nullptr, const u16_be size = 0) { +static int writeTicketParam(u8* buffer, const u16_be type, const char* data = nullptr, const u16_be size = 0) { if (buffer == nullptr) return 0; u16_be sz = (data == nullptr)? static_cast(0): size; @@ -65,7 +65,7 @@ int writeTicketParam(u8* buffer, const u16_be type, const char* data = nullptr, return sz + 4; } -int writeTicketStringParam(u8* buffer, const u16_be type, const char* data = nullptr, const u16_be size = 0) { +static int writeTicketStringParam(u8* buffer, const u16_be type, const char* data = nullptr, const u16_be size = 0) { if (buffer == nullptr) return 0; u16_be sz = (data == nullptr) ? static_cast(0) : size; @@ -78,7 +78,7 @@ int writeTicketStringParam(u8* buffer, const u16_be type, const char* data = nul return sz + 4; } -int writeTicketU32Param(u8* buffer, const u16_be type, const u32_be data) { +static int writeTicketU32Param(u8* buffer, const u16_be type, const u32_be data) { if (buffer == nullptr) return 0; u16_be sz = 4; @@ -89,7 +89,7 @@ int writeTicketU32Param(u8* buffer, const u16_be type, const u32_be data) { return sz + 4; } -int writeTicketU64Param(u8* buffer, const u16_be type, const u64_be data) { +static int writeTicketU64Param(u8* buffer, const u16_be type, const u64_be data) { if (buffer == nullptr) return 0; u16_be sz = 8; @@ -100,7 +100,7 @@ int writeTicketU64Param(u8* buffer, const u16_be type, const u64_be data) { return sz + 4; } -void notifyNpAuthHandlers(u32 id, u32 result, u32 argAddr) { +static void notifyNpAuthHandlers(u32 id, u32 result, u32 argAddr) { std::lock_guard npAuthGuard(npAuthEvtMtx); npAuthEvents.push_back({ { id, result, argAddr } }); } diff --git a/Core/HLE/sceNp2.cpp b/Core/HLE/sceNp2.cpp index a03829a23c..8d6a087121 100644 --- a/Core/HLE/sceNp2.cpp +++ b/Core/HLE/sceNp2.cpp @@ -15,9 +15,6 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. -// This is pretty much a stub implementation. Doesn't actually do anything, just tries to return values -// to keep games happy anyway. - #include #include #include @@ -28,7 +25,6 @@ #include "Core/HLE/sceNp.h" #include "Core/HLE/sceNp2.h" - bool npMatching2Inited = false; SceNpAuthMemoryStat npMatching2MemStat = {}; From 504eadc33797ecab92755bdd89e3752db777e86d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 5 Jan 2025 23:18:13 +0100 Subject: [PATCH 4/5] sceNp: Allow for 16-character usernames (do not insert null) --- Core/HLE/sceNp.cpp | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/Core/HLE/sceNp.cpp b/Core/HLE/sceNp.cpp index f044a210ac..770ed5f140 100644 --- a/Core/HLE/sceNp.cpp +++ b/Core/HLE/sceNp.cpp @@ -72,8 +72,11 @@ static int writeTicketStringParam(u8* buffer, const u16_be type, const char* dat memcpy(buffer, &type, 2); memcpy(buffer + 2, &sz, 2); if (sz > 0) { - memset(buffer + 4, 0, sz); - truncate_cpy((char*)buffer + 4, sz, data); + // Yes, we want to use strncpy. Do not change to truncate_cpy. + if (data) + strncpy((char *)buffer + 4, data, sz); + else + memset(buffer + 4, 0, sz); } return sz + 4; } @@ -159,7 +162,7 @@ static int sceNpGetOnlineId(u32 idPtr) return hleLogError(Log::sceNet, SCE_NP_ERROR_INVALID_ARGUMENT, "invalid arg"); id.FillWithZero(); - truncate_cpy(id->data, sizeof(id->data), npOnlineId.c_str()); + strncpy(id->data, npOnlineId.c_str(), sizeof(id->data)); id.NotifyWrite("NpGetOnlineId"); INFO_LOG(Log::sceNet, "%s - Online ID: %s", __FUNCTION__, id->data); @@ -169,7 +172,8 @@ static int sceNpGetOnlineId(u32 idPtr) int NpGetNpId(SceNpId* npid) { - truncate_cpy(npid->handle.data, sizeof(npid->handle.data), npOnlineId.c_str()); + // Callers make sure that the rest of npid is zero filled, which takes care of the terminator. + strncpy(npid->handle.data, npOnlineId.c_str(), sizeof(npid->handle.data)); return 0; } @@ -246,7 +250,7 @@ static int sceNpGetUserProfile(u32 profilePtr) return hleLogError(Log::sceNet, SCE_NP_ERROR_INVALID_ARGUMENT, "invalid arg"); profile.FillWithZero(); - truncate_cpy(profile->userId.handle.data, sizeof(profile->userId.handle.data), npOnlineId.c_str()); + strncpy(profile->userId.handle.data, npOnlineId.c_str(), sizeof(profile->userId.handle.data)); truncate_cpy(profile->icon.data, sizeof(profile->icon.data), npAvatarUrl.c_str()); INFO_LOG(Log::sceNet, "%s - Online ID: %s", __FUNCTION__, profile->userId.handle.data); @@ -409,7 +413,7 @@ int sceNpAuthGetTicket(u32 requestId, u32 bufferAddr, u32 length) ofs += writeTicketU64Param(buf + ofs, PARAM_TYPE_DATE, now); ofs += writeTicketU64Param(buf + ofs, PARAM_TYPE_DATE, now + 10 * 60 * 1000); // now + 10 minutes, expired time? ofs += writeTicketU64Param(buf + ofs, PARAM_TYPE_LONG, 0x592e71c546e86859); // seems to be consistent, 8-bytes password hash may be? or related to entitlement? or console id? - ofs += writeTicketStringParam(buf + ofs, PARAM_TYPE_STRING, npOnlineId.c_str(), 16); // username + ofs += writeTicketStringParam(buf + ofs, PARAM_TYPE_STRING, npOnlineId.c_str(), 16); // username (cut to 16 chars exactly) ofs += writeTicketParam(buf + ofs, PARAM_TYPE_STRING_ASCII, npCountryCode, 4); // SceNpCountryCode ? ie. "fr" + 00 02 ofs += writeTicketStringParam(buf + ofs, PARAM_TYPE_STRING, npRegionCode, 4); // 2-char code? related to country/lang code? ie. "c9" + 00 00 ofs += writeTicketParam(buf + ofs, PARAM_TYPE_STRING_ASCII, npServiceId.c_str(), 24); From c8da841c3eb1568235b65035d288675687234a52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 6 Jan 2025 08:33:56 +0100 Subject: [PATCH 5/5] Leave 32 bytes of space in the ticket for names, and make sure they're just 16 chars long. --- Core/HLE/sceNp.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Core/HLE/sceNp.cpp b/Core/HLE/sceNp.cpp index 770ed5f140..58df727d9d 100644 --- a/Core/HLE/sceNp.cpp +++ b/Core/HLE/sceNp.cpp @@ -112,6 +112,10 @@ static int sceNpInit() { ERROR_LOG(Log::sceNet, "UNIMPL %s()", __FUNCTION__); npOnlineId = g_Config.sNickName; + // Truncate the nickname to 16 chars exactly - longer names are not support. + if (npOnlineId.size() > 16) { + npOnlineId.resize(16); + } return 0; } @@ -413,7 +417,7 @@ int sceNpAuthGetTicket(u32 requestId, u32 bufferAddr, u32 length) ofs += writeTicketU64Param(buf + ofs, PARAM_TYPE_DATE, now); ofs += writeTicketU64Param(buf + ofs, PARAM_TYPE_DATE, now + 10 * 60 * 1000); // now + 10 minutes, expired time? ofs += writeTicketU64Param(buf + ofs, PARAM_TYPE_LONG, 0x592e71c546e86859); // seems to be consistent, 8-bytes password hash may be? or related to entitlement? or console id? - ofs += writeTicketStringParam(buf + ofs, PARAM_TYPE_STRING, npOnlineId.c_str(), 16); // username (cut to 16 chars exactly) + ofs += writeTicketStringParam(buf + ofs, PARAM_TYPE_STRING, npOnlineId.c_str(), 32); // username (pre-cut to 16 chars) ofs += writeTicketParam(buf + ofs, PARAM_TYPE_STRING_ASCII, npCountryCode, 4); // SceNpCountryCode ? ie. "fr" + 00 02 ofs += writeTicketStringParam(buf + ofs, PARAM_TYPE_STRING, npRegionCode, 4); // 2-char code? related to country/lang code? ie. "c9" + 00 00 ofs += writeTicketParam(buf + ofs, PARAM_TYPE_STRING_ASCII, npServiceId.c_str(), 24);