From 8ef00232d38a72202b748517e212e874acc45435 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Wed, 21 May 2014 23:14:52 -0700 Subject: [PATCH 1/2] Parse exports of blacklisted modules. But ignore them. This allows us to get the devkit version and other potentially useful information. --- Core/HLE/sceKernelModule.cpp | 86 ++++++++++++++++++++++-------------- 1 file changed, 53 insertions(+), 33 deletions(-) diff --git a/Core/HLE/sceKernelModule.cpp b/Core/HLE/sceKernelModule.cpp index 0dd6dc1ff1..f094095092 100644 --- a/Core/HLE/sceKernelModule.cpp +++ b/Core/HLE/sceKernelModule.cpp @@ -282,6 +282,9 @@ public: void Cleanup(); void ImportFunc(const FuncSymbolImport &func) { + if (isFake) { + return; + } if (!Memory::IsValidAddress(func.stubAddr)) { WARN_LOG_REPORT(LOADER, "Invalid address for syscall stub %s %08x", func.moduleName, func.nid); return; @@ -301,6 +304,9 @@ public: } void ImportVar(const VarSymbolImport &var) { + if (isFake) { + return; + } // Keep track and actually hook it up if possible. importedVars.push_back(var); impExpModuleNames.insert(var.moduleName); @@ -308,12 +314,18 @@ public: } void ExportFunc(const FuncSymbolExport &func) { + if (isFake) { + return; + } exportedFuncs.push_back(func); impExpModuleNames.insert(func.moduleName); ExportFuncSymbol(func); } void ExportVar(const VarSymbolExport &var) { + if (isFake) { + return; + } exportedVars.push_back(var); impExpModuleNames.insert(var.moduleName); ExportVarSymbol(var); @@ -812,6 +824,7 @@ Module *__KernelLoadELFFromPtr(const u8 *ptr, u32 loadAddress, std::string *erro memset(&module->nm, 0, sizeof(module->nm)); bool reportedModule = false; + u32 devkitVersion = 0; u8 *newptr = 0; u32_le *magicPtr = (u32_le *) ptr; if (*magicPtr == 0x4543537e) { // "~SCE" @@ -823,6 +836,7 @@ Module *__KernelLoadELFFromPtr(const u8 *ptr, u32 loadAddress, std::string *erro if (*magic == 0x5053507e) { // "~PSP" DEBUG_LOG(SCEMODULE, "Decrypting ~PSP file"); PSP_Header *head = (PSP_Header*)ptr; + devkitVersion = head->devkitversion; if (IsHLEVersionedModule(head->modname)) { int ver = (head->module_ver_hi << 8) | head->module_ver_lo; @@ -934,33 +948,18 @@ Module *__KernelLoadELFFromPtr(const u8 *ptr, u32 loadAddress, std::string *erro char moduleName[29] = {0}; strncpy(moduleName, modinfo->name, ARRAY_SIZE(module->nm.name)); - if (!reportedModule && IsHLEVersionedModule(modinfo->name)) { - char temp[256]; - snprintf(temp, sizeof(temp), "Loading module %s with version %%04x", modinfo->name); - INFO_LOG_REPORT(SCEMODULE, temp, modinfo->moduleVersion); - - if (!strcmp(modinfo->name, "sceMpeg_library")) { - __MpegLoadModule(modinfo->moduleVersion); - } - } - // Check for module blacklist - we don't allow games to load these modules from disc // as we have HLE implementations and the originals won't run in the emu because they // directly access hardware or for other reasons. for (u32 i = 0; i < ARRAY_SIZE(blacklistedModules); i++) { if (strncmp(modinfo->name, blacklistedModules[i], ARRAY_SIZE(modinfo->name)) == 0) { - *error_string = "Blacklisted"; - if (newptr) - { - delete [] newptr; - } module->isFake = true; - module->nm.entry_addr = -1; - return module; } } - symbolMap.AddModule(moduleName, module->memoryBlockAddr, module->memoryBlockSize); + if (!module->isFake) { + symbolMap.AddModule(moduleName, module->memoryBlockAddr, module->memoryBlockSize); + } SectionID textSection = reader.GetSectionByName(".text"); @@ -975,18 +974,20 @@ Module *__KernelLoadELFFromPtr(const u8 *ptr, u32 loadAddress, std::string *erro // TODO: It seems like the data size excludes the text size, which kinda makes sense? module->nm.data_size -= textSize; + if (!module->isFake) { #if !defined(MOBILE_DEVICE) - bool gotSymbols = reader.LoadSymbols(); - MIPSAnalyst::ScanForFunctions(module->textStart, module->textEnd, !gotSymbols); -#else - if (g_Config.bFuncHashMap) { bool gotSymbols = reader.LoadSymbols(); MIPSAnalyst::ScanForFunctions(module->textStart, module->textEnd, !gotSymbols); - } +#else + if (g_Config.bFuncHashMap) { + bool gotSymbols = reader.LoadSymbols(); + MIPSAnalyst::ScanForFunctions(module->textStart, module->textEnd, !gotSymbols); + } #endif + } } - INFO_LOG(LOADER,"Module %s: %08x %08x %08x", modinfo->name, modinfo->gp, modinfo->libent,modinfo->libstub); + INFO_LOG(LOADER, "Module %s: %08x %08x %08x", modinfo->name, modinfo->gp, modinfo->libent, modinfo->libstub); struct PspLibStubEntry { u32_le name; @@ -1136,15 +1137,18 @@ Module *__KernelLoadELFFromPtr(const u8 *ptr, u32 loadAddress, std::string *erro if (textSection == -1) { module->textStart = reader.GetVaddr(); module->textEnd = firstImportStubAddr - 4; + + if (!module->isFake) { #if !defined(MOBILE_DEVICE) - bool gotSymbols = reader.LoadSymbols(); - MIPSAnalyst::ScanForFunctions(module->textStart, module->textEnd, !gotSymbols); -#else - if (g_Config.bFuncHashMap) { bool gotSymbols = reader.LoadSymbols(); MIPSAnalyst::ScanForFunctions(module->textStart, module->textEnd, !gotSymbols); - } +#else + if (g_Config.bFuncHashMap) { + bool gotSymbols = reader.LoadSymbols(); + MIPSAnalyst::ScanForFunctions(module->textStart, module->textEnd, !gotSymbols); + } #endif + } } // Look at the exports, too. @@ -1242,6 +1246,7 @@ Module *__KernelLoadELFFromPtr(const u8 *ptr, u32 loadAddress, std::string *erro int size; switch (nid) { case NID_MODULE_INFO: + // Points to a PspModuleInfo, often the exact one .rodata.sceModuleInfo points to. break; case NID_MODULE_START_THREAD_PARAMETER: size = Memory::Read_U32(exportAddr); @@ -1275,6 +1280,7 @@ Module *__KernelLoadELFFromPtr(const u8 *ptr, u32 loadAddress, std::string *erro break; case NID_MODULE_SDK_VERSION: DEBUG_LOG(LOADER, "Module SDK: %08x", Memory::Read_U32(exportAddr)); + devkitVersion = Memory::Read_U32(exportAddr); break; default: var.nid = nid; @@ -1285,15 +1291,29 @@ Module *__KernelLoadELFFromPtr(const u8 *ptr, u32 loadAddress, std::string *erro } } - module->nm.entry_addr = reader.GetEntryPoint(); + if (!module->isFake) { + module->nm.entry_addr = reader.GetEntryPoint(); - // use module_start_func instead of entry_addr if entry_addr is 0 - if (module->nm.entry_addr == 0) - module->nm.entry_addr = module->nm.module_start_func; + // use module_start_func instead of entry_addr if entry_addr is 0 + if (module->nm.entry_addr == 0) + module->nm.entry_addr = module->nm.module_start_func; + } else { + module->nm.entry_addr = -1; + } if (newptr) delete [] newptr; + if (!reportedModule && IsHLEVersionedModule(modinfo->name)) { + char temp[256]; + snprintf(temp, sizeof(temp), "Loading module %s with version %%04x, devkit %%08x", modinfo->name); + INFO_LOG_REPORT(SCEMODULE, temp, modinfo->moduleVersion, devkitVersion); + + if (!strcmp(modinfo->name, "sceMpeg_library")) { + __MpegLoadModule(modinfo->moduleVersion); + } + } + return module; } From c1fdb5fc5bc7e16beedbc41f195a95bfb704bc99 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 24 May 2014 17:15:25 -0700 Subject: [PATCH 2/2] Might as well allow imports to blacklisted. If someone's trying to read their code. --- Core/HLE/sceKernelModule.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/Core/HLE/sceKernelModule.cpp b/Core/HLE/sceKernelModule.cpp index f094095092..36b5f0d376 100644 --- a/Core/HLE/sceKernelModule.cpp +++ b/Core/HLE/sceKernelModule.cpp @@ -282,9 +282,6 @@ public: void Cleanup(); void ImportFunc(const FuncSymbolImport &func) { - if (isFake) { - return; - } if (!Memory::IsValidAddress(func.stubAddr)) { WARN_LOG_REPORT(LOADER, "Invalid address for syscall stub %s %08x", func.moduleName, func.nid); return; @@ -304,9 +301,6 @@ public: } void ImportVar(const VarSymbolImport &var) { - if (isFake) { - return; - } // Keep track and actually hook it up if possible. importedVars.push_back(var); impExpModuleNames.insert(var.moduleName);