diff --git a/arm9/source/patches/arm7/CardiTaskThreadPatchAsm.h b/arm9/source/patches/arm7/CardiTaskThreadPatchAsm.h index 21df462..29ac1b7 100644 --- a/arm9/source/patches/arm7/CardiTaskThreadPatchAsm.h +++ b/arm9/source/patches/arm7/CardiTaskThreadPatchAsm.h @@ -13,3 +13,4 @@ extern u32 __patch_carditaskthread_failoffset; extern u32 __patch_carditaskthread_successoffset; extern u32 __patch_carditaskthread_readsave_asm_address; extern u32 __patch_carditaskthread_writesave_asm_address; +extern u32 __patch_carditaskthread_verifysave_asm_address; diff --git a/arm9/source/patches/arm7/CardiTaskThreadPatchAsm.s b/arm9/source/patches/arm7/CardiTaskThreadPatchAsm.s index 0778869..22de3ba 100644 --- a/arm9/source/patches/arm7/CardiTaskThreadPatchAsm.s +++ b/arm9/source/patches/arm7/CardiTaskThreadPatchAsm.s @@ -93,8 +93,17 @@ write_backup: verify_backup: ldr r0, [r4] - movs r1, #0 - str r1, [r0] // result + ldr r2, [r0, #0xC] // src + ldr r1, [r0, #0x10] // dst + ldr r3, [r0, #0x14] // len + cmp r3, #0 + beq end_success + + push {r0} + ldr r0, __patch_carditaskthread_verifysave_asm_address + bl blx_r0 + pop {r1} + str r0, [r1] // result b end_success blx_r0: @@ -118,6 +127,10 @@ __patch_carditaskthread_readsave_asm_address: __patch_carditaskthread_writesave_asm_address: .word 0 +.global __patch_carditaskthread_verifysave_asm_address +__patch_carditaskthread_verifysave_asm_address: + .word 0 + .pool .end \ No newline at end of file diff --git a/arm9/source/patches/arm7/VerifySaveAsm.h b/arm9/source/patches/arm7/VerifySaveAsm.h new file mode 100644 index 0000000..9d1e06f --- /dev/null +++ b/arm9/source/patches/arm7/VerifySaveAsm.h @@ -0,0 +1,31 @@ +#pragma once +#include "sections.h" +#include "../PatchCode.h" +#include "../SectorRemapPatchCode.h" +#include "../platform/SdReadPatchCode.h" + +DEFINE_SECTION_SYMBOLS(verifysave); + +extern "C" void verifysave_asm(u32, u32 saveSrc, void* memoryDst, u32 byteLength); + +extern u32 verifysave_tmpBufferPtr; +extern u32 verifysave_save_offset_to_sd_sector_asm_address; +extern u32 verifysave_sdread_asm_address; + +class VerifySavePatchCode : public PatchCode +{ +public: + VerifySavePatchCode(PatchHeap& patchHeap, const SectorRemapPatchCode* sectorRemapPatchCode, + const SdReadPatchCode* sdReadPatchCode, void* tmpBuffer) + : PatchCode(SECTION_START(verifysave), SECTION_SIZE(verifysave), patchHeap) + { + verifysave_save_offset_to_sd_sector_asm_address = (u32)sectorRemapPatchCode->GetRemapFunction(); + verifysave_sdread_asm_address = (u32)sdReadPatchCode->GetSdReadFunction(); + verifysave_tmpBufferPtr = (u32)tmpBuffer; + } + + const void* GetVerifySaveFunction() const + { + return GetAddressAtTarget((void*)verifysave_asm); + } +}; diff --git a/arm9/source/patches/arm7/VerifySaveAsm.s b/arm9/source/patches/arm7/VerifySaveAsm.s new file mode 100644 index 0000000..6f01f54 --- /dev/null +++ b/arm9/source/patches/arm7/VerifySaveAsm.s @@ -0,0 +1,83 @@ +.cpu arm7tdmi +.section "verifysave", "ax" +.syntax unified +.thumb + +// r1 = save src +// r2 = memory src +// r3 = byte length +.global verifysave_asm +.type verifysave_asm, %function +verifysave_asm: + push {r4,r5,r6,r7,lr} + movs r4, r3 // remaining bytes + movs r5, r1 + movs r6, r2 +1: + movs r0, r5 // will be rounded down by function + ldr r3, verifysave_save_offset_to_sd_sector_asm_address + bl blx_r3 + cmp r0, #0 + beq end // out of bounds + + ldr r1, verifysave_tmpBufferPtr + movs r2, #1 // single sector + lsls r7, r2, #9 // 512 + ldr r3, verifysave_sdread_asm_address + bl blx_r3 + + // verify bytes + lsls r2, r5, #23 + lsrs r2, r2, #23 // r2 = byte offset in sector + subs r0, r6, r2 + subs r7, r7, r2 // remaining in sector + cmp r7, r4 // if remaining in sector > requested read length + bls 2f + movs r7, r4 // clamp to requested read length +2: + subs r4, r7 + adds r5, r7 + adds r6, r7 + ldr r1, verifysave_tmpBufferPtr + +3: + ldrb r3, [r1, r2] + mov lr, r3 + ldrb r3, [r0, r2] + cmp lr, r3 + bne bad_end + adds r2, #1 + subs r7, #1 + bne 3b + + cmp r4, #0 + bne 1b + +end: + movs r0, #0 + pop {r4,r5,r6,r7,pc} + +bad_end: + movs r0, #1 + pop {r4,r5,r6,r7,pc} + +blx_r3: + bx r3 + +.balign 4 + +.global verifysave_tmpBufferPtr +verifysave_tmpBufferPtr: + .word 0 + +.global verifysave_save_offset_to_sd_sector_asm_address +verifysave_save_offset_to_sd_sector_asm_address: + .word 0 + +.global verifysave_sdread_asm_address +verifysave_sdread_asm_address: + .word 0 + +.pool + +.end \ No newline at end of file diff --git a/arm9/source/patches/arm7/sdk2to4/CardiTaskThreadPatch.cpp b/arm9/source/patches/arm7/sdk2to4/CardiTaskThreadPatch.cpp index deb42eb..676a3a2 100644 --- a/arm9/source/patches/arm7/sdk2to4/CardiTaskThreadPatch.cpp +++ b/arm9/source/patches/arm7/sdk2to4/CardiTaskThreadPatch.cpp @@ -5,6 +5,7 @@ #include "patches/PatchContext.h" #include "patches/arm7/ReadSaveAsm.h" #include "patches/arm7/WriteSaveAsm.h" +#include "patches/arm7/VerifySaveAsm.h" #include "patches/FunctionSignature.h" #include "patches/platform/LoaderPlatform.h" #include "patches/arm7/SaveOffsetToSdSectorAsm.h" @@ -131,9 +132,16 @@ void CardiTaskThreadPatch::ApplyPatch(PatchContext& patchContext) writePatchCode, tmpBuffer ); + auto verifySavePatchCode = patchContext.GetPatchCodeCollection().AddUniquePatchCode( + patchContext.GetPatchHeap(), + sectorRemapPatchCode, + readPatchCode, + tmpBuffer + ); __patch_carditaskthread_readsave_asm_address = (u32)readSavePatchCode->GetReadSaveFunction(); __patch_carditaskthread_writesave_asm_address = (u32)writeSavePatchCode->GetWriteSaveFunction(); + __patch_carditaskthread_verifysave_asm_address = (u32)verifySavePatchCode->GetVerifySaveFunction(); u32 entryAddress; u32 patchOffset; diff --git a/arm9/source/patches/arm7/sdk5/CardiDoTaskFromArm9Patch.cpp b/arm9/source/patches/arm7/sdk5/CardiDoTaskFromArm9Patch.cpp index 1bb557e..7f32292 100644 --- a/arm9/source/patches/arm7/sdk5/CardiDoTaskFromArm9Patch.cpp +++ b/arm9/source/patches/arm7/sdk5/CardiDoTaskFromArm9Patch.cpp @@ -4,6 +4,7 @@ #include "fileInfo.h" #include "patches/arm7/ReadSaveAsm.h" #include "patches/arm7/WriteSaveAsm.h" +#include "patches/arm7/VerifySaveAsm.h" #include "patches/arm7/SaveOffsetToSdSectorAsm.h" #include "patches/platform/LoaderPlatform.h" #include "patches/OffsetToSectorRemapAsm.h" @@ -82,9 +83,16 @@ void CardiDoTaskFromArm9Patch::ApplyPatch(PatchContext& patchContext) writePatchCode, tmpBuffer ); + auto verifySavePatchCode = patchContext.GetPatchCodeCollection().AddUniquePatchCode( + patchContext.GetPatchHeap(), + sectorRemapPatchCode, + readPatchCode, + tmpBuffer + ); __patch_carditaskthread_readsave_asm_address = (u32)readSavePatchCode->GetReadSaveFunction(); __patch_carditaskthread_writesave_asm_address = (u32)writeSavePatchCode->GetWriteSaveFunction(); + __patch_carditaskthread_verifysave_asm_address = (u32)verifySavePatchCode->GetVerifySaveFunction(); u32 patchOffset;