From 0054d30b1de46782fb93aaacd670f8e473de4b3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 10 Sep 2026 11:32:36 -0600 Subject: [PATCH] HLE: cover the rest of the NIDs the VSH uses across firmware versions sceKernelLoadModuleVSH, sceKernelGetModel and sceImposeSetStatus each appear under a different NID in 3.95/4.05, 6.00/6.20 and 6.31/6.39. Without the load one those shells started no plugins at all and sat on a black screen. Identified the same way as the 5.xx set: for each firmware, the modulemgr export with sceKernelLoadModuleVSH's callee set, and the vshbridge export whose body is the user-level check 6.61 wraps sceKernelGetModel in - which is also the only SysMemForKernel import those shells actually call. 3.95 and 4.05 now reach an interactive XMB. Co-Authored-By: Claude Opus 5 (1M context) --- Core/HLE/sceImpose.cpp | 5 +++++ Core/HLE/sceKernelHeap.cpp | 6 ++++++ Core/HLE/sceKernelModule.cpp | 6 ++++++ 3 files changed, 17 insertions(+) diff --git a/Core/HLE/sceImpose.cpp b/Core/HLE/sceImpose.cpp index e2a4adf3a7..ad905a3f76 100644 --- a/Core/HLE/sceImpose.cpp +++ b/Core/HLE/sceImpose.cpp @@ -281,6 +281,11 @@ const HLEFunction sceImpose_driver[] = { {0X4B02F047, &WrapI_I, "sceImposeGetParam", 'i', "i" }, {0XD1E9019F, &WrapI_II, "sceImposeSetParam", 'i', "ii"}, {0X0BBCA0BF, &WrapI_V, "sceImposeChanges", 'i', "" }, + // sceImposeSetStatus again, for 3.95/4.05, 6.00/6.20 and 6.31/6.39 - identical bodies, and the + // only sceImpose_driver import those shells call. + {0X8434B075, &WrapI_I, "sceImposeSetStatus", 'i', "i" }, + {0X01EF0650, &WrapI_I, "sceImposeSetStatus", 'i', "i" }, + {0X2462EFE4, &WrapI_I, "sceImposeSetStatus", 'i', "i" }, }; void Register_sceImpose_driver() { diff --git a/Core/HLE/sceKernelHeap.cpp b/Core/HLE/sceKernelHeap.cpp index 639c1e01f4..268fecdf5a 100644 --- a/Core/HLE/sceKernelHeap.cpp +++ b/Core/HLE/sceKernelHeap.cpp @@ -208,6 +208,12 @@ const HLEFunction SysMemForKernel[] = { // looking for PSP-3000 resources on a dump that is a 1000. // NOTE: new entries go at the end - the syscall opcode in a savestate is an index into this array. { 0xDA07DC6E, &WrapI_V, "sceKernelGetModel", 'i', "", HLE_KERNEL_SYSCALL }, + // 3.95/4.05, 6.00/6.20 and 6.31/6.39 each use another NID again. Same identification: in every + // one of those firmwares vshbridge wraps it in the identical user-level check 6.61 wraps + // sceKernelGetModel in, and it is the only SysMemForKernel import their shells actually call. + { 0x4823B9D9, &WrapI_V, "sceKernelGetModel", 'i', "", HLE_KERNEL_SYSCALL }, + { 0x864EBFD7, &WrapI_V, "sceKernelGetModel", 'i', "", HLE_KERNEL_SYSCALL }, + { 0x458A70B5, &WrapI_V, "sceKernelGetModel", 'i', "", HLE_KERNEL_SYSCALL }, }; void Register_SysMemForKernel() { diff --git a/Core/HLE/sceKernelModule.cpp b/Core/HLE/sceKernelModule.cpp index ccc6c7116d..bb1ddfabe5 100644 --- a/Core/HLE/sceKernelModule.cpp +++ b/Core/HLE/sceKernelModule.cpp @@ -3200,6 +3200,12 @@ const HLEFunction ModuleMgrForKernel[] = { // identical callee set to 6.61's 0xD5DDAB1F. Without it 5.50's vshbridge couldn't load the // XMB plugins (opening_plugin, impose_plugin, ...) and the VSH stopped at a black screen. {0xCCDE84A8, &WrapU_CUU, "sceKernelLoadModuleVSH", 'x', "sxx", HLE_KERNEL_SYSCALL }, + // And the three remaining NIDs it has worn, all matched by the same callee set: 3.95 and 4.05 + // share one, 6.00 and 6.20 another, 6.31 and 6.39 the last. Each of those shells loaded no + // plugins at all and sat on a black screen until its NID was here. + {0xFE586962, &WrapU_CUU, "sceKernelLoadModuleVSH", 'x', "sxx", HLE_KERNEL_SYSCALL }, + {0x329C89DB, &WrapU_CUU, "sceKernelLoadModuleVSH", 'x', "sxx", HLE_KERNEL_SYSCALL }, + {0x8909A807, &WrapU_CUU, "sceKernelLoadModuleVSH", 'x', "sxx", HLE_KERNEL_SYSCALL }, }; void Register_ModuleMgrForUser() {