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

View File

@ -26,5 +26,7 @@
#define NCSD_MAGIC 0x4453434E #define NCSD_MAGIC 0x4453434E
void locateEmuNAND(u32 *off, u32 *head, FirmwareSource *emuNAND); extern u32 emuOffset;
void patchEmuNAND(u8 *arm9Section, u32 arm9SectionSize, u8 *process9Offset, u32 process9Size, u32 emuOffset, u32 emuHeader, u32 branchAdditive);
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 #pragma once
#include <stdbool.h>
#include "../../types.h" #include "../../types.h"

View File

@ -197,13 +197,13 @@ void main(void)
//If we need to boot emuNAND, make sure it exists //If we need to boot emuNAND, make sure it exists
if(nandType != FIRMWARE_SYSNAND) if(nandType != FIRMWARE_SYSNAND)
{ {
locateEmuNAND(&emuOffset, &emuHeader, &nandType); locateEmuNand(&emuOffset, &emuHeader, &nandType);
if(nandType == FIRMWARE_SYSNAND) firmSource = FIRMWARE_SYSNAND; if(nandType == FIRMWARE_SYSNAND) firmSource = FIRMWARE_SYSNAND;
} }
//Same if we're using emuNAND as the FIRM source //Same if we're using emuNAND as the FIRM source
else if(firmSource != FIRMWARE_SYSNAND) else if(firmSource != FIRMWARE_SYSNAND)
locateEmuNAND(&emuOffset, &emuHeader, &firmSource); locateEmuNand(&emuOffset, &emuHeader, &firmSource);
if(!isFirmlaunch) if(!isFirmlaunch)
{ {
@ -287,6 +287,10 @@ static inline void patchNativeFirm(u32 firmVersion, FirmwareSource nandType, u32
process9MemAddr; process9MemAddr;
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 free space locations
u8 *freeK11Space;
u32 *arm11SvcTable = getKernel11Info(arm11Section1, section[1].size, &freeK11Space);
//Apply signature patches //Apply signature patches
patchSignatureChecks(process9Offset, process9Size); patchSignatureChecks(process9Offset, process9Size);
@ -294,7 +298,7 @@ static inline void patchNativeFirm(u32 firmVersion, FirmwareSource nandType, u32
if(nandType != FIRMWARE_SYSNAND) if(nandType != FIRMWARE_SYSNAND)
{ {
u32 branchAdditive = (u32)firm + section[2].offset - (u32)section[2].address; 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 //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); patchTitleInstallMinVersionCheck(process9Offset, process9Size);
//Restore svcBackdoor //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) static inline void patchLegacyFirm(FirmwareType firmType)

View File

@ -27,33 +27,6 @@
#include "../build/svcGetCFWInfopatch.h" #include "../build/svcGetCFWInfopatch.h"
#include "../build/twl_k11modulespatch.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 *getProcess9(u8 *pos, u32 size, u32 *process9Size, u32 *process9MemAddr)
{ {
u8 *off = memsearch(pos, "ess9", size, 4); 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; 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) void patchSignatureChecks(u8 *pos, u32 size)
{ {
const u16 sigPatch[2] = {0x2000, 0x4770}; const u16 sigPatch[2] = {0x2000, 0x4770};
@ -126,7 +115,7 @@ void patchOldFirmWrites(u8 *pos, u32 size)
off[1] = writeBlockOld[1]; off[1] = writeBlockOld[1];
} }
void reimplementSvcBackdoor(u8 *pos, u32 size) void reimplementSvcBackdoor(u8 *pos, u32 *arm11SvcTable, 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
@ -140,26 +129,20 @@ void reimplementSvcBackdoor(u8 *pos, u32 size)
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
findArm11SvcTable(pos, size);
if(!arm11SvcTable[0x7B]) 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; const char *rev = REVISION;
bool isRelease; bool isRelease;
@ -177,10 +160,8 @@ void implementSvcGetCFWInfo(u8 *pos, u32 size)
info->flags = 0 /* master branch */ | ((isRelease ? 1 : 0) << 1) /* is release */; 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) void patchTitleInstallMinVersionCheck(u8 *pos, u32 size)

View File

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