diff --git a/arm7/source/loader/NdsLoader.cpp b/arm7/source/loader/NdsLoader.cpp index 717692f..58804e3 100644 --- a/arm7/source/loader/NdsLoader.cpp +++ b/arm7/source/loader/NdsLoader.cpp @@ -165,9 +165,9 @@ void NdsLoader::Load(BootMode bootMode) } } - bool isHomebrew = (_romHeader.ntrHeader.makerCode[0] == 0 && _romHeader.ntrHeader.makerCode[1] == 0) - || _romHeader.ntrHeader.arm9AutoLoadDoneHookAddress == 0 - || _romHeader.ntrHeader.arm7LoadAddress >= 0x03000000; + bool isHomebrew = (_romHeader.makerCode[0] == 0 && _romHeader.makerCode[1] == 0) + || _romHeader.arm9AutoLoadDoneHookAddress == 0 + || _romHeader.arm7LoadAddress >= 0x03000000; if (isHomebrew) { @@ -186,16 +186,7 @@ void NdsLoader::Load(BootMode bootMode) memset(&_dsiwareSaveResult, 0, sizeof(_dsiwareSaveResult)); if (bootMode != BootMode::Multiboot) { - if (!_romHeader.IsDsiWare()) - { - if (bootMode != BootMode::SdkResetSystem) - { - HandleCardSave(); - } - - HandleAntiPiracy(); - } - else + if (_romHeader.IsDsiWare()) { if (bootMode == BootMode::SdkResetSystem) { @@ -210,6 +201,15 @@ void NdsLoader::Load(BootMode bootMode) return; } } + else + { + if (bootMode != BootMode::SdkResetSystem) + { + HandleCardSave(); + } + + HandleAntiPiracy(); + } } } @@ -224,14 +224,14 @@ void NdsLoader::Load(BootMode bootMode) SetupSharedMemory(cardId, agbMem, resetParam, romOffset, bootType); - if (Environment::IsDsiMode() && _romHeader.IsTwlRom()) - { - SetupTwlConfig(); - TwlAes().SetupAes(&_romHeader); - } - if (Environment::IsDsiMode()) { + if (_romHeader.IsTwlRom()) + { + SetupTwlConfig(); + TwlAes().SetupAes(&_romHeader); + } + RemapWram(); } @@ -321,20 +321,20 @@ void NdsLoader::Load(BootMode bootMode) if (Environment::IsDsiMode()) { - if (!_romHeader.IsTwlRom()) - { - DSMode().SwitchToDSMode(_romHeader.ntrHeader.gameCode); - } - else + if (_romHeader.IsTwlRom()) { if (!(_romHeader.twlFlags2 & 1)) { - DSMode().SwitchToDSTouchAndSoundMode(_romHeader.ntrHeader.gameCode); + DSMode().SwitchToDSTouchAndSoundMode(_romHeader.gameCode); } // Set back power button handling to irq mode mcu_writeReg(MCU_REG_MODE, 1); } + else + { + DSMode().SwitchToDSMode(_romHeader.gameCode); + } } if (isHomebrew) @@ -349,11 +349,11 @@ void NdsLoader::Load(BootMode bootMode) bool NdsLoader::IsCloneBootRom(u32 romOffset) { bool isCloneBootRom = false; - if (_romHeader.ntrHeader.ntrRomSize != 0) + if (_romHeader.ntrRomSize != 0) { UINT bytesRead = 0; u16 signatureHeader; - if (f_lseek(&_romFile, romOffset + _romHeader.ntrHeader.ntrRomSize) == FR_OK && + if (f_lseek(&_romFile, romOffset + _romHeader.ntrRomSize) == FR_OK && f_read(&_romFile, &signatureHeader, sizeof(signatureHeader), &bytesRead) == FR_OK && bytesRead == 2 && signatureHeader == 0x6361) @@ -371,7 +371,7 @@ void NdsLoader::InsertArgv() u32 argSize = 0; // Find the address to write argv - u32 argDst = ((_romHeader.ntrHeader.arm9LoadAddress + _romHeader.ntrHeader.arm9Size + 3) & ~3) + 4; + u32 argDst = ((_romHeader.arm9LoadAddress + _romHeader.arm9Size + 3) & ~3) + 4; if (_romHeader.IsTwlRom()) { u32 argDstTwl = ((_romHeader.arm9iLoadAddress + _romHeader.arm9iSize + 3) & ~3) + 4; @@ -475,8 +475,8 @@ void NdsLoader::SetupSharedMemory(u32 cardId, u32 agbMem, u32 resetParam, u32 ro memcpy(TWL_SHARED_MEMORY->ntrSharedMem.romHeader, &_romHeader, sizeof(nds_header_ntr_t)); *(vu32*)&TWL_SHARED_MEMORY->ntrSharedMem.bootCheckInfo[0] = cardId; *(vu32*)&TWL_SHARED_MEMORY->ntrSharedMem.bootCheckInfo[4] = cardId; - *(vu16*)&TWL_SHARED_MEMORY->ntrSharedMem.bootCheckInfo[8] = _romHeader.ntrHeader.headerCrc; - *(vu16*)&TWL_SHARED_MEMORY->ntrSharedMem.bootCheckInfo[0xA] = _romHeader.ntrHeader.secureAreaCrc; + *(vu16*)&TWL_SHARED_MEMORY->ntrSharedMem.bootCheckInfo[8] = _romHeader.headerCrc; + *(vu16*)&TWL_SHARED_MEMORY->ntrSharedMem.bootCheckInfo[0xA] = _romHeader.secureAreaCrc; *(vu32*)&TWL_SHARED_MEMORY->ntrSharedMem.bootCheckInfo[0x10] = 0x5835; // use correct card id address *(vu32*)&TWL_SHARED_MEMORY->ntrSharedMem.isDebuggerData[0x1C] = agbMem; TWL_SHARED_MEMORY->ntrSharedMem.resetParam = resetParam; @@ -536,7 +536,7 @@ bool NdsLoader::ShouldAttemptDldiPatch() { // Some games contain a fake dldi header to trick flashcards // See also: https://shutterbug2000.github.io/very-clever/ - switch (_romHeader.ntrHeader.gameCode) + switch (_romHeader.gameCode) { // Final Fantasy IV case GAMECODE("YF4P"): @@ -610,7 +610,7 @@ bool NdsLoader::TryLoadRomHeader(u32 romOffset) void NdsLoader::HandleCardSave() { - if (!CardSaveArranger().SetupCardSave(_romHeader.ntrHeader.gameCode, _savePath)) + if (!CardSaveArranger().SetupCardSave(_romHeader.gameCode, _savePath)) { ErrorDisplay().PrintError("Failed to setup save file."); } @@ -621,7 +621,7 @@ void NdsLoader::HandleAntiPiracy() auto apList = ApListFactory().CreateFromFile(AP_LIST_PATH); if (apList) { - auto entry = apList->FindEntry(_romHeader.ntrHeader.gameCode, _romHeader.ntrHeader.softwareVersion); + auto entry = apList->FindEntry(_romHeader.gameCode, _romHeader.softwareVersion); if (entry) { entry->Dump(); @@ -683,15 +683,15 @@ void NdsLoader::RemapWram() bool NdsLoader::TryLoadArm9() { - if (f_lseek(&_romFile, _romHeader.ntrHeader.arm9RomOffset + TWL_SHARED_MEMORY->ntrSharedMem.romOffset) != FR_OK) + if (f_lseek(&_romFile, _romHeader.arm9RomOffset + TWL_SHARED_MEMORY->ntrSharedMem.romOffset) != FR_OK) { LOG_FATAL("Failed to seek to arm9\n"); return false; } UINT bytesRead = 0; - FRESULT result = f_read(&_romFile, (void*)_romHeader.ntrHeader.arm9LoadAddress, _romHeader.ntrHeader.arm9Size, &bytesRead); - if (result != FR_OK || bytesRead != _romHeader.ntrHeader.arm9Size) + FRESULT result = f_read(&_romFile, (void*)_romHeader.arm9LoadAddress, _romHeader.arm9Size, &bytesRead); + if (result != FR_OK || bytesRead != _romHeader.arm9Size) { LOG_FATAL("Failed to read arm9. Result: %d, bytesRead: %d\n", result, bytesRead); return false; @@ -736,7 +736,7 @@ bool NdsLoader::TryLoadArm9i() bool NdsLoader::TryDecryptArm9i() { - if (!(_romHeader.ntrHeader.twlFlags & (1 << 1))) + if (!(_romHeader.twlFlags & (1 << 1))) { return true; } @@ -756,7 +756,7 @@ bool NdsLoader::TryDecryptArm9i() bool NdsLoader::TryDecryptArm7i() { - if (!(_romHeader.ntrHeader.twlFlags & (1 << 1)) || _romHeader.modcryptArea2Size == 0) + if (!(_romHeader.twlFlags & (1 << 1)) || _romHeader.modcryptArea2Size == 0) { return true; } @@ -776,15 +776,15 @@ bool NdsLoader::TryDecryptArm7i() bool NdsLoader::TryLoadArm7() { - if (f_lseek(&_romFile, _romHeader.ntrHeader.arm7RomOffset + TWL_SHARED_MEMORY->ntrSharedMem.romOffset) != FR_OK) + if (f_lseek(&_romFile, _romHeader.arm7RomOffset + TWL_SHARED_MEMORY->ntrSharedMem.romOffset) != FR_OK) { LOG_FATAL("Failed to seek to arm7\n"); return false; } UINT bytesRead = 0; - FRESULT result = f_read(&_romFile, (void*)_romHeader.ntrHeader.arm7LoadAddress, _romHeader.ntrHeader.arm7Size, &bytesRead); - if (result != FR_OK || bytesRead != _romHeader.ntrHeader.arm7Size) + FRESULT result = f_read(&_romFile, (void*)_romHeader.arm7LoadAddress, _romHeader.arm7Size, &bytesRead); + if (result != FR_OK || bytesRead != _romHeader.arm7Size) { LOG_FATAL("Failed to read arm7. Result: %d, bytesRead: %d\n", result, bytesRead); return false; @@ -828,19 +828,19 @@ void NdsLoader::HandleDldiPatching() } int arm9DldiAddr = sDldiStubMatcher.FindFirstOccurance( - (const u32*)_romHeader.ntrHeader.arm9LoadAddress, _romHeader.ntrHeader.arm9Size >> 2) << 2; + (const u32*)_romHeader.arm9LoadAddress, _romHeader.arm9Size >> 2) << 2; if (arm9DldiAddr >= 0) { - dldi_header_t* arm9Dldi = (dldi_header_t*)(_romHeader.ntrHeader.arm9LoadAddress + arm9DldiAddr); + dldi_header_t* arm9Dldi = (dldi_header_t*)(_romHeader.arm9LoadAddress + arm9DldiAddr); LOG_DEBUG("Dldi found in arm9 at address %p\n", arm9Dldi); dldi_patchTo(arm9Dldi); } int arm7DldiAddr = sDldiStubMatcher.FindFirstOccurance( - (const u32*)_romHeader.ntrHeader.arm7LoadAddress, _romHeader.ntrHeader.arm7Size >> 2) << 2; + (const u32*)_romHeader.arm7LoadAddress, _romHeader.arm7Size >> 2) << 2; if (arm7DldiAddr >= 0) { - dldi_header_t* arm7Dldi = (dldi_header_t*)(_romHeader.ntrHeader.arm7LoadAddress + arm7DldiAddr); + dldi_header_t* arm7Dldi = (dldi_header_t*)(_romHeader.arm7LoadAddress + arm7DldiAddr); LOG_DEBUG("Dldi found in arm7 at address %p\n", arm7Dldi); dldi_patchTo(arm7Dldi); } @@ -860,7 +860,7 @@ void NdsLoader::StartRom(BootMode bootMode) REG_IF2 = ~0u; } - ((entrypoint_t)_romHeader.ntrHeader.arm7EntryAddress)(); + ((entrypoint_t)_romHeader.arm7EntryAddress)(); } void NdsLoader::SetupTwlConfig() @@ -970,20 +970,20 @@ bool NdsLoader::TrySetupDsiWareSave() bool NdsLoader::TryDecryptSecureArea() { - if (_romHeader.ntrHeader.arm9RomOffset < 0x4000 || _romHeader.ntrHeader.arm9RomOffset >= 0x8000) + if (_romHeader.arm9RomOffset < 0x4000 || _romHeader.arm9RomOffset >= 0x8000) { return true; } - if (((u32*)_romHeader.ntrHeader.arm9LoadAddress)[0] == 0xE7FFDEFF && - ((u32*)_romHeader.ntrHeader.arm9LoadAddress)[1] == 0xE7FFDEFF) + if (((u32*)_romHeader.arm9LoadAddress)[0] == 0xE7FFDEFF && + ((u32*)_romHeader.arm9LoadAddress)[1] == 0xE7FFDEFF) { return true; } u16 secureAreaCrc = swi_getCrc16(0xFFFF, - (const void*)_romHeader.ntrHeader.arm9LoadAddress, 0x8000 - _romHeader.ntrHeader.arm9RomOffset); - if (secureAreaCrc != _romHeader.ntrHeader.secureAreaCrc) + (const void*)_romHeader.arm9LoadAddress, 0x8000 - _romHeader.arm9RomOffset); + if (secureAreaCrc != _romHeader.secureAreaCrc) { return true; } @@ -1000,13 +1000,13 @@ bool NdsLoader::TryDecryptSecureArea() } auto blowfish = std::make_unique(keyTable.get()); - blowfish->TransformTable(_romHeader.ntrHeader.gameCode, 3, 8); + blowfish->TransformTable(_romHeader.gameCode, 3, 8); blowfish->Decrypt( - (const void*)_romHeader.ntrHeader.arm9LoadAddress, - (void*)_romHeader.ntrHeader.arm9LoadAddress, - 0x4800 - _romHeader.ntrHeader.arm9RomOffset); - ((u32*)_romHeader.ntrHeader.arm9LoadAddress)[0] = 0xE7FFDEFF; - ((u32*)_romHeader.ntrHeader.arm9LoadAddress)[1] = 0xE7FFDEFF; + (const void*)_romHeader.arm9LoadAddress, + (void*)_romHeader.arm9LoadAddress, + 0x4800 - _romHeader.arm9RomOffset); + ((u32*)_romHeader.arm9LoadAddress)[0] = 0xE7FFDEFF; + ((u32*)_romHeader.arm9LoadAddress)[1] = 0xE7FFDEFF; LOG_DEBUG("Decrypted secure area\n"); return true; diff --git a/arm7/source/loader/TwlAes.cpp b/arm7/source/loader/TwlAes.cpp index 7f9f838..aa4499e 100644 --- a/arm7/source/loader/TwlAes.cpp +++ b/arm7/source/loader/TwlAes.cpp @@ -104,7 +104,7 @@ void TwlAes::DecryptModuleAes(void* data, u32 length, const aes_u128_t* iv) cons void TwlAes::SetupModuleKeyXY(const nds_header_twl_t* romHeader) const { - if ((romHeader->ntrHeader.twlFlags & (1 << 2)) || (romHeader->twlFlags2 & (1 << 7))) + if ((romHeader->twlFlags & (1 << 2)) || (romHeader->twlFlags2 & (1 << 7))) { // debug aes_setKey(KEY_SLOT_MODULE, (const aes_u128_t*)romHeader); @@ -116,8 +116,8 @@ void TwlAes::SetupModuleKeyXY(const nds_header_twl_t* romHeader) const { MODULE_KEYX_NINT, MODULE_KEYX_ENDO, - romHeader->ntrHeader.gameCode, - __builtin_bswap32(romHeader->ntrHeader.gameCode) + romHeader->gameCode, + __builtin_bswap32(romHeader->gameCode) }}; aes_setKeyXY(KEY_SLOT_MODULE, &keyX, (const aes_u128_t*)romHeader->arm9iSha1Hmac); } diff --git a/arm9/source/Arm7Patcher.cpp b/arm9/source/Arm7Patcher.cpp index 3b3f453..9acfca1 100644 --- a/arm9/source/Arm7Patcher.cpp +++ b/arm9/source/Arm7Patcher.cpp @@ -49,15 +49,18 @@ void* Arm7Patcher::ApplyPatches(const LoaderPlatform* loaderPlatform) const patchCollection.AddPatch(arm7ArenaPatch); if (romHeader->unitCode == 0) // seems only present on NITRO, not on HYBRID or LIMITED + { patchCollection.AddPatch(new DisableArm7WramClearPatch()); + } if (sdkVersion.IsTwlSdk()) { - if (gIsDsiMode && romHeader->IsTwlRom() && twlRomHeader->IsDsiWare()) + if (gIsDsiMode && (twlRomHeader->HasNandAccess() || twlRomHeader->HasSdAccess())) { patchCollection.AddPatch(new Sdk5DsiSdCardRedirectPatch()); } - else + + if (!twlRomHeader->IsDsiWare()) { patchCollection.AddPatch(new CardiDoTaskFromArm9Patch()); } diff --git a/arm9/source/Arm9Patcher.cpp b/arm9/source/Arm9Patcher.cpp index b76c896..5759602 100644 --- a/arm9/source/Arm9Patcher.cpp +++ b/arm9/source/Arm9Patcher.cpp @@ -153,14 +153,13 @@ void Arm9Patcher::ApplyPatches(const LoaderPlatform* loaderPlatform, const ApLis } else { - SecureSysCallsUnusedSpaceLocator secureSysCallsUnusedSpaceLocator; - secureSysCallsUnusedSpaceLocator.FindUnusedSpace(romHeader, patchContext.GetPatchHeap()); + SecureSysCallsUnusedSpaceLocator().FindUnusedSpace(romHeader, patchContext.GetPatchHeap()); } } if (sdkVersion.IsTwlSdk()) { - if (!(romHeader->IsTwlRom() && twlRomHeader->IsDsiWare())) + if (!twlRomHeader->IsDsiWare()) { // if ((romHeader->unitCode & 3) != 3) { @@ -168,7 +167,7 @@ void Arm9Patcher::ApplyPatches(const LoaderPlatform* loaderPlatform, const ApLis } patchCollection.AddPatch(new CardiReadRomWithCpuPatch()); - if (gIsDsiMode && (romHeader->unitCode & 2)) + if (gIsDsiMode && romHeader->IsTwlRom()) { patchCollection.AddPatch(new CardiReadCardWithHashInternalAsyncPatch()); } diff --git a/arm9/source/patches/arm7/sdk5/Sdk5DsiSdCardRedirectPatch.cpp b/arm9/source/patches/arm7/sdk5/Sdk5DsiSdCardRedirectPatch.cpp index 2439b5c..51c502e 100644 --- a/arm9/source/patches/arm7/sdk5/Sdk5DsiSdCardRedirectPatch.cpp +++ b/arm9/source/patches/arm7/sdk5/Sdk5DsiSdCardRedirectPatch.cpp @@ -67,7 +67,7 @@ static u32 correctAddressForArm7iAutoLoad(u32 address) { auto romHeader = (const nds_header_twl_t*)TWL_SHARED_MEMORY->twlRomHeader; auto arm7iModuleParams = (const module_params_twl_t*)( - romHeader->ntrHeader.arm7LoadAddress + romHeader->arm7iModuleParamsAddress); + romHeader->arm7LoadAddress + romHeader->arm7iModuleParamsAddress); auto autoLoadListEntry = (autoload_list_entry_sdk5_t*)arm7iModuleParams->autoloadListStart; u32 currentAddress = arm7iModuleParams->autoloadStart; diff --git a/common/ndsHeader.h b/common/ndsHeader.h index dffb821..4a1f41e 100644 --- a/common/ndsHeader.h +++ b/common/ndsHeader.h @@ -63,9 +63,11 @@ struct nds_header_ntr_t static_assert(sizeof(nds_header_ntr_t) == 0x170, "Invalid size for nds_header_ntr_t"); -struct nds_header_twl_t +#define NDS_HEADER_TWL_ACCESS_CONTROL_SD_ACCESS (1 << 3) +#define NDS_HEADER_TWL_ACCESS_CONTROL_NAND_ACCESS (1 << 4) + +struct nds_header_twl_t : public nds_header_ntr_t { - nds_header_ntr_t ntrHeader; u8 gap170[0x10]; u32 globalMbkSettings[5]; // slot mapping u32 arm9MbkSettings[3]; // wram mapping @@ -130,14 +132,19 @@ struct nds_header_twl_t u8 gapF00[0x80]; u8 headerRsaSha1Signature[0x80]; - constexpr bool IsTwlRom() const - { - return ntrHeader.IsTwlRom(); - } - constexpr bool IsDsiWare() const { - return IsTwlRom() && ((titleId >> 32) & 0xFF) != 0; + return IsTwlRom() && ((titleId >> 32) & 4) != 0; + } + + constexpr bool HasSdAccess() const + { + return IsTwlRom() && (accessControl & NDS_HEADER_TWL_ACCESS_CONTROL_SD_ACCESS) != 0; + } + + constexpr bool HasNandAccess() const + { + return IsTwlRom() && (accessControl & NDS_HEADER_TWL_ACCESS_CONTROL_NAND_ACCESS) != 0; } };