Skip to content

Commit

Permalink
Merge pull request #19119 from Nemoumbra/prx-libinfo
Browse files Browse the repository at this point in the history
Advanced logging for the ~SCE header modules
  • Loading branch information
hrydgard committed May 9, 2024
2 parents 70394c1 + 8409914 commit 6a493fc
Showing 1 changed file with 64 additions and 1 deletion.
65 changes: 64 additions & 1 deletion Core/HLE/sceKernelModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1150,6 +1150,62 @@ static int gzipDecompress(u8 *OutBuffer, int OutBufferLength, u8 *InBuffer) {
return stream.total_out;
}

static void parsePrxLibInfo(const u8* ptr, u32 headerSize) {
// 0x0 - ~SCE
// 0x4 - the header's size
// At some offset (starting from 0x8) - the lib info
const u8 start = 0x8;
const u8 lib_info_size = 8 + 12 + 4; // The prefix, libname and version

if (headerSize - start < lib_info_size) {
// That's very wrong!
WARN_LOG(SCEMODULE, "~SCE module, header too small (0x%x bytes) to fit a lib info", headerSize);
return;
}

auto end = ptr + headerSize;
ptr += start;
while (*ptr == 0x0 && ptr < end) {
++ptr;
}

// Now that we have found the start, let's do one more check
if (end - ptr < lib_info_size) {
// That's very wrong!
WARN_LOG(SCEMODULE, "~SCE module, unexpected header (not an error)");
return;
}

// The lib info prefix looks like {'\', 'y', 'r', '=', '`', 'c', '`', '0'} (Big Endian)
const u64_le lib_info_prefix = 0x306063603D72795C;
auto lib_info_ptr = reinterpret_cast<const u64_le*>(ptr);
if (*lib_info_ptr != lib_info_prefix) {
// That's very wrong!
WARN_LOG(SCEMODULE, "~SCE module, unexpected header (not an error)");
return;
}
ptr += sizeof(lib_info_prefix);

// Decipher the Caesar cipher with sanity checks (isprint)

u8 nameBuffer[12 + 1];
for (int i = 0; i < 12; ++i, ++ptr) {
u8 symbol = *ptr - 0x12u;
nameBuffer[i] = isprint(symbol) ? symbol : '?';
}
nameBuffer[12] = '\0';

u8 versionBuffer[8] = "?.?.?.?";
for (int i = 0; i < 4; ++i, ++ptr) {
u8 symbol = *ptr - 0x14u;
if (isprint(symbol)) {
versionBuffer[2 * i] = symbol;
}
}

INFO_LOG(SCEMODULE, "~SCE module: Lib-PSP %s (SDK %s)", nameBuffer, versionBuffer);
}

static PSPModule *__KernelLoadELFFromPtr(const u8 *ptr, size_t elfSize, u32 loadAddress, bool fromTop, std::string *error_string, u32 *magic, u32 &error) {
PSPModule *module = new PSPModule();
kernelObjects.Create(module);
Expand All @@ -1164,13 +1220,20 @@ static PSPModule *__KernelLoadELFFromPtr(const u8 *ptr, size_t elfSize, u32 load
u8 *newptr = 0;
u32_le *magicPtr = (u32_le *) ptr;
if (*magicPtr == 0x4543537e) { // "~SCE"
INFO_LOG(SCEMODULE, "~SCE module, skipping header");

u32 headerSize = *(u32_le*)(ptr + 4);
if (headerSize < elfSize) {
// Parse and print the lib info
parsePrxLibInfo(ptr, headerSize);

// Advance the pointer to the relevant data
ptr += headerSize;
elfSize -= headerSize;
magicPtr = (u32_le *)ptr;
}
else {
ERROR_LOG(SCEMODULE, "~SCE module: bad data");
}
}
*magic = *magicPtr;
if (*magic == 0x5053507e && elfSize > sizeof(PSP_Header)) { // "~PSP"
Expand Down

0 comments on commit 6a493fc

Please sign in to comment.