Merge branch 'master' into developer
Conflicts: source/firm.c source/patches.c source/patches.h
This commit is contained in:
commit
e6645554f0
@ -16,4 +16,4 @@ typedef struct __attribute__((packed))
|
|||||||
u32 config;
|
u32 config;
|
||||||
} CFWInfo;
|
} CFWInfo;
|
||||||
|
|
||||||
void svcGetCFWInfo(CFWInfo *info);
|
int svcGetCFWInfo(CFWInfo *info);
|
@ -34,6 +34,8 @@
|
|||||||
cmp r0, r2
|
cmp r0, r2
|
||||||
blo loop
|
blo loop
|
||||||
|
|
||||||
|
mov r0, #0
|
||||||
|
|
||||||
bx lr
|
bx lr
|
||||||
|
|
||||||
.pool
|
.pool
|
||||||
|
@ -316,10 +316,11 @@ static inline void patchNativeFirm(u32 firmVersion, FirmwareSource nandType, u32
|
|||||||
u8 *process9Offset = getProcess9(arm9Section + 0x15000, section[2].size - 0x15000, &process9Size, &process9MemAddr);
|
u8 *process9Offset = getProcess9(arm9Section + 0x15000, section[2].size - 0x15000, &process9Size, &process9MemAddr);
|
||||||
|
|
||||||
//Find Kernel11 SVC table and handler, exceptions page and free space locations
|
//Find Kernel11 SVC table and handler, exceptions page and free space locations
|
||||||
|
u32 baseK11VA;
|
||||||
u8 *freeK11Space;
|
u8 *freeK11Space;
|
||||||
u32 *arm11SvcHandler,
|
u32 *arm11SvcHandler,
|
||||||
*arm11ExceptionsPage,
|
*arm11ExceptionsPage,
|
||||||
*arm11SvcTable = getKernel11Info(arm11Section1, section[1].size, &freeK11Space, &arm11SvcHandler, &arm11ExceptionsPage);
|
*arm11SvcTable = getKernel11Info(arm11Section1, section[1].size, &baseK11VA, &freeK11Space, &arm11SvcHandler, &arm11ExceptionsPage);
|
||||||
|
|
||||||
//Apply signature patches
|
//Apply signature patches
|
||||||
patchSignatureChecks(process9Offset, process9Size);
|
patchSignatureChecks(process9Offset, process9Size);
|
||||||
@ -344,10 +345,10 @@ static inline void patchNativeFirm(u32 firmVersion, FirmwareSource nandType, u32
|
|||||||
patchTitleInstallMinVersionCheck(process9Offset, process9Size);
|
patchTitleInstallMinVersionCheck(process9Offset, process9Size);
|
||||||
|
|
||||||
//Restore svcBackdoor
|
//Restore svcBackdoor
|
||||||
reimplementSvcBackdoor(arm11Section1, arm11SvcTable, &freeK11Space);
|
reimplementSvcBackdoor(arm11Section1, arm11SvcTable, baseK11VA, &freeK11Space);
|
||||||
}
|
}
|
||||||
|
|
||||||
implementSvcGetCFWInfo(arm11Section1, arm11SvcTable, &freeK11Space);
|
implementSvcGetCFWInfo(arm11Section1, arm11SvcTable, baseK11VA, &freeK11Space);
|
||||||
|
|
||||||
//Apply UNITINFO patch
|
//Apply UNITINFO patch
|
||||||
if(CONFIG_DEVOPTIONS == 1) patchUnitInfoValueSet(arm9Section, section[2].size);
|
if(CONFIG_DEVOPTIONS == 1) patchUnitInfoValueSet(arm9Section, section[2].size);
|
||||||
|
@ -38,13 +38,17 @@ u8 *getProcess9(u8 *pos, u32 size, u32 *process9Size, u32 *process9MemAddr)
|
|||||||
return off - 0x204 + (*(u32 *)(off - 0x64) * 0x200) + 0x200;
|
return off - 0x204 + (*(u32 *)(off - 0x64) * 0x200) + 0x200;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 *getKernel11Info(u8 *pos, u32 size, u8 **freeK11Space, u32 **arm11SvcHandler, u32 **arm11ExceptionsPage)
|
u32 *getKernel11Info(u8 *pos, u32 size, u32 *baseK11VA, u8 **freeK11Space, u32 **arm11SvcHandler, u32 **arm11ExceptionsPage)
|
||||||
{
|
{
|
||||||
const u8 pattern[] = {0x00, 0xB0, 0x9C, 0xE5};
|
const u8 pattern[] = {0x00, 0xB0, 0x9C, 0xE5};
|
||||||
|
|
||||||
*arm11ExceptionsPage = (u32 *)memsearch(pos, pattern, size, sizeof(pattern)) - 0xB;
|
*arm11ExceptionsPage = (u32 *)memsearch(pos, pattern, size, sizeof(pattern)) - 0xB;
|
||||||
u32 svcOffset = (-(((*arm11ExceptionsPage)[2] & 0xFFFFFF) << 2) & (0xFFFFFF << 2)) - 8; //Branch offset + 8 for prefetch
|
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
|
||||||
*arm11SvcHandler = arm11SvcTable;
|
*arm11SvcHandler = arm11SvcTable;
|
||||||
while(*arm11SvcTable) arm11SvcTable++; //Look for SVC0 (NULL)
|
while(*arm11SvcTable) arm11SvcTable++; //Look for SVC0 (NULL)
|
||||||
|
|
||||||
@ -112,7 +116,7 @@ void patchOldFirmWrites(u8 *pos, u32 size)
|
|||||||
off[1] = 0xE01D;
|
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
|
//Official implementation of svcBackdoor
|
||||||
const u8 svcBackdoor[40] = {0xFF, 0x10, 0xCD, 0xE3, //bic r1, sp, #0xff
|
const u8 svcBackdoor[40] = {0xFF, 0x10, 0xCD, 0xE3, //bic r1, sp, #0xff
|
||||||
@ -130,12 +134,12 @@ void reimplementSvcBackdoor(u8 *pos, u32 *arm11SvcTable, u8 **freeK11Space)
|
|||||||
{
|
{
|
||||||
memcpy(*freeK11Space, svcBackdoor, 40);
|
memcpy(*freeK11Space, svcBackdoor, 40);
|
||||||
|
|
||||||
arm11SvcTable[0x7B] = 0xFFF00000 + *freeK11Space - pos;
|
arm11SvcTable[0x7B] = baseK11VA + *freeK11Space - pos;
|
||||||
*freeK11Space += 40;
|
*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);
|
memcpy(*freeK11Space, svcGetCFWInfo, svcGetCFWInfo_size);
|
||||||
|
|
||||||
@ -157,7 +161,7 @@ void implementSvcGetCFWInfo(u8 *pos, u32 *arm11SvcTable, u8 **freeK11Space)
|
|||||||
|
|
||||||
info->flags = 1 /* dev branch */ | ((isRelease ? 1 : 0) << 1) /* is release */;
|
info->flags = 1 /* dev branch */ | ((isRelease ? 1 : 0) << 1) /* is release */;
|
||||||
|
|
||||||
arm11SvcTable[0x2E] = 0xFFF00000 + *freeK11Space - pos; //Stubbed svc
|
arm11SvcTable[0x2E] = baseK11VA + *freeK11Space - pos; //Stubbed svc
|
||||||
*freeK11Space += svcGetCFWInfo_size;
|
*freeK11Space += svcGetCFWInfo_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,14 +50,14 @@ typedef struct __attribute__((packed))
|
|||||||
extern bool isN3DS, isDevUnit;
|
extern bool isN3DS, isDevUnit;
|
||||||
|
|
||||||
u8 *getProcess9(u8 *pos, u32 size, u32 *process9Size, u32 *process9MemAddr);
|
u8 *getProcess9(u8 *pos, u32 size, u32 *process9Size, u32 *process9MemAddr);
|
||||||
u32 *getKernel11Info(u8 *pos, u32 size, u8 **freeK11Space, u32 **arm11SvcHandler, u32 **arm11ExceptionsPage);
|
u32 *getKernel11Info(u8 *pos, u32 size, u32 *baseK11VA, u8 **freeK11Space, u32 **arm11SvcHandler, u32 **arm11ExceptionsPage);
|
||||||
void patchSignatureChecks(u8 *pos, u32 size);
|
void patchSignatureChecks(u8 *pos, u32 size);
|
||||||
void patchTitleInstallMinVersionCheck(u8 *pos, u32 size);
|
void patchTitleInstallMinVersionCheck(u8 *pos, u32 size);
|
||||||
void patchFirmlaunches(u8 *pos, u32 size, u32 process9MemAddr);
|
void patchFirmlaunches(u8 *pos, u32 size, u32 process9MemAddr);
|
||||||
void patchFirmWrites(u8 *pos, u32 size);
|
void patchFirmWrites(u8 *pos, u32 size);
|
||||||
void patchOldFirmWrites(u8 *pos, u32 size);
|
void patchOldFirmWrites(u8 *pos, u32 size);
|
||||||
void reimplementSvcBackdoor(u8 *pos, u32 *arm11SvcTable, u8 **freeK11Space);
|
void reimplementSvcBackdoor(u8 *pos, u32 *arm11SvcTable, u32 baseK11VA, u8 **freeK11Space);
|
||||||
void implementSvcGetCFWInfo(u8 *pos, u32 *arm11SvcTable, u8 **freeK11Space);
|
void implementSvcGetCFWInfo(u8 *pos, u32 *arm11SvcTable, u32 baseK11VA, u8 **freeK11Space);
|
||||||
void applyLegacyFirmPatches(u8 *pos, FirmwareType firmType);
|
void applyLegacyFirmPatches(u8 *pos, FirmwareType firmType);
|
||||||
|
|
||||||
void patchArm9ExceptionHandlersInstall(u8 *pos, u32 size);
|
void patchArm9ExceptionHandlersInstall(u8 *pos, u32 size);
|
||||||
|
Reference in New Issue
Block a user