From a3cbbd086b11ef29fdd2641b90968a0e6209e490 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Fri, 6 Nov 2026 12:34:02 +0100 Subject: [PATCH] VSH: Show the configured MAC address in System Information - See #22924 The page reads IdStorage key 0x44 (6 bytes at offset 0) through vshbridge.prx, as does wlan.prx's sceWlanGetEtherAddr. The real idstorage.prx never finishes its init (it stops at the kernel mutexes we leave unresolved), so every lookup failed and the page showed "-". sceIdStorageLookup is now HLE, answering key 0x44 from the same MAC sceWlanGetEtherAddr uses. Other keys fail with 0x80000108, what the real driver returns uninitialized, and the rest of the library still resolves to idstorage.prx. Taken from the 6.61 modules' disassembly. Co-Authored-By: Claude Opus 5.5 --- Core/HLE/HLETables.cpp | 1 + Core/HLE/sceNet.cpp | 59 ++++++++++++++++++++++++++++++------ Core/HLE/sceNet.h | 1 + docs/VSHBootInvestigation.md | 7 +++-- 4 files changed, 57 insertions(+), 11 deletions(-) diff --git a/Core/HLE/HLETables.cpp b/Core/HLE/HLETables.cpp index 37b67fdfb5..b5958abfe3 100644 --- a/Core/HLE/HLETables.cpp +++ b/Core/HLE/HLETables.cpp @@ -441,6 +441,7 @@ void RegisterAllModules() { Register_sceVaudio_driver(); Register_sceNetApctl_lib(); Register_sceMeCore_driver(); + Register_sceIdStorage_driver(); // Not ready to enable this due to apparent softlocks in Patapon 3. // Register_sceNpMatching2(); diff --git a/Core/HLE/sceNet.cpp b/Core/HLE/sceNet.cpp index b7b6f8789d..663c3a7785 100644 --- a/Core/HLE/sceNet.cpp +++ b/Core/HLE/sceNet.cpp @@ -1103,29 +1103,61 @@ static int sceNetThreadAbort(SceUID thid) { return hleLogError(Log::sceNet, 0, "UNIMPL"); } -static u32 sceWlanGetEtherAddr(u32 addrAddr) { - if (!Memory::IsValidRange(addrAddr, 6)) { - // More correctly, it should crash. - return hleLogError(Log::sceNet, SCE_KERNEL_ERROR_ILLEGAL_ADDR, "illegal address"); - } - - u8 *addr = Memory::GetPointerWriteUnchecked(addrAddr); +// The console's MAC address: the configured one, or one made from the instance ID when several run. +static void GetEtherAddr(u8 addr[6]) { if (PPSSPP_ID > 1) { - Memory::Memset(addrAddr, PPSSPP_ID, 6); + memset(addr, PPSSPP_ID, 6); // Making sure the 1st 2-bits on the 1st byte of OUI are zero to prevent issue with some games (ie. Gran Turismo) addr[0] &= 0xfc; } else { // Read MAC Address from config if (!ParseMacAddress(g_Config.sMACAddress, addr)) { ERROR_LOG(Log::sceNet, "Error parsing mac address %s", g_Config.sMACAddress.c_str()); - Memory::Memset(addrAddr, 0, 6); + memset(addr, 0, 6); } } +} + +static u32 sceWlanGetEtherAddr(u32 addrAddr) { + if (!Memory::IsValidRange(addrAddr, 6)) { + // More correctly, it should crash. + return hleLogError(Log::sceNet, SCE_KERNEL_ERROR_ILLEGAL_ADDR, "illegal address"); + } + + GetEtherAddr(Memory::GetPointerWriteUnchecked(addrAddr)); NotifyMemInfo(MemBlockFlags::WRITE, addrAddr, 6, "WlanEtherAddr"); return hleDelayResult(hleLogDebug(Log::sceNet, 0), "get ether mac", 200); } +// Reads len bytes at offset from the 512-byte IdStorage leaf for key. We only have the leaf that +// holds the MAC address, key 0x44, which the VSH's wlan.prx (sceWlanGetEtherAddr) and +// sysconf_plugin.prx (System Information, through vshbridge.prx's sceVshBridge_4db43867) both read +// as 6 bytes at offset 0. Every other key gets the error flash0:/kd/idstorage.prx returned before +// this existed: its init stops at the kernel mutexes we leave unresolved (see ThreadManForKernel), +// so it never sets its initialized flag. The argument checks come from that function, too. +static u32 sceIdStorageLookup(u32 key, u32 offset, u32 bufAddr, u32 len) { + key &= 0xFFFF; + if (key > 0xFFEF) { + return hleLogError(Log::sceMisc, 0x80000100, "bad key"); + } + if (offset >= 0x200 || offset + len > 0x200) { + return hleLogError(Log::sceMisc, 0x800001FE, "out of range"); + } + if (key != 0x44) { + return hleLogDebug(Log::sceMisc, 0x80000108, "key not available"); + } + if (!Memory::IsValidRange(bufAddr, len)) { + return hleLogError(Log::sceMisc, SCE_KERNEL_ERROR_ILLEGAL_ADDR, "illegal address"); + } + + u8 leaf[0x200]{}; + GetEtherAddr(leaf); + Memory::MemcpyUnchecked(bufAddr, leaf + offset, len); + NotifyMemInfo(MemBlockFlags::WRITE, bufAddr, len, "IdStorageLookup"); + return hleLogInfo(Log::sceMisc, 0); +} + static u32 sceNetGetLocalEtherAddr(u32 addrAddr) { // FIXME: Return 0x80410180 (pspnet[_core] error code?) before successful attempt to Create/Connect/Join a Group? (ie. adhocctlCurrentMode == ADHOCCTL_MODE_NONE) // Fails while apctl is initialized but not connected (pspautotests net/adhoc/apctlinit). PES 2009 polls it @@ -1975,3 +2007,12 @@ void Register_sceNetUpnp() { void Register_sceNetIfhandle() { RegisterHLEModule("sceNetIfhandle", ARRAY_SIZE(sceNetIfhandle), sceNetIfhandle); } + +// Just the one function. The rest of the library still resolves to flash0:/kd/idstorage.prx. +const HLEFunction sceIdStorage_driver[] = { + {0x6FE062D1, &WrapU_UUUU, "sceIdStorageLookup", 'x', "xxpx" }, +}; + +void Register_sceIdStorage_driver() { + RegisterHLEModule("sceIdStorage_driver", ARRAY_SIZE(sceIdStorage_driver), sceIdStorage_driver); +} diff --git a/Core/HLE/sceNet.h b/Core/HLE/sceNet.h index 5418efa2fb..12ad744854 100644 --- a/Core/HLE/sceNet.h +++ b/Core/HLE/sceNet.h @@ -109,6 +109,7 @@ void Register_sceNetApctl_lib(); void Register_sceWlanDrv(); void Register_sceNetUpnp(); void Register_sceNetIfhandle(); +void Register_sceIdStorage_driver(); void __NetInit(); void __NetShutdown(); diff --git a/docs/VSHBootInvestigation.md b/docs/VSHBootInvestigation.md index b1561a8b5e..9f289c313e 100644 --- a/docs/VSHBootInvestigation.md +++ b/docs/VSHBootInvestigation.md @@ -101,8 +101,11 @@ Two separate things: that hands each buffer to the ME (`sceVaudio_E8E78DC8`, then `sceVaudio_504E4745` many times a second). Its Motion JPEG thumbnails replace the frame's Huffman tables with the standard ones, so a file encoded with optimised tables (ffmpeg's default) gets a garbled thumbnail. -- **Settings**: the menus open. System Information shows "-" for the MAC address: wlan.prx reads it - from IdStorage key 0x44, and IdStorage is left failing on purpose (see below). +- **Settings**: the menus open. System Information shows the configured MAC address. It reads + IdStorage key 0x44 itself (6 bytes at offset 0, through vshbridge.prx's `sceVshBridge_4db43867`), + as does wlan.prx's `sceWlanGetEtherAddr`. The real idstorage.prx is left failing on purpose (see + below), so `sceIdStorageLookup` is HLE: it answers key 0x44 from the config and fails every other + key with the 0x80000108 the real driver returns uninitialized. - **Network**: the browser and the online manuals reach their Network Connection screen once `sceNetApctl_lib` is there, then stop at 8002013A on `sceHttp` functions only the NetFront browser uses (06488A1C, 2C3C82CF, 3A67F306, 739C2D79, 77EE5319, 8046E250, A461A167, B0257723).