Fix broken assumptions and bugs

This commit is contained in:
TuxSH 2016-09-10 21:12:53 +02:00
parent 2cd2a081d6
commit 0f83d1ffaa
5 changed files with 20 additions and 13 deletions

View File

@ -16,4 +16,4 @@ typedef struct __attribute__((packed))
u32 config;
} CFWInfo;
void svcGetCFWInfo(CFWInfo *info);
int svcGetCFWInfo(CFWInfo *info);

View File

@ -34,6 +34,8 @@
cmp r0, r2
blo loop
mov r0, #0
bx lr
.pool

View File

@ -299,8 +299,9 @@ static inline void patchNativeFirm(u32 firmVersion, FirmwareSource nandType, u32
u8 *process9Offset = getProcess9(arm9Section + 0x15000, section[2].size - 0x15000, &process9Size, &process9MemAddr);
//Find Kernel11 SVC table and free space locations
u32 baseK11VA;
u8 *freeK11Space;
u32 *arm11SvcTable = getKernel11Info(arm11Section1, section[1].size, &freeK11Space);
u32 *arm11SvcTable = getKernel11Info(arm11Section1, section[1].size, &baseK11VA, &freeK11Space);
//Apply signature patches
patchSignatureChecks(process9Offset, process9Size);
@ -325,10 +326,10 @@ static inline void patchNativeFirm(u32 firmVersion, FirmwareSource nandType, u32
patchTitleInstallMinVersionCheck(process9Offset, process9Size);
//Restore svcBackdoor
reimplementSvcBackdoor(arm11Section1, arm11SvcTable, &freeK11Space);
reimplementSvcBackdoor(arm11Section1, arm11SvcTable, baseK11VA, &freeK11Space);
}
implementSvcGetCFWInfo(arm11Section1, arm11SvcTable, &freeK11Space);
implementSvcGetCFWInfo(arm11Section1, arm11SvcTable, baseK11VA, &freeK11Space);
}
static inline void patchLegacyFirm(FirmwareType firmType)

View File

@ -37,13 +37,17 @@ u8 *getProcess9(u8 *pos, u32 size, u32 *process9Size, u32 *process9MemAddr)
return off - 0x204 + (*(u32 *)(off - 0x64) * 0x200) + 0x200;
}
u32 *getKernel11Info(u8 *pos, u32 size, u8 **freeK11Space)
u32 *getKernel11Info(u8 *pos, u32 size, u32 *baseK11VA, u8 **freeK11Space)
{
const u8 pattern[] = {0x00, 0xB0, 0x9C, 0xE5};
u32 *arm11ExceptionsPage = (u32 *)memsearch(pos, pattern, size, sizeof(pattern)) - 0xB;
u32 svcOffset = (-((arm11ExceptionsPage[2] & 0xFFFFFF) << 2) & (0xFFFFFF << 2)) - 8; //Branch offset + 8 for prefetch
u32 *arm11SvcTable = (u32 *)(pos + *(u32 *)(pos + 0xFFFF0008 - svcOffset - 0xFFF00000 + 8) - 0xFFF00000); //SVC handler address
u32 pointedInstructionVA = 0xFFFF0008 - svcOffset;
*baseK11VA = pointedInstructionVA & 0xFFFF0000; //this assumes that the pointed instruction has an offset < 0x10000; iirc that's always the case
u32 *arm11SvcTable = (u32 *)(pos + *(u32 *)(pos + pointedInstructionVA - *baseK11VA + 8) - *baseK11VA); //SVC handler address
while(*arm11SvcTable) arm11SvcTable++; //Look for SVC0 (NULL)
const u8 pattern2[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
@ -110,7 +114,7 @@ void patchOldFirmWrites(u8 *pos, u32 size)
off[1] = 0xE01D;
}
void reimplementSvcBackdoor(u8 *pos, u32 *arm11SvcTable, u8 **freeK11Space)
void reimplementSvcBackdoor(u8 *pos, u32 *arm11SvcTable, u32 baseK11VA, u8 **freeK11Space)
{
//Official implementation of svcBackdoor
const u8 svcBackdoor[40] = {0xFF, 0x10, 0xCD, 0xE3, //bic r1, sp, #0xff
@ -128,12 +132,12 @@ void reimplementSvcBackdoor(u8 *pos, u32 *arm11SvcTable, u8 **freeK11Space)
{
memcpy(*freeK11Space, svcBackdoor, 40);
arm11SvcTable[0x7B] = 0xFFF00000 + *freeK11Space - pos;
arm11SvcTable[0x7B] = baseK11VA + *freeK11Space - pos;
*freeK11Space += 40;
}
}
void implementSvcGetCFWInfo(u8 *pos, u32 *arm11SvcTable, u8 **freeK11Space)
void implementSvcGetCFWInfo(u8 *pos, u32 *arm11SvcTable, u32 baseK11VA, u8 **freeK11Space)
{
memcpy(*freeK11Space, svcGetCFWInfo, svcGetCFWInfo_size);
@ -155,7 +159,7 @@ void implementSvcGetCFWInfo(u8 *pos, u32 *arm11SvcTable, u8 **freeK11Space)
info->flags = 0 /* master branch */ | ((isRelease ? 1 : 0) << 1) /* is release */;
arm11SvcTable[0x2E] = 0xFFF00000 + *freeK11Space - pos; //Stubbed svc
arm11SvcTable[0x2E] = baseK11VA + *freeK11Space - pos; //Stubbed svc
*freeK11Space += svcGetCFWInfo_size;
}

View File

@ -50,12 +50,12 @@ typedef struct __attribute__((packed))
extern bool isN3DS;
u8 *getProcess9(u8 *pos, u32 size, u32 *process9Size, u32 *process9MemAddr);
u32 *getKernel11Info(u8 *pos, u32 size, u8 **freeK11Space);
u32 *getKernel11Info(u8 *pos, u32 size, u32 *baseK11VA, u8 **freeK11Space);
void patchSignatureChecks(u8 *pos, u32 size);
void patchTitleInstallMinVersionCheck(u8 *pos, u32 size);
void patchFirmlaunches(u8 *pos, u32 size, u32 process9MemAddr);
void patchFirmWrites(u8 *pos, u32 size);
void patchOldFirmWrites(u8 *pos, u32 size);
void reimplementSvcBackdoor(u8 *pos, u32 *arm11SvcTable, u8 **freeK11Space);
void implementSvcGetCFWInfo(u8 *pos, u32 *arm11SvcTable, u8 **freeK11Space);
void reimplementSvcBackdoor(u8 *pos, u32 *arm11SvcTable, u32 baseK11VA, u8 **freeK11Space);
void implementSvcGetCFWInfo(u8 *pos, u32 *arm11SvcTable, u32 baseK11VA, u8 **freeK11Space);
void applyLegacyFirmPatches(u8 *pos, FirmwareType firmType);