More sanity checks
This commit is contained in:
parent
06ea123dbd
commit
e9692a438b
@ -498,7 +498,7 @@ void kernel9Loader(Arm9Bin *arm9Section)
|
|||||||
aes_use_keyslot(arm9BinSlot);
|
aes_use_keyslot(arm9BinSlot);
|
||||||
aes(startOfArm9Bin, startOfArm9Bin, arm9BinSize / AES_BLOCK_SIZE, arm9BinCtr, AES_CTR_MODE, AES_INPUT_BE | AES_INPUT_NORMAL);
|
aes(startOfArm9Bin, startOfArm9Bin, arm9BinSize / AES_BLOCK_SIZE, arm9BinCtr, AES_CTR_MODE, AES_INPUT_BE | AES_INPUT_NORMAL);
|
||||||
|
|
||||||
if(*startOfArm9Bin != 0x47704770 && *startOfArm9Bin != 0xB0862000) error("Error decrypting New 3DS ARM9 Binary.");
|
if(*startOfArm9Bin != 0x47704770 && *startOfArm9Bin != 0xB0862000) error("Error decrypting the ARM9 binary.");
|
||||||
}
|
}
|
||||||
|
|
||||||
//Set >=9.6 KeyXs
|
//Set >=9.6 KeyXs
|
||||||
|
@ -27,21 +27,6 @@
|
|||||||
#define MAKE_BRANCH(src,dst) (0xEA000000 | ((u32)((((u8 *)(dst) - (u8 *)(src)) >> 2) - 2) & 0xFFFFFF))
|
#define MAKE_BRANCH(src,dst) (0xEA000000 | ((u32)((((u8 *)(dst) - (u8 *)(src)) >> 2) - 2) & 0xFFFFFF))
|
||||||
#define MAKE_BRANCH_LINK(src,dst) (0xEB000000 | ((u32)((((u8 *)(dst) - (u8 *)(src)) >> 2) - 2) & 0xFFFFFF))
|
#define MAKE_BRANCH_LINK(src,dst) (0xEB000000 | ((u32)((((u8 *)(dst) - (u8 *)(src)) >> 2) - 2) & 0xFFFFFF))
|
||||||
|
|
||||||
typedef struct __attribute__((packed))
|
|
||||||
{
|
|
||||||
u32 magic[2];
|
|
||||||
u16 versionMinor, versionMajor;
|
|
||||||
|
|
||||||
u16 processor, core;
|
|
||||||
u32 type;
|
|
||||||
|
|
||||||
u32 totalSize;
|
|
||||||
u32 registerDumpSize;
|
|
||||||
u32 codeDumpSize;
|
|
||||||
u32 stackDumpSize;
|
|
||||||
u32 additionalDataSize;
|
|
||||||
} ExceptionDumpHeader;
|
|
||||||
|
|
||||||
void installArm9Handlers(void);
|
void installArm9Handlers(void);
|
||||||
u32 installArm11Handlers(u32 *exceptionsPage, u32 stackAddress, u32 codeSetOffset);
|
u32 installArm11Handlers(u32 *exceptionsPage, u32 stackAddress, u32 codeSetOffset);
|
||||||
void detectAndProcessExceptionDumps(void);
|
void detectAndProcessExceptionDumps(void);
|
@ -155,10 +155,10 @@ u32 patchNativeFirm(u32 firmVersion, FirmwareSource nandType, u32 emuHeader, u32
|
|||||||
ret += patchTitleInstallMinVersionChecks(process9Offset, process9Size, firmVersion);
|
ret += patchTitleInstallMinVersionChecks(process9Offset, process9Size, firmVersion);
|
||||||
|
|
||||||
//Restore svcBackdoor
|
//Restore svcBackdoor
|
||||||
reimplementSvcBackdoor(arm11Section1, arm11SvcTable, baseK11VA, &freeK11Space);
|
ret += reimplementSvcBackdoor(arm11Section1, arm11SvcTable, baseK11VA, &freeK11Space);
|
||||||
}
|
}
|
||||||
|
|
||||||
implementSvcGetCFWInfo(arm11Section1, arm11SvcTable, baseK11VA, &freeK11Space);
|
ret += implementSvcGetCFWInfo(arm11Section1, arm11SvcTable, baseK11VA, &freeK11Space);
|
||||||
|
|
||||||
//Apply UNITINFO patch
|
//Apply UNITINFO patch
|
||||||
if(devMode == 2) ret += patchUnitInfoValueSet(arm9Section, firm->section[2].size);
|
if(devMode == 2) ret += patchUnitInfoValueSet(arm9Section, firm->section[2].size);
|
||||||
|
100
source/patches.c
100
source/patches.c
@ -203,55 +203,85 @@ u32 patchOldFirmWrites(u8 *pos, u32 size)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void reimplementSvcBackdoor(u8 *pos, u32 *arm11SvcTable, u32 baseK11VA, u8 **freeK11Space)
|
u32 reimplementSvcBackdoor(u8 *pos, u32 *arm11SvcTable, u32 baseK11VA, u8 **freeK11Space)
|
||||||
{
|
{
|
||||||
|
u32 ret = 0;
|
||||||
|
|
||||||
//Official implementation of svcBackdoor
|
//Official implementation of svcBackdoor
|
||||||
const u8 svcBackdoor[40] = {0xFF, 0x10, 0xCD, 0xE3, //bic r1, sp, #0xff
|
const u8 svcBackdoor[] = {0xFF, 0x10, 0xCD, 0xE3, //bic r1, sp, #0xff
|
||||||
0x0F, 0x1C, 0x81, 0xE3, //orr r1, r1, #0xf00
|
0x0F, 0x1C, 0x81, 0xE3, //orr r1, r1, #0xf00
|
||||||
0x28, 0x10, 0x81, 0xE2, //add r1, r1, #0x28
|
0x28, 0x10, 0x81, 0xE2, //add r1, r1, #0x28
|
||||||
0x00, 0x20, 0x91, 0xE5, //ldr r2, [r1]
|
0x00, 0x20, 0x91, 0xE5, //ldr r2, [r1]
|
||||||
0x00, 0x60, 0x22, 0xE9, //stmdb r2!, {sp, lr}
|
0x00, 0x60, 0x22, 0xE9, //stmdb r2!, {sp, lr}
|
||||||
0x02, 0xD0, 0xA0, 0xE1, //mov sp, r2
|
0x02, 0xD0, 0xA0, 0xE1, //mov sp, r2
|
||||||
0x30, 0xFF, 0x2F, 0xE1, //blx r0
|
0x30, 0xFF, 0x2F, 0xE1, //blx r0
|
||||||
0x03, 0x00, 0xBD, 0xE8, //pop {r0, r1}
|
0x03, 0x00, 0xBD, 0xE8, //pop {r0, r1}
|
||||||
0x00, 0xD0, 0xA0, 0xE1, //mov sp, r0
|
0x00, 0xD0, 0xA0, 0xE1, //mov sp, r0
|
||||||
0x11, 0xFF, 0x2F, 0xE1}; //bx r1
|
0x11, 0xFF, 0x2F, 0xE1}; //bx r1
|
||||||
|
|
||||||
if(!arm11SvcTable[0x7B])
|
if(!arm11SvcTable[0x7B])
|
||||||
{
|
{
|
||||||
memcpy(*freeK11Space, svcBackdoor, 40);
|
if(*(u32 *)(*freeK11Space + sizeof(svcBackdoor) - 4) != 0xFFFFFFFF) ret = 1;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
memcpy(*freeK11Space, svcBackdoor, sizeof(svcBackdoor));
|
||||||
|
|
||||||
arm11SvcTable[0x7B] = baseK11VA + *freeK11Space - pos;
|
arm11SvcTable[0x7B] = baseK11VA + *freeK11Space - pos;
|
||||||
*freeK11Space += 40;
|
*freeK11Space += 40;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void implementSvcGetCFWInfo(u8 *pos, u32 *arm11SvcTable, u32 baseK11VA, u8 **freeK11Space)
|
u32 implementSvcGetCFWInfo(u8 *pos, u32 *arm11SvcTable, u32 baseK11VA, u8 **freeK11Space)
|
||||||
{
|
{
|
||||||
memcpy(*freeK11Space, svcGetCFWInfo_bin, svcGetCFWInfo_bin_size);
|
u32 ret;
|
||||||
|
|
||||||
CFWInfo *info = (CFWInfo *)memsearch(*freeK11Space, "LUMA", svcGetCFWInfo_bin_size, 4);
|
if(*(u32 *)(*freeK11Space + svcGetCFWInfo_bin_size - 4) != 0xFFFFFFFF) ret = 1;
|
||||||
|
else
|
||||||
const char *rev = REVISION;
|
|
||||||
|
|
||||||
info->commitHash = COMMIT_HASH;
|
|
||||||
info->config = configData.config;
|
|
||||||
info->versionMajor = (u8)(rev[1] - '0');
|
|
||||||
info->versionMinor = (u8)(rev[3] - '0');
|
|
||||||
|
|
||||||
bool isRelease;
|
|
||||||
|
|
||||||
if(rev[4] == '.')
|
|
||||||
{
|
{
|
||||||
info->versionBuild = (u8)(rev[5] - '0');
|
memcpy(*freeK11Space, svcGetCFWInfo_bin, svcGetCFWInfo_bin_size);
|
||||||
isRelease = rev[6] == 0;
|
|
||||||
|
struct CfwInfo
|
||||||
|
{
|
||||||
|
char magic[4];
|
||||||
|
|
||||||
|
u8 versionMajor;
|
||||||
|
u8 versionMinor;
|
||||||
|
u8 versionBuild;
|
||||||
|
u8 flags;
|
||||||
|
|
||||||
|
u32 commitHash;
|
||||||
|
|
||||||
|
u32 config;
|
||||||
|
} __attribute__((packed)) *info = (struct CfwInfo *)memsearch(*freeK11Space, "LUMA", svcGetCFWInfo_bin_size, 4);
|
||||||
|
|
||||||
|
const char *rev = REVISION;
|
||||||
|
|
||||||
|
info->commitHash = COMMIT_HASH;
|
||||||
|
info->config = configData.config;
|
||||||
|
info->versionMajor = (u8)(rev[1] - '0');
|
||||||
|
info->versionMinor = (u8)(rev[3] - '0');
|
||||||
|
|
||||||
|
bool isRelease;
|
||||||
|
|
||||||
|
if(rev[4] == '.')
|
||||||
|
{
|
||||||
|
info->versionBuild = (u8)(rev[5] - '0');
|
||||||
|
isRelease = rev[6] == 0;
|
||||||
|
}
|
||||||
|
else isRelease = rev[4] == 0;
|
||||||
|
|
||||||
|
info->flags = isRelease ? 1 : 0;
|
||||||
|
|
||||||
|
arm11SvcTable[0x2E] = baseK11VA + *freeK11Space - pos; //Stubbed svc
|
||||||
|
*freeK11Space += svcGetCFWInfo_bin_size;
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
}
|
}
|
||||||
else isRelease = rev[4] == 0;
|
|
||||||
|
|
||||||
info->flags = isRelease ? 1 : 0;
|
return ret;
|
||||||
|
|
||||||
arm11SvcTable[0x2E] = baseK11VA + *freeK11Space - pos; //Stubbed svc
|
|
||||||
*freeK11Space += svcGetCFWInfo_bin_size;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 patchTitleInstallMinVersionChecks(u8 *pos, u32 size, u32 firmVersion)
|
u32 patchTitleInstallMinVersionChecks(u8 *pos, u32 size, u32 firmVersion)
|
||||||
|
@ -28,20 +28,6 @@
|
|||||||
|
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
typedef struct __attribute__((packed))
|
|
||||||
{
|
|
||||||
char magic[4];
|
|
||||||
|
|
||||||
u8 versionMajor;
|
|
||||||
u8 versionMinor;
|
|
||||||
u8 versionBuild;
|
|
||||||
u8 flags;
|
|
||||||
|
|
||||||
u32 commitHash;
|
|
||||||
|
|
||||||
u32 config;
|
|
||||||
} CFWInfo;
|
|
||||||
|
|
||||||
extern CfgData configData;
|
extern CfgData configData;
|
||||||
|
|
||||||
u8 *getProcess9Info(u8 *pos, u32 size, u32 *process9Size, u32 *process9MemAddr);
|
u8 *getProcess9Info(u8 *pos, u32 size, u32 *process9Size, u32 *process9MemAddr);
|
||||||
@ -51,8 +37,8 @@ u32 patchTitleInstallMinVersionChecks(u8 *pos, u32 size, u32 firmVersion);
|
|||||||
u32 patchFirmlaunches(u8 *pos, u32 size, u32 process9MemAddr);
|
u32 patchFirmlaunches(u8 *pos, u32 size, u32 process9MemAddr);
|
||||||
u32 patchFirmWrites(u8 *pos, u32 size);
|
u32 patchFirmWrites(u8 *pos, u32 size);
|
||||||
u32 patchOldFirmWrites(u8 *pos, u32 size);
|
u32 patchOldFirmWrites(u8 *pos, u32 size);
|
||||||
void reimplementSvcBackdoor(u8 *pos, u32 *arm11SvcTable, u32 baseK11VA, u8 **freeK11Space);
|
u32 reimplementSvcBackdoor(u8 *pos, u32 *arm11SvcTable, u32 baseK11VA, u8 **freeK11Space);
|
||||||
void implementSvcGetCFWInfo(u8 *pos, u32 *arm11SvcTable, u32 baseK11VA, u8 **freeK11Space);
|
u32 implementSvcGetCFWInfo(u8 *pos, u32 *arm11SvcTable, u32 baseK11VA, u8 **freeK11Space);
|
||||||
u32 patchArm9ExceptionHandlersInstall(u8 *pos, u32 size);
|
u32 patchArm9ExceptionHandlersInstall(u8 *pos, u32 size);
|
||||||
u32 getInfoForArm11ExceptionHandlers(u8 *pos, u32 size, u32 *codeSetOffset);
|
u32 getInfoForArm11ExceptionHandlers(u8 *pos, u32 size, u32 *codeSetOffset);
|
||||||
u32 patchSvcBreak9(u8 *pos, u32 size, u32 kernel9Address);
|
u32 patchSvcBreak9(u8 *pos, u32 size, u32 kernel9Address);
|
||||||
|
@ -67,6 +67,21 @@ typedef struct __attribute__((packed))
|
|||||||
u8 hash[32];
|
u8 hash[32];
|
||||||
} PinData;
|
} PinData;
|
||||||
|
|
||||||
|
typedef struct __attribute__((packed))
|
||||||
|
{
|
||||||
|
u32 magic[2];
|
||||||
|
u16 versionMinor, versionMajor;
|
||||||
|
|
||||||
|
u16 processor, core;
|
||||||
|
u32 type;
|
||||||
|
|
||||||
|
u32 totalSize;
|
||||||
|
u32 registerDumpSize;
|
||||||
|
u32 codeDumpSize;
|
||||||
|
u32 stackDumpSize;
|
||||||
|
u32 additionalDataSize;
|
||||||
|
} ExceptionDumpHeader;
|
||||||
|
|
||||||
typedef enum FirmwareSource
|
typedef enum FirmwareSource
|
||||||
{
|
{
|
||||||
FIRMWARE_SYSNAND = 0,
|
FIRMWARE_SYSNAND = 0,
|
||||||
|
Reference in New Issue
Block a user