mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
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:
parent
e007a299cf
commit
2e7b971895
2 changed files with 38 additions and 27 deletions
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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"},
|
||||||
|
|
Loading…
Add table
Reference in a new issue