Cleanup and refactoring

This commit is contained in:
Aurora 2016-08-29 15:35:24 +02:00
parent ad9e00acaa
commit 8209433696
6 changed files with 70 additions and 83 deletions

View File

@ -25,12 +25,12 @@
#include "fatfs/sdmmc/sdmmc.h"
#include "../build/emunandpatch.h"
void locateEmuNAND(u32 *off, u32 *head, FirmwareSource *emuNAND)
void locateEmuNand(u32 *off, u32 *head, FirmwareSource *emuNand)
{
static u8 temp[0x200];
const u32 nandSize = getMMCDevice(0)->total_size;
u32 nandOffset = *emuNAND == FIRMWARE_EMUNAND ? 0 :
u32 nandOffset = *emuNand == FIRMWARE_EMUNAND ? 0 :
(nandSize > 0x200000 ? 0x400000 : 0x200000);
//Check for RedNAND
@ -53,12 +53,12 @@ void locateEmuNAND(u32 *off, u32 *head, FirmwareSource *emuNAND)
or to SysNAND if there isn't any */
else
{
*emuNAND = (*emuNAND == FIRMWARE_EMUNAND2) ? FIRMWARE_EMUNAND : FIRMWARE_SYSNAND;
if(*emuNAND) locateEmuNAND(off, head, emuNAND);
*emuNand = (*emuNand == FIRMWARE_EMUNAND2) ? FIRMWARE_EMUNAND : FIRMWARE_SYSNAND;
if(*emuNand) locateEmuNand(off, head, emuNand);
}
}
static inline void *getEmuCode(u8 *pos, u32 size)
static inline void *getFreeK9Space(u8 *pos, u32 size)
{
const u8 pattern[] = {0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0x00};
@ -66,7 +66,7 @@ static inline void *getEmuCode(u8 *pos, u32 size)
return memsearch(pos + 0x13500, pattern, size - 0x13500, 6) + 0x455;
}
static inline u32 getSDMMC(u8 *pos, u32 size)
static inline u32 getSdmmc(u8 *pos, u32 size)
{
//Look for struct code
const u8 pattern[] = {0x21, 0x20, 0x18, 0x20};
@ -75,7 +75,7 @@ static inline u32 getSDMMC(u8 *pos, u32 size)
return *(u32 *)(off + 9) + *(u32 *)(off + 0xD);
}
static inline void patchNANDRW(u8 *pos, u32 size, u32 branchOffset)
static inline void patchNandRw(u8 *pos, u32 size, u32 branchOffset)
{
const u16 nandRedir[2] = {0x4C00, 0x47A0};
@ -93,7 +93,7 @@ static inline void patchNANDRW(u8 *pos, u32 size, u32 branchOffset)
((u32 *)writeOffset)[1] = branchOffset;
}
static inline void patchMPU(u8 *pos, u32 size)
static inline void patchMpu(u8 *pos, u32 size)
{
const u32 mpuPatch[3] = {0x00360003, 0x00200603, 0x001C0603};
@ -107,26 +107,26 @@ static inline void patchMPU(u8 *pos, u32 size)
off[9] = mpuPatch[2];
}
void patchEmuNAND(u8 *arm9Section, u32 arm9SectionSize, u8 *process9Offset, u32 process9Size, u32 emuOffset, u32 emuHeader, u32 branchAdditive)
void patchEmuNand(u8 *arm9Section, u32 arm9SectionSize, u8 *process9Offset, u32 process9Size, u32 emuHeader, u32 branchAdditive)
{
//Copy emuNAND code
void *emuCodeOffset = getEmuCode(arm9Section, arm9SectionSize);
memcpy(emuCodeOffset, emunand, emunand_size);
void *freeK9Space = getFreeK9Space(arm9Section, arm9SectionSize);
memcpy(freeK9Space, emunand, emunand_size);
//Add the data of the found emuNAND
u32 *pos_offset = (u32 *)memsearch(emuCodeOffset, "NAND", emunand_size, 4),
*pos_header = (u32 *)memsearch(emuCodeOffset, "NCSD", emunand_size, 4);
*pos_offset = emuOffset;
*pos_header = emuHeader;
u32 *posOffset = (u32 *)memsearch(freeK9Space, "NAND", emunand_size, 4),
*posHeader = (u32 *)memsearch(freeK9Space, "NCSD", emunand_size, 4);
*posOffset = emuOffset;
*posHeader = emuHeader;
//Find and add the SDMMC struct
u32 *pos_sdmmc = (u32 *)memsearch(emuCodeOffset, "SDMC", emunand_size, 4);
*pos_sdmmc = getSDMMC(process9Offset, process9Size);
u32 *posSdmmc = (u32 *)memsearch(freeK9Space, "SDMC", emunand_size, 4);
*posSdmmc = getSdmmc(process9Offset, process9Size);
//Add emuNAND hooks
u32 branchOffset = (u32)emuCodeOffset - branchAdditive;
patchNANDRW(process9Offset, process9Size, branchOffset);
u32 branchOffset = (u32)freeK9Space - branchAdditive;
patchNandRw(process9Offset, process9Size, branchOffset);
//Set MPU for emu code region
patchMPU(arm9Section, arm9SectionSize);
patchMpu(arm9Section, arm9SectionSize);
}

View File

@ -26,5 +26,7 @@
#define NCSD_MAGIC 0x4453434E
void locateEmuNAND(u32 *off, u32 *head, FirmwareSource *emuNAND);
void patchEmuNAND(u8 *arm9Section, u32 arm9SectionSize, u8 *process9Offset, u32 process9Size, u32 emuOffset, u32 emuHeader, u32 branchAdditive);
extern u32 emuOffset;
void locateEmuNand(u32 *off, u32 *head, FirmwareSource *emuNand);
void patchEmuNand(u8 *arm9Section, u32 arm9SectionSize, u8 *process9Offset, u32 process9Size, u32 emuHeader, u32 branchAdditive);

View File

@ -1,4 +1,3 @@
#pragma once
#include <stdbool.h>
#include "../../types.h"

View File

@ -197,13 +197,13 @@ void main(void)
//If we need to boot emuNAND, make sure it exists
if(nandType != FIRMWARE_SYSNAND)
{
locateEmuNAND(&emuOffset, &emuHeader, &nandType);
locateEmuNand(&emuOffset, &emuHeader, &nandType);
if(nandType == FIRMWARE_SYSNAND) firmSource = FIRMWARE_SYSNAND;
}
//Same if we're using emuNAND as the FIRM source
else if(firmSource != FIRMWARE_SYSNAND)
locateEmuNAND(&emuOffset, &emuHeader, &firmSource);
locateEmuNand(&emuOffset, &emuHeader, &firmSource);
if(!isFirmlaunch)
{
@ -287,6 +287,10 @@ static inline void patchNativeFirm(u32 firmVersion, FirmwareSource nandType, u32
process9MemAddr;
u8 *process9Offset = getProcess9(arm9Section + 0x15000, section[2].size - 0x15000, &process9Size, &process9MemAddr);
//Find Kernel11 SVC table and free space locations
u8 *freeK11Space;
u32 *arm11SvcTable = getKernel11Info(arm11Section1, section[1].size, &freeK11Space);
//Apply signature patches
patchSignatureChecks(process9Offset, process9Size);
@ -294,7 +298,7 @@ static inline void patchNativeFirm(u32 firmVersion, FirmwareSource nandType, u32
if(nandType != FIRMWARE_SYSNAND)
{
u32 branchAdditive = (u32)firm + section[2].offset - (u32)section[2].address;
patchEmuNAND(arm9Section, section[2].size, process9Offset, process9Size, emuOffset, emuHeader, branchAdditive);
patchEmuNand(arm9Section, section[2].size, process9Offset, process9Size, emuHeader, branchAdditive);
}
//Apply FIRM0/1 writes patches on sysNAND to protect A9LH
@ -310,10 +314,10 @@ static inline void patchNativeFirm(u32 firmVersion, FirmwareSource nandType, u32
patchTitleInstallMinVersionCheck(process9Offset, process9Size);
//Restore svcBackdoor
reimplementSvcBackdoor(arm11Section1, section[1].size);
reimplementSvcBackdoor(arm11Section1, arm11SvcTable, &freeK11Space);
}
implementSvcGetCFWInfo(arm11Section1, section[1].size);
implementSvcGetCFWInfo(arm11Section1, arm11SvcTable, &freeK11Space);
}
static inline void patchLegacyFirm(FirmwareType firmType)

View File

@ -27,33 +27,6 @@
#include "../build/svcGetCFWInfopatch.h"
#include "../build/twl_k11modulespatch.h"
static u32 *arm11SvcTable = NULL;
static u8 *freeK11Space = NULL;
static void findArm11SvcTable(u8 *pos, u32 size)
{
if(arm11SvcTable == NULL)
{
const u8 pattern[] = {0x00, 0xB0, 0x9C, 0xE5};
u32 *arm11ExceptionsPage = (u32 *)memsearch(pos, pattern, size, 4) - 0xB;
u32 svcOffset = (-((arm11ExceptionsPage[2] & 0xFFFFFF) << 2) & (0xFFFFFF << 2)) - 8; //Branch offset + 8 for prefetch
arm11SvcTable = (u32 *)(pos + *(u32 *)(pos + 0xFFFF0008 - svcOffset - 0xFFF00000 + 8) - 0xFFF00000); //SVC handler address
while(*arm11SvcTable) arm11SvcTable++; //Look for SVC0 (NULL)
}
}
static void findFreeK11Space(u8 *pos, u32 size)
{
if(freeK11Space == NULL)
{
const u8 pattern[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
freeK11Space = memsearch(pos, pattern, size, 5) + 1;
}
}
u8 *getProcess9(u8 *pos, u32 size, u32 *process9Size, u32 *process9MemAddr)
{
u8 *off = memsearch(pos, "ess9", size, 4);
@ -65,6 +38,22 @@ 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)
{
const u8 pattern[] = {0x00, 0xB0, 0x9C, 0xE5};
u32 *arm11ExceptionsPage = (u32 *)memsearch(pos, pattern, size, 4) - 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
while(*arm11SvcTable) arm11SvcTable++; //Look for SVC0 (NULL)
const u8 pattern2[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
*freeK11Space = memsearch(pos, pattern2, size, 5) + 1;
return arm11SvcTable;
}
void patchSignatureChecks(u8 *pos, u32 size)
{
const u16 sigPatch[2] = {0x2000, 0x4770};
@ -126,40 +115,34 @@ void patchOldFirmWrites(u8 *pos, u32 size)
off[1] = writeBlockOld[1];
}
void reimplementSvcBackdoor(u8 *pos, u32 size)
void reimplementSvcBackdoor(u8 *pos, u32 *arm11SvcTable, u8 **freeK11Space)
{
//Official implementation of svcBackdoor
const u8 svcBackdoor[40] = {0xFF, 0x10, 0xCD, 0xE3, //bic r1, sp, #0xff
0x0F, 0x1C, 0x81, 0xE3, //orr r1, r1, #0xf00
0x28, 0x10, 0x81, 0xE2, //add r1, r1, #0x28
0x00, 0x20, 0x91, 0xE5, //ldr r2, [r1]
0x00, 0x60, 0x22, 0xE9, //stmdb r2!, {sp, lr}
0x02, 0xD0, 0xA0, 0xE1, //mov sp, r2
0x30, 0xFF, 0x2F, 0xE1, //blx r0
0x03, 0x00, 0xBD, 0xE8, //pop {r0, r1}
0x00, 0xD0, 0xA0, 0xE1, //mov sp, r0
0x11, 0xFF, 0x2F, 0xE1}; //bx r1
findArm11SvcTable(pos, size);
0x0F, 0x1C, 0x81, 0xE3, //orr r1, r1, #0xf00
0x28, 0x10, 0x81, 0xE2, //add r1, r1, #0x28
0x00, 0x20, 0x91, 0xE5, //ldr r2, [r1]
0x00, 0x60, 0x22, 0xE9, //stmdb r2!, {sp, lr}
0x02, 0xD0, 0xA0, 0xE1, //mov sp, r2
0x30, 0xFF, 0x2F, 0xE1, //blx r0
0x03, 0x00, 0xBD, 0xE8, //pop {r0, r1}
0x00, 0xD0, 0xA0, 0xE1, //mov sp, r0
0x11, 0xFF, 0x2F, 0xE1}; //bx r1
if(!arm11SvcTable[0x7B])
{
findFreeK11Space(pos, size);
memcpy(*freeK11Space, svcBackdoor, 40);
memcpy(freeK11Space, svcBackdoor, 40);
arm11SvcTable[0x7B] = 0xFFF00000 + freeK11Space - pos;
freeK11Space += 40;
arm11SvcTable[0x7B] = 0xFFF00000 + *freeK11Space - pos;
(*freeK11Space) += 40;
}
}
void implementSvcGetCFWInfo(u8 *pos, u32 size)
void implementSvcGetCFWInfo(u8 *pos, u32 *arm11SvcTable, u8 **freeK11Space)
{
findFreeK11Space(pos, size);
memcpy(freeK11Space, svcGetCFWInfo, svcGetCFWInfo_size);
memcpy(*freeK11Space, svcGetCFWInfo, svcGetCFWInfo_size);
CFWInfo *info = (CFWInfo *)memsearch(freeK11Space, "LUMA", svcGetCFWInfo_size, 4);
CFWInfo *info = (CFWInfo *)memsearch(*freeK11Space, "LUMA", svcGetCFWInfo_size, 4);
const char *rev = REVISION;
bool isRelease;
@ -177,10 +160,8 @@ void implementSvcGetCFWInfo(u8 *pos, u32 size)
info->flags = 0 /* master branch */ | ((isRelease ? 1 : 0) << 1) /* is release */;
findArm11SvcTable(pos, size);
arm11SvcTable[0x2E] = 0xFFF00000 + freeK11Space - pos; //Stubbed svc
freeK11Space += svcGetCFWInfo_size;
arm11SvcTable[0x2E] = 0xFFF00000 + *freeK11Space - pos; //Stubbed svc
(*freeK11Space) += svcGetCFWInfo_size;
}
void patchTitleInstallMinVersionCheck(u8 *pos, u32 size)

View File

@ -50,12 +50,13 @@ 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);
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 size);
void implementSvcGetCFWInfo(u8 *pos, u32 size);
void reimplementSvcBackdoor(u8 *pos, u32 *arm11SvcTable, u8 **freeK11Space);
void implementSvcGetCFWInfo(u8 *pos, u32 *arm11SvcTable, u8 **freeK11Space);
void applyLegacyFirmPatches(u8 *pos, FirmwareType firmType);
void patchTwlBg(u8 *pos);