Groundwork
Change the payload loader location Always set keys 0x18..0x1F Set arm11 entrypoint correctly
This commit is contained in:
@@ -4,7 +4,7 @@ OUTPUT_ARCH(arm)
|
|||||||
ENTRY(_start)
|
ENTRY(_start)
|
||||||
SECTIONS
|
SECTIONS
|
||||||
{
|
{
|
||||||
. = 0x24FFFE00;
|
. = 0x27FFE000;
|
||||||
|
|
||||||
.text : ALIGN(4) { *(.text.start) *(.text*); . = ALIGN(4); }
|
.text : ALIGN(4) { *(.text.start) *(.text*); . = ALIGN(4); }
|
||||||
.rodata : ALIGN(4) { *(.rodata*); . = ALIGN(4); }
|
.rodata : ALIGN(4) { *(.rodata*); . = ALIGN(4); }
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
.align 4
|
.align 4
|
||||||
.global _start
|
.global _start
|
||||||
_start:
|
_start:
|
||||||
|
ldr sp, =0x27ffe000
|
||||||
b main
|
b main
|
||||||
|
|
||||||
.global payloadSize
|
.global payloadSize
|
||||||
|
|||||||
@@ -484,6 +484,10 @@ 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:
|
||||||
@@ -496,9 +500,10 @@ void kernel9Loader(Arm9Bin *arm9Section)
|
|||||||
k9lVersion = 2;
|
k9lVersion = 2;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
u32 *startOfArm9Bin = (u32 *)((u8 *)arm9Section + 0x800);
|
u32 *startOfArm9Bin = (u32 *)((u8 *)arm9Section + 0x800);
|
||||||
bool needToDecrypt = *startOfArm9Bin != 0x47704770 && *startOfArm9Bin != 0xB0862000;
|
bool needToDecrypt = arm9Section != NULL && *startOfArm9Bin != 0x47704770 && *startOfArm9Bin != 0xB0862000;
|
||||||
|
|
||||||
//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] = {
|
||||||
@@ -564,10 +569,6 @@ void kernel9Loader(Arm9Bin *arm9Section)
|
|||||||
aes_setkey(slot, decKey, AES_KEYX, AES_INPUT_BE | AES_INPUT_NORMAL);
|
aes_setkey(slot, decKey, AES_KEYX, AES_INPUT_BE | AES_INPUT_NORMAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!ISSIGHAX) return;
|
|
||||||
|
|
||||||
twlConsoleInfoInit();
|
|
||||||
|
|
||||||
if(k9lVersion == 2)
|
if(k9lVersion == 2)
|
||||||
{
|
{
|
||||||
aes_setkey(0x11, key1s[ISDEVUNIT ? 1 : 0], AES_KEYNORMAL, AES_INPUT_BE | AES_INPUT_NORMAL);
|
aes_setkey(0x11, key1s[ISDEVUNIT ? 1 : 0], AES_KEYNORMAL, AES_INPUT_BE | AES_INPUT_NORMAL);
|
||||||
@@ -575,6 +576,9 @@ void kernel9Loader(Arm9Bin *arm9Section)
|
|||||||
aes(decKey, keyBlocks[0], 1, NULL, AES_ECB_DECRYPT_MODE, 0);
|
aes(decKey, keyBlocks[0], 1, NULL, AES_ECB_DECRYPT_MODE, 0);
|
||||||
aes_setkey(0x18, decKey, AES_KEYX, AES_INPUT_BE | AES_INPUT_NORMAL);
|
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)
|
||||||
|
|||||||
@@ -128,6 +128,9 @@ u32 patchNativeFirm(u32 firmVersion, FirmwareSource nandType, u32 emuHeader, boo
|
|||||||
//Sets the 7.x NCCH KeyX and the 6.x gamecard save data KeyY on >= 6.0 O3DS FIRMs, if not using A9LH
|
//Sets the 7.x NCCH KeyX and the 6.x gamecard save data KeyY on >= 6.0 O3DS FIRMs, if not using A9LH
|
||||||
else if(!ISA9LH && !ISFIRMLAUNCH && firmVersion >= 0x29) set6x7xKeys();
|
else if(!ISA9LH && !ISFIRMLAUNCH && firmVersion >= 0x29) set6x7xKeys();
|
||||||
|
|
||||||
|
if(!ISN3DS)
|
||||||
|
kernel9Loader(NULL); //Just set the N3DS 9.6+ keys even on O3DS
|
||||||
|
|
||||||
//Find the Process9 .code location, size and memory address
|
//Find the Process9 .code location, size and memory address
|
||||||
u32 process9Size,
|
u32 process9Size,
|
||||||
process9MemAddr;
|
process9MemAddr;
|
||||||
@@ -227,6 +230,8 @@ u32 patchTwlFirm(u32 firmVersion, bool doUnitinfoPatch)
|
|||||||
kernel9Loader((Arm9Bin *)arm9Section);
|
kernel9Loader((Arm9Bin *)arm9Section);
|
||||||
firm->arm9Entry = (u8 *)0x801301C;
|
firm->arm9Entry = (u8 *)0x801301C;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
kernel9Loader(NULL); //Just set the keys
|
||||||
|
|
||||||
//Find the Process9 .code location, size and memory address
|
//Find the Process9 .code location, size and memory address
|
||||||
u32 process9Size,
|
u32 process9Size,
|
||||||
@@ -260,6 +265,8 @@ u32 patchAgbFirm(bool doUnitinfoPatch)
|
|||||||
kernel9Loader((Arm9Bin *)arm9Section);
|
kernel9Loader((Arm9Bin *)arm9Section);
|
||||||
firm->arm9Entry = (u8 *)0x801301C;
|
firm->arm9Entry = (u8 *)0x801301C;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
kernel9Loader(NULL); //Just set the keys
|
||||||
|
|
||||||
//Find the Process9 .code location, size and memory address
|
//Find the Process9 .code location, size and memory address
|
||||||
u32 process9Size,
|
u32 process9Size,
|
||||||
@@ -288,6 +295,8 @@ u32 patch1x2xNativeAndSafeFirm(bool enableExceptionHandlers)
|
|||||||
kernel9Loader((Arm9Bin *)arm9Section);
|
kernel9Loader((Arm9Bin *)arm9Section);
|
||||||
firm->arm9Entry = (u8 *)0x801B01C;
|
firm->arm9Entry = (u8 *)0x801B01C;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
kernel9Loader(NULL); //Just set the keys
|
||||||
|
|
||||||
//Find the Process9 .code location, size and memory address
|
//Find the Process9 .code location, size and memory address
|
||||||
u32 process9Size,
|
u32 process9Size,
|
||||||
@@ -381,17 +390,13 @@ 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);
|
||||||
|
|
||||||
//Determine the ARM11 entry to use
|
if(!ISFIRMLAUNCH) deinitScreens();
|
||||||
vu32 *arm11;
|
|
||||||
if(ISFIRMLAUNCH) arm11 = (vu32 *)0x1FFFFFFC;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
deinitScreens();
|
|
||||||
arm11 = (vu32 *)BRAHMA_ARM11_ENTRY;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Set ARM11 kernel entrypoint
|
//Set ARM11 kernel entrypoint
|
||||||
*arm11 = (u32)firm->arm11Entry;
|
if(ISFIRMLAUNCH | ISSIGHAX)
|
||||||
|
ARM11_CORE0_MAILBOX_ENTRYPOINT = (u32)firm->arm11Entry;
|
||||||
|
else
|
||||||
|
BRAHMA_ARM11_ENTRYPOINT = (u32)firm->arm11Entry;
|
||||||
|
|
||||||
//Ensure that all memory transfers have completed and that the caches have been flushed
|
//Ensure that all memory transfers have completed and that the caches have been flushed
|
||||||
flushEntireDCache();
|
flushEntireDCache();
|
||||||
|
|||||||
@@ -119,7 +119,7 @@ void fileDelete(const char *path)
|
|||||||
void loadPayload(u32 pressed, const char *payloadPath)
|
void loadPayload(u32 pressed, const char *payloadPath)
|
||||||
{
|
{
|
||||||
u32 *loaderAddress = (u32 *)0x24FFFE00;
|
u32 *loaderAddress = (u32 *)0x24FFFE00;
|
||||||
u8 *payloadAddress = (u8 *)0x24F00000;
|
u8 *payloadAddress = (u8 *)0x27FFE000;
|
||||||
u32 payloadSize = 0,
|
u32 payloadSize = 0,
|
||||||
maxPayloadSize = (u32)((u8 *)loaderAddress - payloadAddress);
|
maxPayloadSize = (u32)((u8 *)loaderAddress - payloadAddress);
|
||||||
|
|
||||||
|
|||||||
@@ -164,7 +164,11 @@ void main(void)
|
|||||||
pressed = HID_PAD;
|
pressed = HID_PAD;
|
||||||
}
|
}
|
||||||
else if(((pressed & SINGLE_PAYLOAD_BUTTONS) && !(pressed & (BUTTON_L1 | BUTTON_R1 | BUTTON_A))) ||
|
else if(((pressed & SINGLE_PAYLOAD_BUTTONS) && !(pressed & (BUTTON_L1 | BUTTON_R1 | BUTTON_A))) ||
|
||||||
((pressed & L_PAYLOAD_BUTTONS) && (pressed & BUTTON_L1))) loadPayload(pressed, NULL);
|
((pressed & L_PAYLOAD_BUTTONS) && (pressed & BUTTON_L1)))
|
||||||
|
{
|
||||||
|
kernel9Loader(NULL);
|
||||||
|
loadPayload(pressed, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
if(splashMode == 2) loadSplash();
|
if(splashMode == 2) loadSplash();
|
||||||
|
|
||||||
|
|||||||
@@ -42,7 +42,8 @@
|
|||||||
#include "i2c.h"
|
#include "i2c.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
vu32 *arm11Entry = (vu32 *)BRAHMA_ARM11_ENTRY;
|
static vu32 *arm11Entry;
|
||||||
|
|
||||||
static const u32 brightness[4] = {0x5F, 0x4C, 0x39, 0x26};
|
static const u32 brightness[4] = {0x5F, 0x4C, 0x39, 0x26};
|
||||||
|
|
||||||
void __attribute__((naked)) arm11Stub(void)
|
void __attribute__((naked)) arm11Stub(void)
|
||||||
@@ -56,6 +57,7 @@ static void invokeArm11Function(void (*func)())
|
|||||||
|
|
||||||
if(!hasCopiedStub)
|
if(!hasCopiedStub)
|
||||||
{
|
{
|
||||||
|
arm11Entry = (vu32 *)((ISFIRMLAUNCH | ISSIGHAX) ? 0x1FFFFFFC : 0x1FFFFFF8);
|
||||||
memcpy((void *)ARM11_STUB_ADDRESS, arm11Stub, 0x2C);
|
memcpy((void *)ARM11_STUB_ADDRESS, arm11Stub, 0x2C);
|
||||||
hasCopiedStub = true;
|
hasCopiedStub = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,7 +47,8 @@ typedef volatile s64 vs64;
|
|||||||
|
|
||||||
#include "3dsheaders.h"
|
#include "3dsheaders.h"
|
||||||
|
|
||||||
#define BRAHMA_ARM11_ENTRY 0x1FFFFFF8
|
#define BRAHMA_ARM11_ENTRYPOINT *(vu32 *)0x1FFFFFF8
|
||||||
|
#define ARM11_CORE0_MAILBOX_ENTRYPOINT *(vu32 *)0x1FFFFFFC
|
||||||
|
|
||||||
#define CFG_SYSPROT9 (*(vu8 *)0x10000000)
|
#define CFG_SYSPROT9 (*(vu8 *)0x10000000)
|
||||||
#define CFG_BOOTENV (*(vu32 *)0x10010000)
|
#define CFG_BOOTENV (*(vu32 *)0x10010000)
|
||||||
@@ -61,7 +62,7 @@ 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 ISA9LH (!PDN_SPI_CNT)
|
#define ISA9LH (!PDN_SPI_CNT)
|
||||||
#define ISSIGHAX (!(CFG_SYSPROT9 & 2))
|
#define ISSIGHAX (!PDN_SPI_CNT && !(CFG_SYSPROT9 & 2))
|
||||||
#define ISFIRMLAUNCH (launchedFirmTidLow[5] != 0)
|
#define ISFIRMLAUNCH (launchedFirmTidLow[5] != 0)
|
||||||
|
|
||||||
typedef struct __attribute__((packed))
|
typedef struct __attribute__((packed))
|
||||||
|
|||||||
Reference in New Issue
Block a user