Refuse to load truncated ~PSP files.

This commit is contained in:
Henrik Rydgård committed 2017-06-06 23:41:23 +02:00
1 parent 57a20f02ed
commit b1b3b7c9d7
2 files changed
+59 -49

No files matched your search

+34 -21
View File
@@ -1043,7 +1043,7 @@ static bool KernelImportModuleFuncs(Module *module, u32 *firstImportStubAddr, bo
return true;
}
static Module *__KernelLoadELFFromPtr(const u8 *ptr, u32 loadAddress, bool fromTop, std::string *error_string, u32 *magic, u32 &error) {
static Module *__KernelLoadELFFromPtr(const u8 *ptr, size_t elfSize, u32 loadAddress, bool fromTop, std::string *error_string, u32 *magic, u32 &error) {
Module *module = new Module;
kernelObjects.Create(module);
loadedModules.insert(module->GetUID());
@@ -1055,7 +1055,9 @@ static Module *__KernelLoadELFFromPtr(const u8 *ptr, u32 loadAddress, bool fromT
u32_le *magicPtr = (u32_le *) ptr;
if (*magicPtr == 0x4543537e) { // "~SCE"
INFO_LOG(SCEMODULE, "~SCE module, skipping header");
ptr += *(u32_le*)(ptr + 4);
u32 headerSize = *(u32_le*)(ptr + 4);
ptr += headerSize;
elfSize -= headerSize;
magicPtr = (u32_le *)ptr;
}
*magic = *magicPtr;
@@ -1081,8 +1083,14 @@ static Module *__KernelLoadELFFromPtr(const u8 *ptr, u32 loadAddress, bool fromT
const u8 *in = ptr;
// Kind of odd.
u32 size = std::max(head->elf_size, head->psp_size);
newptr = new u8[size];
u32 size = head->psp_size;
if (size > elfSize) {
*error_string = StringFromFormat("ELF/PRX truncated: %d > %d", (int)size, (int)elfSize);
module->Cleanup();
kernelObjects.Destroy<Module>(module->GetUID());
return nullptr;
}
newptr = new u8[std::max(head->elf_size, head->psp_size)];
ptr = newptr;
magicPtr = (u32_le *)ptr;
int ret = pspDecryptPRX(in, (u8*)ptr, head->psp_size);
@@ -1147,8 +1155,9 @@ static Module *__KernelLoadELFFromPtr(const u8 *ptr, u32 loadAddress, bool fromT
error = SCE_KERNEL_ERROR_UNSUPPORTED_PRX_TYPE;
return 0;
}
// Open ELF reader
ElfReader reader((void*)ptr);
ElfReader reader((void*)ptr, elfSize);
int result = reader.LoadInto(loadAddress, fromTop);
if (result != SCE_KERNEL_ERROR_OK) {
@@ -1439,8 +1448,7 @@ static Module *__KernelLoadELFFromPtr(const u8 *ptr, u32 loadAddress, bool fromT
return module;
}
static Module *__KernelLoadModule(u8 *fileptr, SceKernelLMOption *options, std::string *error_string)
{
static Module *__KernelLoadModule(u8 *fileptr, size_t fileSize, SceKernelLMOption *options, std::string *error_string) {
Module *module = 0;
// Check for PBP
if (memcmp(fileptr, "\0PBP", 4) == 0) {
@@ -1455,28 +1463,33 @@ static Module *__KernelLoadModule(u8 *fileptr, SceKernelLMOption *options, std::
for (int i = 1; i < numfiles; i++)
memcpy(&offsets[i], fileptr + 12 + 4*i, 4);
if (offsets[6] > fileSize) {
// File is too small to fully contain the ELF! Must have been truncated.
*error_string = "ELF file truncated - can't load";
return nullptr;
}
u32 magic = 0;
u8 *temp = 0;
u8 *temp = nullptr;
size_t elfSize = offsets[6] - offsets[5];
if (offsets[5] & 3) {
// Our loader does NOT like to load from an unaligned address on ARM!
size_t size = offsets[6] - offsets[5];
temp = new u8[size];
memcpy(temp, fileptr + offsets[5], size);
// Our loader does NOT like to load from an unaligned address on ARM! Copy to a new block.
temp = new u8[elfSize];
memcpy(temp, fileptr + offsets[5], elfSize);
INFO_LOG(LOADER, "PBP: ELF unaligned (%d: %d), aligning!", offsets[5], offsets[5] & 3);
}
u32 error;
module = __KernelLoadELFFromPtr(temp ? temp : fileptr + offsets[5], PSP_GetDefaultLoadAddress(), false, error_string, &magic, error);
module = __KernelLoadELFFromPtr(temp ? temp : fileptr + offsets[5], elfSize, PSP_GetDefaultLoadAddress(), false, error_string, &magic, error);
if (temp) {
delete [] temp;
}
}
else
{
} else {
u32 error;
u32 magic = 0;
module = __KernelLoadELFFromPtr(fileptr, PSP_GetDefaultLoadAddress(), false, error_string, &magic, error);
module = __KernelLoadELFFromPtr(fileptr, fileSize, PSP_GetDefaultLoadAddress(), false, error_string, &magic, error);
}
return module;
@@ -1582,7 +1595,7 @@ bool __KernelLoadExec(const char *filename, u32 paramPtr, std::string *error_str
pspFileSystem.ReadFile(handle, temp, (size_t)info.size);
Module *module = __KernelLoadModule(temp, 0, error_string);
Module *module = __KernelLoadModule(temp, (size_t)info.size, 0, error_string);
if (!module || module->isFake) {
if (module) {
@@ -1797,7 +1810,7 @@ u32 sceKernelLoadModule(const char *name, u32 flags, u32 optionAddr) {
u32 magic;
u32 error;
std::string error_string;
module = __KernelLoadELFFromPtr(temp, 0, lmoption ? lmoption->position == 1 : false, &error_string, &magic, error);
module = __KernelLoadELFFromPtr(temp, (size_t)size, 0, lmoption ? lmoption->position == 1 : false, &error_string, &magic, error);
delete [] temp;
pspFileSystem.CloseFile(handle);
@@ -2243,7 +2256,7 @@ static u32 sceKernelLoadModuleByID(u32 id, u32 flags, u32 lmoptionPtr)
u8 *temp = new u8[size - pos];
pspFileSystem.ReadFile(handle, temp, size - pos);
u32 magic;
module = __KernelLoadELFFromPtr(temp, 0, lmoption ? lmoption->position == 1 : false, &error_string, &magic, error);
module = __KernelLoadELFFromPtr(temp, size - pos, 0, lmoption ? lmoption->position == 1 : false, &error_string, &magic, error);
delete [] temp;
if (!module) {
@@ -2300,7 +2313,7 @@ static SceUID sceKernelLoadModuleBufferUsbWlan(u32 size, u32 bufPtr, u32 flags,
Module *module = 0;
u32 magic;
u32 error;
module = __KernelLoadELFFromPtr(Memory::GetPointer(bufPtr), 0, lmoption ? lmoption->position == 1 : false, &error_string, &magic, error);
module = __KernelLoadELFFromPtr(Memory::GetPointer(bufPtr), size, 0, lmoption ? lmoption->position == 1 : false, &error_string, &magic, error);
if (!module) {
// Some games try to load strange stuff as PARAM.SFO as modules and expect it to fail.