Improved handling of module params and locating of unused libsyscall space to support rom hacks that repack roms in unusual ways. Fixes #129

This commit is contained in:
Gericom
2026-02-01 11:04:59 +01:00
parent f5a8498e08
commit df614fb89f
4 changed files with 100 additions and 93 deletions

View File

@@ -1,19 +1,26 @@
#include "common.h"
#include "ModuleParamsLocator.h"
module_params_ntr_t* ModuleParamsLocator::FindModuleParams(const nds_header_ntr_t* romHeader)
static bool isValidArm9Address(const nds_header_ntr_t* romHeader, const void* address)
{
return romHeader->arm9LoadAddress <= (u32)address && (u32)address < romHeader->arm9LoadAddress + romHeader->arm9Size;
}
module_params_ntr_t* ModuleParamsLocator::FindModuleParams(const nds_header_ntr_t* romHeader) const
{
//todo: static footer
module_params_ntr_t* moduleParams = nullptr;
if (romHeader->arm9ModuleParamsAddress != 0)
{
moduleParams = (module_params_ntr_t*)(romHeader->arm9LoadAddress + romHeader->arm9ModuleParamsAddress);
if (moduleParams->magicBigEndian != MODULE_PARAMS_NTR_MAGIC_BE ||
if (!isValidArm9Address(romHeader, &moduleParams->magicLittleEndian) ||
moduleParams->magicBigEndian != MODULE_PARAMS_NTR_MAGIC_BE ||
moduleParams->magicLittleEndian != MODULE_PARAMS_NTR_MAGIC_LE)
{
// try again by subtracting arm9 rom address
moduleParams = (module_params_ntr_t*)((u8*)moduleParams - romHeader->arm9RomOffset);
if (moduleParams->magicBigEndian != MODULE_PARAMS_NTR_MAGIC_BE ||
if (!isValidArm9Address(romHeader, &moduleParams->magicLittleEndian) ||
moduleParams->magicBigEndian != MODULE_PARAMS_NTR_MAGIC_BE ||
moduleParams->magicLittleEndian != MODULE_PARAMS_NTR_MAGIC_LE)
{
LOG_DEBUG("Module params not found at header specified offset 0x%x\n", romHeader->arm9ModuleParamsAddress);
@@ -29,21 +36,6 @@ module_params_ntr_t* ModuleParamsLocator::FindModuleParams(const nds_header_ntr_
if (!moduleParams)
{
// try searching for the module params as not all roms have the address in the header
// it should be within the first 0x1000 bytes of the arm9
for (u32 i = 0; i < 0x1000; i += 4)
{
u32* ptr = (u32*)(romHeader->arm9LoadAddress + i);
if (ptr[0] == MODULE_PARAMS_NTR_MAGIC_BE && ptr[1] == MODULE_PARAMS_NTR_MAGIC_LE)
{
moduleParams = (module_params_ntr_t*)((u8*)ptr + 8 - sizeof(module_params_ntr_t));
break;
}
}
}
if (!moduleParams)
{
// as a last resort, scan the entire arm9 binary
for (u32 i = 0; i < romHeader->arm9Size; i += 4)
{
u32* ptr = (u32*)(romHeader->arm9LoadAddress + i);
@@ -53,6 +45,11 @@ module_params_ntr_t* ModuleParamsLocator::FindModuleParams(const nds_header_ntr_
break;
}
}
if (moduleParams != nullptr && (u32)moduleParams - romHeader->arm9LoadAddress > 0x1000)
{
LOG_WARNING("Module params not found in first 0x1000 bytes of arm9\n");
}
}
return moduleParams;