diff --git a/arm9/source/patches/arm7/cheats/CheatEnginePatch.cpp b/arm9/source/patches/arm7/cheats/CheatEnginePatch.cpp index 0659c10..b680769 100644 --- a/arm9/source/patches/arm7/cheats/CheatEnginePatch.cpp +++ b/arm9/source/patches/arm7/cheats/CheatEnginePatch.cpp @@ -3,89 +3,38 @@ #include "CheatEnginePatchCode.h" #include "CheatEnginePatch.h" -// sdk2-4 -static const u32 sVBlankIntrPatternArm0[] = { 0xE92D4000u, 0xE24DD004u, 0xE59F0018u, 0xE5900000u }; -static const u32 sVBlankIntrPatternArm1[] = { 0xE92D4008u, 0xE59F0014u, 0xE5900000u, 0xE3500000u }; -static const u32 sVBlankIntrPatternThumb0[] = { 0x00000000u, 0xB081B500u, 0x68004804u, 0xD0012800u }; // +4 -static const u32 sVBlankIntrPatternThumb1[] = { 0x46C04770u, 0x027FFE1Du, 0x4804B508u, 0x28006800u }; // +8 -static const u32 sVBlankIntrPatternThumb2[] = { 0x46C04718u, 0x0000FFFFu, 0x4804B508u, 0x28006800u }; // +8 -static const u32 sVBlankIntrPatternThumb3[] = { 0xE51FF004u, 0x037FD67Cu, 0x4804B508u, 0x28006800u }; // +8 -static const u32 sVBlankIntrPatternThumb4[] = { 0x46C04770u, 0x02FFFE1Du, 0x4804B508u, 0x28006800u }; // +8 -static const u32 sVBlankIntrPatternThumb5[] = { 0xE51FF004u, 0x037FA868u, 0x4804B508u, 0x28006800u }; // +8 +static const u32 sOSiIrqVBlankPattern0[] = { 0xE92D4008u, 0xE59F2038u, 0xE59F0038u, 0xE5921000u }; +static const u32 sOSiIrqVBlankPattern1[] = { 0xE92D4000u, 0xE24DD004u, 0xE59F003Cu, 0xE5902060u }; +static const u32 sOSiIrqVBlankPatternThumb0[] = { 0x4809B508u, 0x69024909u, 0x1C406808u, 0x2A006008u }; bool CheatEnginePatch::FindPatchTarget(PatchContext& patchContext) { - _vblankIrqHandler = patchContext.FindPattern32(sVBlankIntrPatternArm0, sizeof(sVBlankIntrPatternArm0)); + _vblankIrqHandler = patchContext.FindPattern32(sOSiIrqVBlankPattern0, sizeof(sOSiIrqVBlankPattern0)); if (_vblankIrqHandler) { - _foundPattern = sVBlankIntrPatternArm0; + _foundPattern = sOSiIrqVBlankPattern0; } if (!_vblankIrqHandler) { - _vblankIrqHandler = patchContext.FindPattern32(sVBlankIntrPatternArm1, sizeof(sVBlankIntrPatternArm1)); + _vblankIrqHandler = patchContext.FindPattern32(sOSiIrqVBlankPattern1, sizeof(sOSiIrqVBlankPattern1)); if (_vblankIrqHandler) { - _foundPattern = sVBlankIntrPatternArm1; + _foundPattern = sOSiIrqVBlankPattern1; } } if (!_vblankIrqHandler) { - _vblankIrqHandler = patchContext.FindPattern32(sVBlankIntrPatternThumb0, sizeof(sVBlankIntrPatternThumb0)); + _vblankIrqHandler = patchContext.FindPattern32(sOSiIrqVBlankPatternThumb0, sizeof(sOSiIrqVBlankPatternThumb0)); if (_vblankIrqHandler) { - _foundPattern = sVBlankIntrPatternThumb0; - _vblankIrqHandler += 1; - } - } - if (!_vblankIrqHandler) - { - _vblankIrqHandler = patchContext.FindPattern32(sVBlankIntrPatternThumb1, sizeof(sVBlankIntrPatternThumb1)); - if (_vblankIrqHandler) - { - _foundPattern = sVBlankIntrPatternThumb1; - _vblankIrqHandler += 2; - } - } - if (!_vblankIrqHandler) - { - _vblankIrqHandler = patchContext.FindPattern32(sVBlankIntrPatternThumb2, sizeof(sVBlankIntrPatternThumb2)); - if (_vblankIrqHandler) - { - _foundPattern = sVBlankIntrPatternThumb2; - _vblankIrqHandler += 2; - } - } - if (!_vblankIrqHandler) - { - _vblankIrqHandler = patchContext.FindPattern32(sVBlankIntrPatternThumb3, sizeof(sVBlankIntrPatternThumb3)); - if (_vblankIrqHandler) - { - _foundPattern = sVBlankIntrPatternThumb3; - _vblankIrqHandler += 2; - } - } - if (!_vblankIrqHandler) - { - _vblankIrqHandler = patchContext.FindPattern32(sVBlankIntrPatternThumb4, sizeof(sVBlankIntrPatternThumb4)); - if (_vblankIrqHandler) - { - _foundPattern = sVBlankIntrPatternThumb4; - _vblankIrqHandler += 2; - } - } - if (!_vblankIrqHandler) - { - _vblankIrqHandler = patchContext.FindPattern32(sVBlankIntrPatternThumb5, sizeof(sVBlankIntrPatternThumb5)); - if (_vblankIrqHandler) - { - _foundPattern = sVBlankIntrPatternThumb5; - _vblankIrqHandler += 2; + _foundPattern = sOSiIrqVBlankPatternThumb0; + _thumb = true; } } if (_vblankIrqHandler) { - LOG_DEBUG("ARM7 VBlankIntr found at 0x%p\n", _vblankIrqHandler); + LOG_DEBUG("ARM7 OSi_IrqVBlank found at 0x%p\n", _vblankIrqHandler); } return _vblankIrqHandler != nullptr; @@ -102,91 +51,35 @@ void CheatEnginePatch::ApplyPatch(PatchContext& patchContext) _cheats ); - if (_foundPattern == sVBlankIntrPatternArm0) + int patchOffset; + if (_foundPattern == sOSiIrqVBlankPattern0) { - // push {lr} - // sub sp, sp, #4 - // ldr r0,= - // ldr r0, [r0] - // cmp r0, #0 - // beq 1f - // bl - // 1: - // add sp, sp, #4 - // pop {lr} - // bx lr - _vblankIrqHandler[7] = 0xE59F0000; // ldr r0,= address - _vblankIrqHandler[8] = 0xE12FFF10; // bx r0 - _vblankIrqHandler[9] = (u32)cheatEnginePatchCode->GetCheatEngineFunction(); // address + patchOffset = 0x3C; } - else if (_foundPattern == sVBlankIntrPatternArm1) + else if (_foundPattern == sOSiIrqVBlankPattern1) { - // push {r3,lr} - // ldr r0,= - // ldr r0, [r0] - // cmp r0, #0 - // beq 1f - // bl - // 1: - // pop {r3,lr} - // bx lr - _vblankIrqHandler[6] = 0xE51FF004; // ldr pc,= address - _vblankIrqHandler[7] = (u32)cheatEnginePatchCode->GetCheatEngineFunctionArm(); // address + patchOffset = 0x40; } - else if (_foundPattern == sVBlankIntrPatternThumb0) + else if (_foundPattern == sOSiIrqVBlankPatternThumb0) { - // push {lr} - // sub sp, sp, #4 - // ldr r0,= - // ldr r0, [r0] - // cmp r0, #0 - // beq 1f - // bl - // 1: - // add sp, sp, #4 - // pop {r3} - // bx r3 - // nop - ((u16*)_vblankIrqHandler)[8] = THUMB_LDR_PC_IMM(THUMB_R1, 0); // ldr r1,= address - ((u16*)_vblankIrqHandler)[9] = THUMB_BX(THUMB_R1); // bx r1 - _vblankIrqHandler[10 >> 1] = (u32)cheatEnginePatchCode->GetCheatEngineFunction(); // address - } - else if (_foundPattern == sVBlankIntrPatternThumb1 - || _foundPattern == sVBlankIntrPatternThumb2 - || _foundPattern == sVBlankIntrPatternThumb3 - || _foundPattern == sVBlankIntrPatternThumb4 - || _foundPattern == sVBlankIntrPatternThumb5) - { - // push {r3,lr} - // ldr r0,= - // ldr r0, [r0] - // cmp r0, #0 - // beq 1f - // bl - // 1: - // pop {r3} - // pop {r3} - // bx r3 - - // rewrite the function to - // add r1, pc, #4 - // ldr r0,= - // ldr r2,= cheatengine_entry_thumb_replace - // bx r2 - // beq 1f - // bl - // 1: - // mov pc, r4 - // .word cheatengine_entry_thumb_replace - - ((u16*)_vblankIrqHandler)[0] = THUMB_ADD_PC_IMM(THUMB_R1, 4); // add r1, pc, #4 - ((u16*)_vblankIrqHandler)[2] = THUMB_LDR_PC_IMM(THUMB_R2, 8); // ldr r2,= cheatengine_entry_thumb_replace - ((u16*)_vblankIrqHandler)[3] = THUMB_BX(THUMB_R2); // bx r2 - ((u16*)_vblankIrqHandler)[7] = THUMB_MOV_HIREG(THUMB_HI_PC, THUMB_R4); // mov pc, r4 - _vblankIrqHandler[8 >> 1] = (u32)cheatEnginePatchCode->GetCheatEngineFunctionThumbReplace(); // .word cheatengine_entry_thumb_replace + patchOffset = 0x20; } else { - LOG_ERROR("ARM7 VBlankIntr signature not implemented\n"); + LOG_ERROR("ARM7 OSi_IrqVBlank signature not implemented\n"); + return; } + + if (_thumb) + { + *(u16*)((u8*)_vblankIrqHandler + patchOffset + 0) = THUMB_LDR_PC_IMM(THUMB_R1, 0); // ldr r1,= address + *(u16*)((u8*)_vblankIrqHandler + patchOffset + 2) = THUMB_BX(THUMB_R1); // bx r1 + *(u32*)((u8*)_vblankIrqHandler + patchOffset + 4) = (u32)cheatEnginePatchCode->GetCheatEngineFunction(); // address + } + else + { + *(u32*)((u8*)_vblankIrqHandler + patchOffset + 0) = 0xE51FF004; // ldr pc,= address + *(u32*)((u8*)_vblankIrqHandler + patchOffset + 4) = (u32)cheatEnginePatchCode->GetCheatEngineFunctionArm(); // address + } + LOG_DEBUG("Cheats enabled\n"); } diff --git a/arm9/source/patches/arm7/cheats/CheatEnginePatch.h b/arm9/source/patches/arm7/cheats/CheatEnginePatch.h index 35a5f58..9c0cbcd 100644 --- a/arm9/source/patches/arm7/cheats/CheatEnginePatch.h +++ b/arm9/source/patches/arm7/cheats/CheatEnginePatch.h @@ -15,4 +15,5 @@ private: const void* _cheats; u32* _vblankIrqHandler = nullptr; const u32* _foundPattern = nullptr; + u16 _thumb = false; }; diff --git a/arm9/source/patches/arm7/cheats/CheatEnginePatchCode.h b/arm9/source/patches/arm7/cheats/CheatEnginePatchCode.h index add9774..69f9b9e 100644 --- a/arm9/source/patches/arm7/cheats/CheatEnginePatchCode.h +++ b/arm9/source/patches/arm7/cheats/CheatEnginePatchCode.h @@ -5,7 +5,6 @@ DEFINE_SECTION_SYMBOLS(patch_cheatengine); extern "C" void cheatengine_entry_arm(void); -extern "C" void cheatengine_entry_thumb_replace(void); extern "C" void cheatengine_entry(void); extern const void* cheatengine_cheatsPtr; @@ -28,9 +27,4 @@ public: { return GetAddressAtTarget((void*)cheatengine_entry_arm); } - - const void* GetCheatEngineFunctionThumbReplace() const - { - return GetAddressAtTarget((void*)cheatengine_entry_thumb_replace); - } }; diff --git a/arm9/source/patches/arm7/cheats/CheatEnginePatchCode.s b/arm9/source/patches/arm7/cheats/CheatEnginePatchCode.s index b4c8540..fae8964 100644 --- a/arm9/source/patches/arm7/cheats/CheatEnginePatchCode.s +++ b/arm9/source/patches/arm7/cheats/CheatEnginePatchCode.s @@ -14,21 +14,6 @@ cheatengine_entry_arm: bx r12 .thumb -.global cheatengine_entry_thumb_replace -.type cheatengine_entry_thumb_replace, %function -cheatengine_entry_thumb_replace: - push {r4, r5, lr} // r5 is a dummy - ldr r0, [r0] - adr r4, cheatengine_entry_thumb_replace_return - cmp r0, #0 - mov pc, r1 - -.balign 4 - -cheatengine_entry_thumb_replace_return: - pop {r4} - nop - .global cheatengine_entry .type cheatengine_entry, %function cheatengine_entry: