Check magic number to reject SFO files specifically from being loaded as modules. Should fix the strange Soul Calibur issue in issue #2063.

This commit is contained in:
Henrik Rydgard 2013-06-05 19:56:36 +02:00
parent e007a299cf
commit 2e7b971895
2 changed files with 38 additions and 27 deletions

View file

@ -411,8 +411,7 @@ void ExportVarSymbol(const char *moduleName, u32 nid, u32 address)
} }
} }
Module *__KernelLoadELFFromPtr(const u8 *ptr, u32 loadAddress, std::string *error_string) Module *__KernelLoadELFFromPtr(const u8 *ptr, u32 loadAddress, std::string *error_string, u32 *magic) {
{
Module *module = new Module; Module *module = new Module;
kernelObjects.Create(module); kernelObjects.Create(module);
memset(&module->nm, 0, sizeof(module->nm)); memset(&module->nm, 0, sizeof(module->nm));
@ -422,9 +421,8 @@ Module *__KernelLoadELFFromPtr(const u8 *ptr, u32 loadAddress, std::string *erro
INFO_LOG(HLE, "~SCE module, skipping header"); INFO_LOG(HLE, "~SCE module, skipping header");
ptr += *(u32*)(ptr + 4); ptr += *(u32*)(ptr + 4);
} }
*magic = *(u32*)ptr;
if (*(u32*)ptr == 0x5053507e) { // "~PSP" if (*magic == 0x5053507e) { // "~PSP"
// Decrypt module! YAY!
INFO_LOG(HLE, "Decrypting ~PSP file"); INFO_LOG(HLE, "Decrypting ~PSP file");
PSP_Header *head = (PSP_Header*)ptr; PSP_Header *head = (PSP_Header*)ptr;
const u8 *in = ptr; const u8 *in = ptr;
@ -451,29 +449,26 @@ Module *__KernelLoadELFFromPtr(const u8 *ptr, u32 loadAddress, std::string *erro
{ {
ERROR_LOG(HLE, "Failed decrypting PRX! That's not normal! ret = %i\n", ret); ERROR_LOG(HLE, "Failed decrypting PRX! That's not normal! ret = %i\n", ret);
Reporting::ReportMessage("Failed decrypting the PRX (ret = %i, size = %i, psp_size = %i)!", ret, head->elf_size, head->psp_size); Reporting::ReportMessage("Failed decrypting the PRX (ret = %i, size = %i, psp_size = %i)!", ret, head->elf_size, head->psp_size);
// Fall through to safe exit in the next check.
} }
} }
if (*(u32*)ptr != 0x464c457f) // DO NOT change to else if, see above.
{ if (*(u32*)ptr != 0x464c457f) {
ERROR_LOG_REPORT(HLE, "Wrong magic number %08x", *(u32*)ptr); ERROR_LOG_REPORT(HLE, "Wrong magic number %08x", *(u32*)ptr);
*error_string = "File corrupt"; *error_string = "File corrupt";
if (newptr) { if (newptr)
delete [] newptr; delete [] newptr;
}
kernelObjects.Destroy<Module>(module->GetUID()); kernelObjects.Destroy<Module>(module->GetUID());
return 0; return 0;
} }
// Open ELF reader // Open ELF reader
ElfReader reader((void*)ptr); ElfReader reader((void*)ptr);
if (!reader.LoadInto(loadAddress)) if (!reader.LoadInto(loadAddress)) {
{
ERROR_LOG(HLE, "LoadInto failed"); ERROR_LOG(HLE, "LoadInto failed");
if (newptr) if (newptr)
{
delete [] newptr; delete [] newptr;
}
kernelObjects.Destroy<Module>(module->GetUID()); kernelObjects.Destroy<Module>(module->GetUID());
return 0; return 0;
} }
@ -525,8 +520,7 @@ Module *__KernelLoadELFFromPtr(const u8 *ptr, u32 loadAddress, std::string *erro
SectionID textSection = reader.GetSectionByName(".text"); SectionID textSection = reader.GetSectionByName(".text");
if (textSection != -1) if (textSection != -1) {
{
u32 textStart = reader.GetSectionAddr(textSection); u32 textStart = reader.GetSectionAddr(textSection);
u32 textSize = reader.GetSectionSize(textSection); u32 textSize = reader.GetSectionSize(textSection);
@ -810,9 +804,8 @@ Module *__KernelLoadELFFromPtr(const u8 *ptr, u32 loadAddress, std::string *erro
module->nm.entry_addr = module->nm.module_start_func; module->nm.entry_addr = module->nm.module_start_func;
if (newptr) if (newptr)
{
delete [] newptr; delete [] newptr;
}
return module; return module;
} }
@ -833,7 +826,8 @@ bool __KernelLoadPBP(const char *filename, std::string *error_string)
size_t elfSize; size_t elfSize;
u8 *elfData = pbp.GetSubFile(PBP_EXECUTABLE_PSP, &elfSize); u8 *elfData = pbp.GetSubFile(PBP_EXECUTABLE_PSP, &elfSize);
Module *module = __KernelLoadELFFromPtr(elfData, PSP_GetDefaultLoadAddress(), error_string); u32 magic;
Module *module = __KernelLoadELFFromPtr(elfData, PSP_GetDefaultLoadAddress(), error_string, &magic);
if (!module) { if (!module) {
delete [] elfData; delete [] elfData;
return false; return false;
@ -860,11 +854,13 @@ Module *__KernelLoadModule(u8 *fileptr, SceKernelLMOption *options, std::string
offsets[0] = offset0; offsets[0] = offset0;
for (int i = 1; i < numfiles; i++) for (int i = 1; i < numfiles; i++)
memcpy(&offsets[i], fileptr + 12 + 4*i, 4); memcpy(&offsets[i], fileptr + 12 + 4*i, 4);
module = __KernelLoadELFFromPtr(fileptr + offsets[5], PSP_GetDefaultLoadAddress(), error_string); u32 magic = 0;
module = __KernelLoadELFFromPtr(fileptr + offsets[5], PSP_GetDefaultLoadAddress(), error_string, &magic);
} }
else else
{ {
module = __KernelLoadELFFromPtr(fileptr, PSP_GetDefaultLoadAddress(), error_string); u32 magic = 0;
module = __KernelLoadELFFromPtr(fileptr, PSP_GetDefaultLoadAddress(), error_string, &magic);
} }
return module; return module;
@ -1032,11 +1028,17 @@ u32 sceKernelLoadModule(const char *name, u32 flags, u32 optionAddr)
u8 *temp = new u8[(int)size]; u8 *temp = new u8[(int)size];
u32 handle = pspFileSystem.OpenFile(name, FILEACCESS_READ); u32 handle = pspFileSystem.OpenFile(name, FILEACCESS_READ);
pspFileSystem.ReadFile(handle, temp, (size_t)size); pspFileSystem.ReadFile(handle, temp, (size_t)size);
module = __KernelLoadELFFromPtr(temp, 0, &error_string); u32 magic;
module = __KernelLoadELFFromPtr(temp, 0, &error_string, &magic);
delete [] temp; delete [] temp;
pspFileSystem.CloseFile(handle); pspFileSystem.CloseFile(handle);
if (!module) { if (!module) {
if (magic == 0x46535000) {
ERROR_LOG(LOADER, "Game tried to load an SFO as a module. Go figure? Magic = %08x", magic);
return -1;
}
// Module was blacklisted or couldn't be decrypted, which means it's a kernel module we don't want to run. // Module was blacklisted or couldn't be decrypted, which means it's a kernel module we don't want to run.
// Let's just act as if it worked. // Let's just act as if it worked.
NOTICE_LOG(LOADER, "Module %s is blacklisted or undecryptable - we lie about success", name); NOTICE_LOG(LOADER, "Module %s is blacklisted or undecryptable - we lie about success", name);
@ -1356,12 +1358,21 @@ u32 sceKernelLoadModuleByID(u32 id, u32 flags, u32 lmoptionPtr)
Module *module = 0; Module *module = 0;
u8 *temp = new u8[size]; u8 *temp = new u8[size];
pspFileSystem.ReadFile(handle, temp, size); pspFileSystem.ReadFile(handle, temp, size);
module = __KernelLoadELFFromPtr(temp, 0, &error_string); u32 magic;
module = __KernelLoadELFFromPtr(temp, 0, &error_string, &magic);
delete [] temp; delete [] temp;
if (!module) { if (!module) {
// Some games try to load strange stuff as PARAM.SFO as modules and expect it to fail.
// This checks for the SFO magic number.
if (magic == 0x46535000) {
ERROR_LOG(LOADER, "Game tried to load an SFO as a module. Go figure? Magic = %08x", magic);
return -1;
}
// Module was blacklisted or couldn't be decrypted, which means it's a kernel module we don't want to run. // Module was blacklisted or couldn't be decrypted, which means it's a kernel module we don't want to run.
// Let's just act as if it worked. // Let's just act as if it worked.
NOTICE_LOG(LOADER, "Module %d is blacklisted or undecryptable - we lie about success", id); NOTICE_LOG(LOADER, "Module %d is blacklisted or undecryptable - we lie about success", id);
return 1; return 1;
} }

View file

@ -417,6 +417,11 @@ u32 scePsmfSpecifyStreamWithStreamTypeNumber(u32 psmfStruct, u32 streamType, u32
return 0; return 0;
} }
u32 scePsmfSpecifyStream(u32 psmfPlayer, int streamNum) {
ERROR_LOG(HLE, "UNIMPL scePsmfSpecifyStream(%08x, %i)", psmfPlayer, streamNum);
return 0;
}
u32 scePsmfGetVideoInfo(u32 psmfStruct, u32 videoInfoAddr) { u32 scePsmfGetVideoInfo(u32 psmfStruct, u32 videoInfoAddr) {
INFO_LOG(HLE, "scePsmfGetVideoInfo(%08x, %08x)", psmfStruct, videoInfoAddr); INFO_LOG(HLE, "scePsmfGetVideoInfo(%08x, %08x)", psmfStruct, videoInfoAddr);
Psmf *psmf = getPsmf(psmfStruct); Psmf *psmf = getPsmf(psmfStruct);
@ -1026,11 +1031,6 @@ u32 scePsmfPlayerConfigPlayer(u32 psmfPlayer, int configMode, int configAttr)
return 0; return 0;
} }
u32 scePsmfSpecifyStream(u32 psmfPlayer, int streamNum) {
ERROR_LOG(HLE, "UNIMPL scePsmfSpecifyStream(%08x, %i)", psmfPlayer, streamNum);
return 0;
}
const HLEFunction scePsmf[] = { const HLEFunction scePsmf[] = {
{0xc22c8327, WrapU_UU<scePsmfSetPsmf>, "scePsmfSetPsmf"}, {0xc22c8327, WrapU_UU<scePsmfSetPsmf>, "scePsmfSetPsmf"},
{0xC7DB3A5B, WrapU_UUU<scePsmfGetCurrentStreamType>, "scePsmfGetCurrentStreamType"}, {0xC7DB3A5B, WrapU_UUU<scePsmfGetCurrentStreamType>, "scePsmfGetCurrentStreamType"},