mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-22 10:49:05 +02:00
Refuse to load truncated ~PSP files.
This commit is contained in:
1 parent
57a20f02ed
commit
b1b3b7c9d7
2 files changed
+59
-49
No files matched your search
@@ -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.
|
||||
|
||||
Reference in new issue
Block a user