General cleanup/refactoring
This commit is contained in:
parent
a8b2e9a50c
commit
78a7d6c5af
@ -441,31 +441,10 @@ bool decryptNusFirm(const Ticket *ticket, Cxi *cxi, u32 ncchSize)
|
|||||||
return decryptExeFs(cxi);
|
return decryptExeFs(cxi);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void twlConsoleInfoInit(void)
|
|
||||||
{
|
|
||||||
u64 twlConsoleId = CFG_UNITINFO != 0 ? OTP_DEVCONSOLEID : (0x80000000ULL | (*(vu64 *)0x01FFB808 ^ 0x8C267B7B358A6AFULL));
|
|
||||||
CFG_TWLUNITINFO = CFG_UNITINFO;
|
|
||||||
OTP_TWLCONSOLEID = twlConsoleId;
|
|
||||||
|
|
||||||
*REG_AESCNT = 0;
|
|
||||||
|
|
||||||
vu32 *k3X = REGs_AESTWLKEYS[3][1], *k1X = REGs_AESTWLKEYS[1][1];
|
|
||||||
|
|
||||||
k3X[0] = (u32)twlConsoleId;
|
|
||||||
k3X[3] = (u32)(twlConsoleId >> 32);
|
|
||||||
|
|
||||||
k1X[2] = (u32)(twlConsoleId >> 32);
|
|
||||||
k1X[3] = (u32)twlConsoleId;
|
|
||||||
}
|
|
||||||
|
|
||||||
void kernel9Loader(Arm9Bin *arm9Section)
|
void kernel9Loader(Arm9Bin *arm9Section)
|
||||||
{
|
{
|
||||||
//Determine the kernel9loader version
|
//Determine the kernel9loader version
|
||||||
u32 k9lVersion;
|
u32 k9lVersion;
|
||||||
if(arm9Section == NULL)
|
|
||||||
k9lVersion = 2;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
switch(arm9Section->magic[3])
|
switch(arm9Section->magic[3])
|
||||||
{
|
{
|
||||||
case 0xFF:
|
case 0xFF:
|
||||||
@ -476,12 +455,10 @@ void kernel9Loader(Arm9Bin *arm9Section)
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
k9lVersion = 2;
|
k9lVersion = 2;
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 *startOfArm9Bin = (u32 *)((u8 *)arm9Section + 0x800);
|
u32 *startOfArm9Bin = (u32 *)((u8 *)arm9Section + 0x800);
|
||||||
bool needToDecrypt = arm9Section != NULL && *startOfArm9Bin != 0x47704770 && *startOfArm9Bin != 0xB0862000;
|
if(*startOfArm9Bin == 0x47704770 || *startOfArm9Bin == 0xB0862000) return; //Already decrypted
|
||||||
|
|
||||||
//Set 0x11 keyslot
|
//Set 0x11 keyslot
|
||||||
__attribute__((aligned(4))) const u8 key1s[2][AES_BLOCK_SIZE] = {
|
__attribute__((aligned(4))) const u8 key1s[2][AES_BLOCK_SIZE] = {
|
||||||
@ -495,8 +472,6 @@ void kernel9Loader(Arm9Bin *arm9Section)
|
|||||||
|
|
||||||
aes_setkey(0x11, k9lVersion == 2 ? key2s[ISDEVUNIT ? 1 : 0] : key1s[ISDEVUNIT ? 1 : 0], AES_KEYNORMAL, AES_INPUT_BE | AES_INPUT_NORMAL);
|
aes_setkey(0x11, k9lVersion == 2 ? key2s[ISDEVUNIT ? 1 : 0] : key1s[ISDEVUNIT ? 1 : 0], AES_KEYNORMAL, AES_INPUT_BE | AES_INPUT_NORMAL);
|
||||||
|
|
||||||
if(needToDecrypt)
|
|
||||||
{
|
|
||||||
u8 arm9BinSlot = k9lVersion == 0 ? 0x15 : 0x16;
|
u8 arm9BinSlot = k9lVersion == 0 ? 0x15 : 0x16;
|
||||||
|
|
||||||
//Set keyX
|
//Set keyX
|
||||||
@ -519,44 +494,6 @@ void kernel9Loader(Arm9Bin *arm9Section)
|
|||||||
aes(startOfArm9Bin, startOfArm9Bin, decAtoi(arm9Section->size, sizeof(arm9Section->size)) / AES_BLOCK_SIZE, arm9BinCtr, AES_CTR_MODE, AES_INPUT_BE | AES_INPUT_NORMAL);
|
aes(startOfArm9Bin, startOfArm9Bin, decAtoi(arm9Section->size, sizeof(arm9Section->size)) / AES_BLOCK_SIZE, arm9BinCtr, AES_CTR_MODE, AES_INPUT_BE | AES_INPUT_NORMAL);
|
||||||
|
|
||||||
if(*startOfArm9Bin != 0x47704770 && *startOfArm9Bin != 0xB0862000) error("Failed to decrypt the ARM9 binary.");
|
if(*startOfArm9Bin != 0x47704770 && *startOfArm9Bin != 0xB0862000) error("Failed to decrypt the ARM9 binary.");
|
||||||
}
|
|
||||||
|
|
||||||
__attribute__((aligned(4))) u8 keyBlocks[2][AES_BLOCK_SIZE] = {
|
|
||||||
{0xA4, 0x8D, 0xE4, 0xF1, 0x0B, 0x36, 0x44, 0xAA, 0x90, 0x31, 0x28, 0xFF, 0x4D, 0xCA, 0x76, 0xDF},
|
|
||||||
{0xDD, 0xDA, 0xA4, 0xC6, 0x2C, 0xC4, 0x50, 0xE9, 0xDA, 0xB6, 0x9B, 0x0D, 0x9D, 0x2A, 0x21, 0x98}
|
|
||||||
}, decKey[AES_BLOCK_SIZE];
|
|
||||||
|
|
||||||
u8 firstKey;
|
|
||||||
u32 keyBlocksIndex;
|
|
||||||
|
|
||||||
if(k9lVersion == 2)
|
|
||||||
{
|
|
||||||
firstKey = 0x19;
|
|
||||||
keyBlocksIndex = 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
firstKey = 0x18;
|
|
||||||
keyBlocksIndex = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
aes_use_keyslot(0x11);
|
|
||||||
for(u8 slot = firstKey; slot < 0x20; slot++, keyBlocks[keyBlocksIndex][0xF]++)
|
|
||||||
{
|
|
||||||
aes(decKey, keyBlocks[keyBlocksIndex], 1, NULL, AES_ECB_DECRYPT_MODE, 0);
|
|
||||||
aes_setkey(slot, decKey, AES_KEYX, AES_INPUT_BE | AES_INPUT_NORMAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(k9lVersion == 2)
|
|
||||||
{
|
|
||||||
aes_setkey(0x11, key1s[ISDEVUNIT ? 1 : 0], AES_KEYNORMAL, AES_INPUT_BE | AES_INPUT_NORMAL);
|
|
||||||
aes_use_keyslot(0x11);
|
|
||||||
aes(decKey, keyBlocks[0], 1, NULL, AES_ECB_DECRYPT_MODE, 0);
|
|
||||||
aes_setkey(0x18, decKey, AES_KEYX, AES_INPUT_BE | AES_INPUT_NORMAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(ISSIGHAX)
|
|
||||||
twlConsoleInfoInit();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void computePinHash(u8 *outbuf, const u8 *inbuf)
|
void computePinHash(u8 *outbuf, const u8 *inbuf)
|
||||||
|
@ -376,7 +376,7 @@ void launchFirm(FirmwareType firmType, bool loadFromStorage)
|
|||||||
for(; sectionNum < 4 && firm->section[sectionNum].size != 0; sectionNum++)
|
for(; sectionNum < 4 && firm->section[sectionNum].size != 0; sectionNum++)
|
||||||
memcpy(firm->section[sectionNum].address, (u8 *)firm + firm->section[sectionNum].offset, firm->section[sectionNum].size);
|
memcpy(firm->section[sectionNum].address, (u8 *)firm + firm->section[sectionNum].offset, firm->section[sectionNum].size);
|
||||||
|
|
||||||
if(!ISFIRMLAUNCH) deinitScreens();
|
if(!isFirmlaunch) deinitScreens();
|
||||||
|
|
||||||
//Set ARM11 kernel entrypoint
|
//Set ARM11 kernel entrypoint
|
||||||
ARM11_CORE0_MAILBOX_ENTRYPOINT = (u32)firm->arm11Entry;
|
ARM11_CORE0_MAILBOX_ENTRYPOINT = (u32)firm->arm11Entry;
|
||||||
|
@ -189,9 +189,6 @@ void loadPayload(u32 pressed, const char *payloadPath)
|
|||||||
char absPath[24 + _MAX_LFN] = {0};
|
char absPath[24 + _MAX_LFN] = {0};
|
||||||
char path[10 + _MAX_LFN] = {0};
|
char path[10 + _MAX_LFN] = {0};
|
||||||
|
|
||||||
u16 mountPoint[5] = {0};
|
|
||||||
for(u32 i = 0; i < 4 && launchedPath[i] != u':'; i++)
|
|
||||||
|
|
||||||
if(payloadPath == NULL)
|
if(payloadPath == NULL)
|
||||||
{
|
{
|
||||||
const char *pattern;
|
const char *pattern;
|
||||||
@ -212,7 +209,6 @@ void loadPayload(u32 pressed, const char *payloadPath)
|
|||||||
FILINFO info;
|
FILINFO info;
|
||||||
FRESULT result;
|
FRESULT result;
|
||||||
|
|
||||||
|
|
||||||
result = f_findfirst(&dir, &info, "payloads", pattern);
|
result = f_findfirst(&dir, &info, "payloads", pattern);
|
||||||
|
|
||||||
if(result != FR_OK) return;
|
if(result != FR_OK) return;
|
||||||
@ -232,7 +228,7 @@ void loadPayload(u32 pressed, const char *payloadPath)
|
|||||||
|
|
||||||
writeConfig(true);
|
writeConfig(true);
|
||||||
|
|
||||||
if(memcmp(mountPoint, u"nand", 8))
|
if(memcmp(launchedPath, u"nand", 8))
|
||||||
sprintf(absPath, "nand:/rw/luma/%s", path);
|
sprintf(absPath, "nand:/rw/luma/%s", path);
|
||||||
else
|
else
|
||||||
sprintf(absPath, "sdmc:/luma/%s", path);
|
sprintf(absPath, "sdmc:/luma/%s", path);
|
||||||
|
@ -38,19 +38,18 @@ extern CfgData configData;
|
|||||||
extern ConfigurationStatus needConfig;
|
extern ConfigurationStatus needConfig;
|
||||||
extern FirmwareSource firmSource;
|
extern FirmwareSource firmSource;
|
||||||
|
|
||||||
u16 launchedFirmTidLow[8];
|
bool isFirmlaunch;
|
||||||
u16 launchedPath[7 + 255];
|
u16 launchedPath[41];
|
||||||
|
|
||||||
void main(int argc, char **argv)
|
void main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
bool isSafeMode = false,
|
bool isSafeMode = false,
|
||||||
isNoForceFlagSet = false;
|
isNoForceFlagSet = false;
|
||||||
|
char errbuf[46];
|
||||||
u32 emuHeader;
|
u32 emuHeader;
|
||||||
FirmwareType firmType;
|
FirmwareType firmType;
|
||||||
FirmwareSource nandType;
|
FirmwareSource nandType;
|
||||||
|
|
||||||
char errbuf[128];
|
|
||||||
|
|
||||||
switch(argc)
|
switch(argc)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
@ -60,12 +59,12 @@ void main(int argc, char **argv)
|
|||||||
case 1: //Normal boot
|
case 1: //Normal boot
|
||||||
{
|
{
|
||||||
u32 i;
|
u32 i;
|
||||||
for(i = 0; i < 6 + 255 && argv[0][i] != 0; i++) //Copy and convert the path to utf16
|
for(i = 0; i < 40 && argv[0][i] != 0; i++) //Copy and convert the path to utf16
|
||||||
launchedPath[i] = argv[0][i];
|
launchedPath[i] = argv[0][i];
|
||||||
for(; i < 7 + 255; i++)
|
for(; i < 41; i++)
|
||||||
launchedPath[i] = 0;
|
launchedPath[i] = 0;
|
||||||
|
|
||||||
memset(launchedFirmTidLow, 0, 16);
|
isFirmlaunch = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,34 +72,32 @@ void main(int argc, char **argv)
|
|||||||
{
|
{
|
||||||
u32 i;
|
u32 i;
|
||||||
u16 *p = (u16 *)argv[0];
|
u16 *p = (u16 *)argv[0];
|
||||||
for(i = 0; i < 6 + 255 && p[i] != 0; i++)
|
for(i = 0; i < 40 && p[i] != 0; i++)
|
||||||
launchedPath[i] = p[i];
|
launchedPath[i] = p[i];
|
||||||
for(; i < 7 + 255; i++)
|
for(; i < 41; i++)
|
||||||
launchedPath[i] = 0;
|
launchedPath[i] = 0;
|
||||||
|
|
||||||
memcpy(launchedFirmTidLow, (u16 *)argv[1], 16);
|
isFirmlaunch = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
sprintf(errbuf, "Unsupported launcher (argc = %d > 2).", argc);
|
{
|
||||||
|
sprintf(errbuf, "Unsupported launcher (argc = %d).", argc);
|
||||||
error(errbuf);
|
error(errbuf);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
u16 mountPoint[5] = {0};
|
|
||||||
for(u32 i = 0; i < 4 && launchedPath[i] != u':'; i++)
|
|
||||||
mountPoint[i] = launchedPath[i];
|
|
||||||
|
|
||||||
//Mount SD or CTRNAND
|
//Mount SD or CTRNAND
|
||||||
bool isSdMode;
|
bool isSdMode;
|
||||||
|
|
||||||
if(memcmp(mountPoint, u"sdmc", 8) == 0)
|
if(memcmp(launchedPath, u"sdmc", 8) == 0)
|
||||||
{
|
{
|
||||||
if(!mountFs(true, false)) error("Failed to mount SD.");
|
if(!mountFs(true, false)) error("Failed to mount SD.");
|
||||||
isSdMode = true;
|
isSdMode = true;
|
||||||
}
|
}
|
||||||
else if(memcmp(mountPoint, u"nand", 8) == 0)
|
else if(memcmp(launchedPath, u"nand", 8) == 0)
|
||||||
{
|
{
|
||||||
firmSource = FIRMWARE_SYSNAND;
|
firmSource = FIRMWARE_SYSNAND;
|
||||||
if(!mountFs(false, true)) error("Failed to mount SD and CTRNAND.");
|
if(!mountFs(false, true)) error("Failed to mount SD and CTRNAND.");
|
||||||
@ -108,11 +105,10 @@ void main(int argc, char **argv)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
char mount8[5] = {0};
|
char mountPoint[5] = {0};
|
||||||
for(u32 i = 0 ; i < 4; i++)
|
for(u32 i = 0; i < 4 && launchedPath[i] != u':'; i++)
|
||||||
mount8[i] = (char)mountPoint[i];
|
mountPoint[i] = (char)launchedPath[i];
|
||||||
|
sprintf(errbuf, "Launched from an unsupported location: %s.", mountPoint);
|
||||||
sprintf(errbuf, "Launched from an unsupported location: %s.", mount8);
|
|
||||||
error(errbuf);
|
error(errbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,19 +116,19 @@ void main(int argc, char **argv)
|
|||||||
needConfig = readConfig() ? MODIFY_CONFIGURATION : CREATE_CONFIGURATION;
|
needConfig = readConfig() ? MODIFY_CONFIGURATION : CREATE_CONFIGURATION;
|
||||||
|
|
||||||
//Determine if this is a firmlaunch boot
|
//Determine if this is a firmlaunch boot
|
||||||
if(ISFIRMLAUNCH)
|
if(isFirmlaunch)
|
||||||
{
|
{
|
||||||
if(needConfig == CREATE_CONFIGURATION) mcuPowerOff();
|
if(needConfig == CREATE_CONFIGURATION) mcuPowerOff();
|
||||||
|
|
||||||
switch(launchedFirmTidLow[7])
|
switch(argv[1][14])
|
||||||
{
|
{
|
||||||
case u'2':
|
case '2':
|
||||||
firmType = (FirmwareType)(launchedFirmTidLow[5] - u'0');
|
firmType = (FirmwareType)(argv[1][10] - '0');
|
||||||
break;
|
break;
|
||||||
case u'3':
|
case '3':
|
||||||
firmType = SAFE_FIRM;
|
firmType = SAFE_FIRM;
|
||||||
break;
|
break;
|
||||||
case u'1':
|
case '1':
|
||||||
firmType = SYSUPDATER_FIRM;
|
firmType = SYSUPDATER_FIRM;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -285,7 +281,7 @@ boot:
|
|||||||
else if(firmSource != FIRMWARE_SYSNAND)
|
else if(firmSource != FIRMWARE_SYSNAND)
|
||||||
locateEmuNand(&emuHeader, &firmSource);
|
locateEmuNand(&emuHeader, &firmSource);
|
||||||
|
|
||||||
if(!ISFIRMLAUNCH)
|
if(!isFirmlaunch)
|
||||||
{
|
{
|
||||||
configData.config = (configData.config & 0xFFFFFF80) | ((u32)isNoForceFlagSet << 6) | ((u32)firmSource << 3) | (u32)nandType;
|
configData.config = (configData.config & 0xFFFFFF80) | ((u32)isNoForceFlagSet << 6) | ((u32)firmSource << 3) | (u32)nandType;
|
||||||
writeConfig(false);
|
writeConfig(false);
|
||||||
|
@ -120,10 +120,9 @@ u32 patchFirmlaunches(u8 *pos, u32 size, u32 process9MemAddr)
|
|||||||
const u8 pattern[] = {0xE2, 0x20, 0x20, 0x90};
|
const u8 pattern[] = {0xE2, 0x20, 0x20, 0x90};
|
||||||
|
|
||||||
u32 pathLen;
|
u32 pathLen;
|
||||||
for(pathLen = 0; launchedPath[pathLen] != 0; pathLen++);
|
for(pathLen = 0; pathLen < 41 && launchedPath[pathLen] != 0; pathLen++);
|
||||||
|
|
||||||
if(pathLen > 82)
|
if(launchedPath[pathLen] != 0) return 1;
|
||||||
return 1;
|
|
||||||
|
|
||||||
u8 *off = memsearch(pos, pattern, size, sizeof(pattern));
|
u8 *off = memsearch(pos, pattern, size, sizeof(pattern));
|
||||||
|
|
||||||
@ -142,7 +141,7 @@ u32 patchFirmlaunches(u8 *pos, u32 size, u32 process9MemAddr)
|
|||||||
*pos_fopen = fOpenOffset;
|
*pos_fopen = fOpenOffset;
|
||||||
|
|
||||||
u16 *fname = (u16 *)memsearch(off, u"sdmc", reboot_bin_size, 8);
|
u16 *fname = (u16 *)memsearch(off, u"sdmc", reboot_bin_size, 8);
|
||||||
memcpy(fname, launchedPath, 82);
|
memcpy(fname, launchedPath, 2 * (1 + pathLen));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,7 @@
|
|||||||
#include "i2c.h"
|
#include "i2c.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
static vu32 *arm11Entry;
|
static vu32 *arm11Entry = (vu32 *)0x1FFFFFFC;
|
||||||
|
|
||||||
static const u32 brightness[4] = {0x5F, 0x4C, 0x39, 0x26};
|
static const u32 brightness[4] = {0x5F, 0x4C, 0x39, 0x26};
|
||||||
|
|
||||||
@ -57,8 +57,6 @@ static void invokeArm11Function(void (*func)())
|
|||||||
|
|
||||||
if(!hasCopiedStub)
|
if(!hasCopiedStub)
|
||||||
{
|
{
|
||||||
arm11Entry = (vu32 *)((ISSIGHAX) ? 0x1FFFFFFC : 0x1FFFFFF8);
|
|
||||||
flushDCacheRange(&arm11Entry, 4);
|
|
||||||
memcpy((void *)ARM11_STUB_ADDRESS, arm11Stub, 0x2C);
|
memcpy((void *)ARM11_STUB_ADDRESS, arm11Stub, 0x2C);
|
||||||
hasCopiedStub = true;
|
hasCopiedStub = true;
|
||||||
}
|
}
|
||||||
|
@ -60,8 +60,6 @@ typedef volatile s64 vs64;
|
|||||||
|
|
||||||
#define ISN3DS (PDN_MPCORE_CFG == 7)
|
#define ISN3DS (PDN_MPCORE_CFG == 7)
|
||||||
#define ISDEVUNIT (CFG_UNITINFO != 0)
|
#define ISDEVUNIT (CFG_UNITINFO != 0)
|
||||||
#define ISSIGHAX (!(CFG_SYSPROT9 & 2))
|
|
||||||
#define ISFIRMLAUNCH (launchedFirmTidLow[5] != 0)
|
|
||||||
|
|
||||||
typedef struct __attribute__((packed))
|
typedef struct __attribute__((packed))
|
||||||
{
|
{
|
||||||
@ -115,4 +113,5 @@ typedef enum FirmwareType
|
|||||||
} FirmwareType;
|
} FirmwareType;
|
||||||
|
|
||||||
extern u16 launchedFirmTidLow[8];
|
extern u16 launchedFirmTidLow[8];
|
||||||
extern u16 launchedPath[7 + 255];
|
extern u16 launchedPath[41];
|
||||||
|
extern bool isFirmlaunch;
|
||||||
|
@ -89,7 +89,7 @@ u32 waitInput(bool isMenu)
|
|||||||
|
|
||||||
void mcuPowerOff(void)
|
void mcuPowerOff(void)
|
||||||
{
|
{
|
||||||
if(!ISFIRMLAUNCH && ARESCREENSINITIALIZED) clearScreens(false);
|
if(!isFirmlaunch && ARESCREENSINITIALIZED) clearScreens(false);
|
||||||
|
|
||||||
//Ensure that all memory transfers have completed and that the data cache has been flushed
|
//Ensure that all memory transfers have completed and that the data cache has been flushed
|
||||||
flushEntireDCache();
|
flushEntireDCache();
|
||||||
@ -106,7 +106,7 @@ void wait(u64 amount)
|
|||||||
|
|
||||||
void error(const char *message)
|
void error(const char *message)
|
||||||
{
|
{
|
||||||
if(!ISFIRMLAUNCH)
|
if(!isFirmlaunch)
|
||||||
{
|
{
|
||||||
initScreens();
|
initScreens();
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user