mirror of
https://github.com/LNH-team/pico-loader.git
synced 2026-06-02 09:16:49 +02:00
Added support for SDK variant with a lot of inlining. Fixes #53.
Fixes Tropix! ...Your Island Getaway and Think - Training für den Kopf - Kids - Spiel Dich Schlau!
This commit is contained in:
@@ -20,6 +20,7 @@ static const u32 sCARDiReadCardPatternSdk3027530Thumb[] = { 0xB082B5F8u, 0x90019
|
||||
static const u32 sCARDiReadCardPatternSdk4002774[] = { 0xE92D4070u, 0xE59F40D0u, 0xE1A06000u, 0xE3A00C02u };
|
||||
static const u32 sCARDiReadCardPatternSdk4017530[] = { 0xE92D4070u, 0xE59F40D8u, 0xE1A06000u, 0xE3A00C02u };
|
||||
static const u32 sCARDiReadCardPatternSdk4017530Thumb[] = { 0xB082B5F8u, 0x90019000u, 0x90013020u, 0x69C24827u };
|
||||
static const u32 sCARDiReadCardPatternSdk4027531ThumbInlined[] = { 0xB082B5F8u, 0x90019000u, 0x90013020u, 0x69C14841u };
|
||||
static const u32 sCARDiReadCardPatternSdk4027539SpiritTracks[] = { 0xE92D4070u, 0xE59F40D4u, 0xE1A06000u, 0xE3A00C02u };
|
||||
|
||||
void CardiReadCardPatch::TryPattern(PatchContext& patchContext, const u32* pattern, u32 byteLength)
|
||||
@@ -90,6 +91,8 @@ bool CardiReadCardPatch::FindPatchTarget(PatchContext& patchContext)
|
||||
TryPattern(patchContext, sCARDiReadCardPatternSdk3027530Thumb, sizeof(sCARDiReadCardPatternSdk3027530Thumb));
|
||||
if (!_cardiReadCard)
|
||||
TryPattern(patchContext, sCARDiReadCardPatternSdk2027533ThumbChouSoujuu, sizeof(sCARDiReadCardPatternSdk2027533ThumbChouSoujuu));
|
||||
if (!_cardiReadCard)
|
||||
TryPattern(patchContext, sCARDiReadCardPatternSdk4027531ThumbInlined, sizeof(sCARDiReadCardPatternSdk4027531ThumbInlined));
|
||||
|
||||
if (_cardiReadCard)
|
||||
_thumb = true;
|
||||
@@ -153,42 +156,53 @@ void CardiReadCardPatch::ApplyPatch(PatchContext& patchContext)
|
||||
if (_thumb)
|
||||
{
|
||||
u32 patchOffset;
|
||||
u32 cardiCommonOffset;
|
||||
if (_foundPattern == sCARDiReadCardPatternSdk4017530Thumb)
|
||||
{
|
||||
patchOffset = 0x36;
|
||||
cardiCommonOffset = 0x74;
|
||||
patch_cardireadcard_return_offset = THUMB_MOVS_IMM(THUMB_R0, 0x3C);
|
||||
patch_cardireadcard_mov_src_to_r0 = THUMB_MOVS_REG(THUMB_R0, THUMB_R1); // src
|
||||
patch_cardireadcard_mov_dst_to_r1 = THUMB_MOVS_REG(THUMB_R1, THUMB_R4); // dst
|
||||
patch_cardireadcard_mov_cardicommon_to_r6 = THUMB_LDR_SP_IMM(THUMB_R6, 0);
|
||||
patch_cardireadcard_mov_cardicommon_to_r6 = THUMB_LDR_SP_IMM(THUMB_R6, 8); // r3 from the stack
|
||||
patch_cardireadcard_adjust_cardicommon_offset = THUMB_NOP;
|
||||
patch_cardireadcard_mov_r3_to_dst = THUMB_STR_SP_IMM(THUMB_R3, 4);
|
||||
patch_cardireadcard_mov_r3_to_dst = THUMB_STR_SP_IMM(THUMB_R3, 0xC); // copy to r4 on the stack
|
||||
*(u16*)((u8*)_cardiReadCard + patchOffset + 0) = THUMB_LDR_PC_IMM(THUMB_R3, 0x74); // ldr r3,= cardi_common
|
||||
}
|
||||
else if (_foundPattern == sCARDiReadCardPatternSdk3027530Thumb)
|
||||
{
|
||||
patchOffset = 0x36;
|
||||
cardiCommonOffset = 0x6C;
|
||||
patch_cardireadcard_return_offset = THUMB_MOVS_IMM(THUMB_R0, 0x36);
|
||||
patch_cardireadcard_mov_src_to_r0 = THUMB_MOVS_REG(THUMB_R0, THUMB_R1); // src
|
||||
patch_cardireadcard_mov_dst_to_r1 = THUMB_MOVS_REG(THUMB_R1, THUMB_R4); // dst
|
||||
patch_cardireadcard_mov_cardicommon_to_r6 = THUMB_LDR_SP_IMM(THUMB_R6, 0);
|
||||
patch_cardireadcard_mov_cardicommon_to_r6 = THUMB_LDR_SP_IMM(THUMB_R6, 8); // r3 from the stack
|
||||
patch_cardireadcard_adjust_cardicommon_offset = THUMB_NOP;
|
||||
patch_cardireadcard_mov_r3_to_dst = THUMB_STR_SP_IMM(THUMB_R3, 4);
|
||||
patch_cardireadcard_mov_r3_to_dst = THUMB_STR_SP_IMM(THUMB_R3, 0xC); // copy to r4 on the stack
|
||||
*(u16*)((u8*)_cardiReadCard + patchOffset + 0) = THUMB_LDR_PC_IMM(THUMB_R3, 0x6C); // ldr r3,= cardi_common
|
||||
}
|
||||
else if (_foundPattern == sCARDiReadCardPatternSdk2004F4CThumb)
|
||||
{
|
||||
patchOffset = 0x36;
|
||||
cardiCommonOffset = 0;
|
||||
patch_cardireadcard_return_offset = THUMB_MOVS_IMM(THUMB_R0, 0x2E);
|
||||
patch_cardireadcard_mov_src_to_r0 = THUMB_MOVS_REG(THUMB_R0, THUMB_R1); // src
|
||||
patch_cardireadcard_mov_dst_to_r1 = THUMB_MOVS_REG(THUMB_R1, THUMB_R5); // dst
|
||||
patch_cardireadcard_mov_cardicommon_to_r6 = THUMB_LDR_SP_IMM(THUMB_R6, 8); // r6 from stack
|
||||
patch_cardireadcard_mov_cardicommon_to_r6 = THUMB_LDR_SP_IMM(THUMB_R6, 0x10); // r6 from stack
|
||||
if (patchContext.GetSdkVersion().GetMajor() <= SDK_VERSION_MAJOR_NITRO_2)
|
||||
patch_cardireadcard_adjust_cardicommon_offset = THUMB_SUBS_IMM(THUMB_R6, THUMB_R6, 4);
|
||||
else
|
||||
patch_cardireadcard_adjust_cardicommon_offset = THUMB_NOP;
|
||||
patch_cardireadcard_mov_r3_to_dst = THUMB_MOVS_REG(THUMB_R5, THUMB_R3);
|
||||
*(u16*)((u8*)_cardiReadCard + patchOffset + 0) = THUMB_NOP;
|
||||
}
|
||||
else if (_foundPattern == sCARDiReadCardPatternSdk4027531ThumbInlined)
|
||||
{
|
||||
// This variant has a lot of inlining
|
||||
patchOffset = 0x36;
|
||||
patch_cardireadcard_return_offset = THUMB_MOVS_IMM(THUMB_R0, 0x64);
|
||||
patch_cardireadcard_mov_src_to_r0 = THUMB_LDR_SP_IMM(THUMB_R0, 8); // src, r3 from the stack
|
||||
patch_cardireadcard_mov_dst_to_r1 = THUMB_LDR_SP_IMM(THUMB_R1, 4); // dst, r2 from the stack
|
||||
patch_cardireadcard_mov_cardicommon_to_r6 = THUMB_LDR_SP_IMM(THUMB_R6, 0); // r1 from the stack
|
||||
patch_cardireadcard_adjust_cardicommon_offset = THUMB_NOP;
|
||||
patch_cardireadcard_mov_r3_to_dst = THUMB_STR_SP_IMM(THUMB_R3, 4); // copy to r2 on the stack
|
||||
*(u16*)((u8*)_cardiReadCard + patchOffset + 0) = THUMB_LDR_PC_IMM(THUMB_R1, 0xDC); // ldr r1,= cardi_common
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -196,7 +210,6 @@ void CardiReadCardPatch::ApplyPatch(PatchContext& patchContext)
|
||||
while (1);
|
||||
}
|
||||
|
||||
*(u16*)((u8*)_cardiReadCard + patchOffset + 0) = cardiCommonOffset == 0 ? THUMB_NOP : THUMB_LDR_PC_IMM(THUMB_R3, cardiCommonOffset); // ldr r0,= cardi_common
|
||||
*(u16*)((u8*)_cardiReadCard + patchOffset + 2) = THUMB_LDR_PC_IMM(THUMB_R0, 0); // ldr r0,= entryAddress
|
||||
*(u16*)((u8*)_cardiReadCard + patchOffset + 4) = THUMB_BLX(THUMB_R0);
|
||||
*(u32*)((u8*)_cardiReadCard + patchOffset + 6) = entryAddress;
|
||||
|
||||
@@ -11,7 +11,7 @@ patch_cardireadcard_entry:
|
||||
patch_cardireadcard_return_offset:
|
||||
movs r0, #0x38
|
||||
add lr, r0
|
||||
push {r3,r4,r6,lr}
|
||||
push {r1,r2,r3,r4,r6,lr}
|
||||
ldr r3, __patch_cardireadcard_fix_cp15_asm_address
|
||||
blx r3
|
||||
.global patch_cardireadcard_mov_src_to_r0
|
||||
@@ -59,7 +59,7 @@ patch_cardireadcard_mov_r3_to_dst:
|
||||
do_read:
|
||||
ldr r3, __patch_cardireadcard_sdread_asm_address
|
||||
blx r3
|
||||
pop {r3,r4,r6,pc}
|
||||
pop {r1,r2,r3,r4,r6,pc}
|
||||
|
||||
.balign 4
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@ static const u32 sCARDiTryReadCardDmaPatternSdkThumb[] = { 0xB084B5F8u, 0x483D90
|
||||
static const u32 sCARDiTryReadCardDmaPatternSdk4007531Thumb[] = { 0xB084B5F8u, 0x483E9000u, 0x6A446A05u, 0x90032000u };
|
||||
static const u32 sCARDiTryReadCardDmaPatternSdk4017530Thumb[] = { 0xB084B5F8u, 0x48479000u, 0x6A446A05u, 0x90032000u };
|
||||
static const u32 sCARDiTryReadCardDmaPatternSdk4027530Thumb[] = { 0xB084B5F8u, 0x48479000u, 0x6A446A05u, 0x90032000u };
|
||||
static const u32 sCARDiTryReadCardDmaPatternSdk4027531ThumbInlined[] = { 0xB083B5F0u, 0x485D9000u, 0x6A062500u, 0x1C286A44u };
|
||||
|
||||
static const u16 sReturnFalsePatchThumb[] = { THUMB_MOVS_IMM(0, 0), THUMB_BX_LR };
|
||||
static const u32 sReturnFalsePatchArm[] = { 0xE3A00000, 0xE12FFF1E }; // mov r0, #0; bx lr
|
||||
@@ -141,6 +142,10 @@ bool CardiTryReadCardDmaPatch::FindPatchTarget(PatchContext& patchContext)
|
||||
if (!_cardiTryReadCardDma)
|
||||
TryPattern(patchContext, sCARDiTryReadCardDmaPatternThumbChouSoujuu);
|
||||
}
|
||||
if (!_cardiTryReadCardDma && patchContext.GetSdkVersion() == 0x4027531)
|
||||
{
|
||||
TryPattern(patchContext, sCARDiTryReadCardDmaPatternSdk4027531ThumbInlined);
|
||||
}
|
||||
|
||||
if (_cardiTryReadCardDma)
|
||||
_thumb = true;
|
||||
|
||||
Reference in New Issue
Block a user