Archived
Fixed CTRNAND writing leaving encrypted data (thanks to d0k3), added path.txt support for CTRNAND, have the firmlaunch patch panic if both payloads cannot be found
This commit is contained in:
@@ -113,6 +113,6 @@ void __attribute__((noreturn)) mainHandler(u32 *regs, u32 type)
|
|||||||
*(ExceptionDumpHeader *)FINAL_BUFFER = dumpHeader;
|
*(ExceptionDumpHeader *)FINAL_BUFFER = dumpHeader;
|
||||||
|
|
||||||
((void (*)())0xFFFF0830)(); //Ensure that all memory transfers have completed and that the data cache has been flushed
|
((void (*)())0xFFFF0830)(); //Ensure that all memory transfers have completed and that the data cache has been flushed
|
||||||
i2cWriteRegister(I2C_DEV_MCU, 0x20, 1 << 2); //Reboot
|
i2cWriteRegister(I2C_DEV_MCU, 0x20, 1 << 1); //Reboot
|
||||||
while(true);
|
while(true);
|
||||||
}
|
}
|
||||||
+10
-2
@@ -26,9 +26,12 @@ payload_maxsize equ 0x100000 ; Maximum size for the payload (maximum that CakeB
|
|||||||
bne pxi_wait_recv
|
bne pxi_wait_recv
|
||||||
|
|
||||||
adr r1, sd_fname
|
adr r1, sd_fname
|
||||||
|
mov r4, #0
|
||||||
|
|
||||||
open_payload:
|
open_payload:
|
||||||
; Open file
|
; Open file
|
||||||
|
cmp r4, #2 ; Panic if both payloads don't exist
|
||||||
|
beq svcBreak
|
||||||
add r0, r7, #8
|
add r0, r7, #8
|
||||||
mov r2, #1
|
mov r2, #1
|
||||||
ldr r6, [fopen]
|
ldr r6, [fopen]
|
||||||
@@ -36,6 +39,7 @@ payload_maxsize equ 0x100000 ; Maximum size for the payload (maximum that CakeB
|
|||||||
blx r6
|
blx r6
|
||||||
cmp r0, #0
|
cmp r0, #0
|
||||||
adrne r1, nand_fname
|
adrne r1, nand_fname
|
||||||
|
addne r4, #1
|
||||||
bne open_payload
|
bne open_payload
|
||||||
|
|
||||||
; Read file
|
; Read file
|
||||||
@@ -73,14 +77,18 @@ payload_maxsize equ 0x100000 ; Maximum size for the payload (maximum that CakeB
|
|||||||
die:
|
die:
|
||||||
b die
|
b die
|
||||||
|
|
||||||
|
svcBreak:
|
||||||
|
swi 0x3C
|
||||||
|
b die
|
||||||
|
|
||||||
bytes_read: .word 0
|
bytes_read: .word 0
|
||||||
fopen: .ascii "OPEN"
|
fopen: .ascii "OPEN"
|
||||||
.pool
|
.pool
|
||||||
sd_fname: .dcw "sdmc:/arm9loaderhax.bin"
|
sd_fname: .dcw "sdmc:/arm9loaderhax.bin"
|
||||||
.word 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
.word 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||||
.pool
|
.pool
|
||||||
nand_fname: .dcw "nand:/arm9loaderhax.bin"
|
nand_fname: .dcw "nand:/arm9loaderhax.bin"
|
||||||
.word 0
|
.word 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||||
|
|
||||||
.align 4
|
.align 4
|
||||||
kernelcode_start:
|
kernelcode_start:
|
||||||
|
|||||||
+1
-1
@@ -213,7 +213,7 @@ void configMenu(bool isSdMode, bool oldPinStatus, u32 oldPinMode)
|
|||||||
{ .visible = isSdMode },
|
{ .visible = isSdMode },
|
||||||
{ .visible = isSdMode },
|
{ .visible = isSdMode },
|
||||||
{ .visible = true },
|
{ .visible = true },
|
||||||
{ .visible = isSdMode },
|
{ .visible = true },
|
||||||
{ .visible = true },
|
{ .visible = true },
|
||||||
{ .visible = true },
|
{ .visible = true },
|
||||||
{ .visible = true },
|
{ .visible = true },
|
||||||
|
|||||||
+20
-6
@@ -24,6 +24,7 @@
|
|||||||
* Crypto libs from http://github.com/b1l1s/ctr
|
* Crypto libs from http://github.com/b1l1s/ctr
|
||||||
* kernel9Loader code originally adapted from https://github.com/Reisyukaku/ReiNand/blob/228c378255ba693133dec6f3368e14d386f2cde7/source/crypto.c#L233
|
* kernel9Loader code originally adapted from https://github.com/Reisyukaku/ReiNand/blob/228c378255ba693133dec6f3368e14d386f2cde7/source/crypto.c#L233
|
||||||
* decryptNusFirm code adapted from https://github.com/mid-kid/CakesForeveryWan/blob/master/source/firm.c
|
* decryptNusFirm code adapted from https://github.com/mid-kid/CakesForeveryWan/blob/master/source/firm.c
|
||||||
|
* ctrNandWrite logic adapted from https://github.com/d0k3/GodMode9/blob/master/source/nand/nand.c
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "crypto.h"
|
#include "crypto.h"
|
||||||
@@ -352,18 +353,31 @@ int ctrNandRead(u32 sector, u32 sectorCount, u8 *outbuf)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ctrNandWrite(u32 sector, u32 sectorCount, u8 *inbuf)
|
int ctrNandWrite(u32 sector, u32 sectorCount, const u8 *inbuf)
|
||||||
{
|
{
|
||||||
|
u8 *buffer = (u8 *)0x23000000;
|
||||||
|
u32 bufferSize = 0xF00000;
|
||||||
|
|
||||||
u8 __attribute__((aligned(4))) tmpCtr[sizeof(nandCtr)];
|
u8 __attribute__((aligned(4))) tmpCtr[sizeof(nandCtr)];
|
||||||
memcpy(tmpCtr, nandCtr, sizeof(nandCtr));
|
memcpy(tmpCtr, nandCtr, sizeof(nandCtr));
|
||||||
aes_advctr(tmpCtr, ((sector + fatStart) * 0x200) / AES_BLOCK_SIZE, AES_INPUT_BE | AES_INPUT_NORMAL);
|
aes_advctr(tmpCtr, ((sector + fatStart) * 0x200) / AES_BLOCK_SIZE, AES_INPUT_BE | AES_INPUT_NORMAL);
|
||||||
|
|
||||||
//Encrypt
|
|
||||||
aes_use_keyslot(nandSlot);
|
aes_use_keyslot(nandSlot);
|
||||||
aes(inbuf, inbuf, sectorCount * 0x200 / AES_BLOCK_SIZE, tmpCtr, AES_CTR_MODE, AES_INPUT_BE | AES_INPUT_NORMAL);
|
|
||||||
|
|
||||||
//Write
|
int result = 0;
|
||||||
return sdmmc_nand_writesectors(sector + fatStart, sectorCount, inbuf);
|
for(u32 i = 0; i < sectorCount && !result; i += bufferSize / 0x200)
|
||||||
|
{
|
||||||
|
u32 tempAmount = (bufferSize / 0x200) < (sectorCount - i) ? (bufferSize / 0x200) : (sectorCount - i);
|
||||||
|
|
||||||
|
memcpy(buffer, inbuf + (i * 0x200), tempAmount * 0x200);
|
||||||
|
|
||||||
|
//Encrypt
|
||||||
|
aes(buffer, buffer, tempAmount * 0x200 / AES_BLOCK_SIZE, tmpCtr, AES_CTR_MODE, AES_INPUT_BE | AES_INPUT_NORMAL);
|
||||||
|
|
||||||
|
//Write
|
||||||
|
result = sdmmc_nand_writesectors(i + sector + fatStart, tempAmount, buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void set6x7xKeys(void)
|
void set6x7xKeys(void)
|
||||||
|
|||||||
+2
-1
@@ -24,6 +24,7 @@
|
|||||||
* Crypto libs from http://github.com/b1l1s/ctr
|
* Crypto libs from http://github.com/b1l1s/ctr
|
||||||
* kernel9Loader code originally adapted from https://github.com/Reisyukaku/ReiNand/blob/228c378255ba693133dec6f3368e14d386f2cde7/source/crypto.c#L233
|
* kernel9Loader code originally adapted from https://github.com/Reisyukaku/ReiNand/blob/228c378255ba693133dec6f3368e14d386f2cde7/source/crypto.c#L233
|
||||||
* decryptNusFirm code adapted from https://github.com/mid-kid/CakesForeveryWan/blob/master/source/firm.c
|
* decryptNusFirm code adapted from https://github.com/mid-kid/CakesForeveryWan/blob/master/source/firm.c
|
||||||
|
* ctrNandWrite logic adapted from https://github.com/d0k3/GodMode9/blob/master/source/nand/nand.c
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
@@ -106,7 +107,7 @@ extern FirmwareSource firmSource;
|
|||||||
|
|
||||||
void ctrNandInit(void);
|
void ctrNandInit(void);
|
||||||
int ctrNandRead(u32 sector, u32 sectorCount, u8 *outbuf);
|
int ctrNandRead(u32 sector, u32 sectorCount, u8 *outbuf);
|
||||||
int ctrNandWrite(u32 sector, u32 sectorCount, u8 *inbuf);
|
int ctrNandWrite(u32 sector, u32 sectorCount, const u8 *inbuf);
|
||||||
void set6x7xKeys(void);
|
void set6x7xKeys(void);
|
||||||
bool decryptExeFs(Cxi *cxi);
|
bool decryptExeFs(Cxi *cxi);
|
||||||
bool decryptNusFirm(const Ticket *ticket, Cxi *cxi, u32 ncchSize);
|
bool decryptNusFirm(const Ticket *ticket, Cxi *cxi, u32 ncchSize);
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ DRESULT disk_write (
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
return ((pdrv == SDCARD && !sdmmc_sdcard_writesectors(sector, count, (BYTE *)buff)) ||
|
return ((pdrv == SDCARD && !sdmmc_sdcard_writesectors(sector, count, (BYTE *)buff)) ||
|
||||||
(pdrv == CTRNAND && !ctrNandWrite(sector, count, (BYTE *)buff))) ? RES_OK : RES_PARERR;
|
(pdrv == CTRNAND && !ctrNandWrite(sector, count, buff))) ? RES_OK : RES_PARERR;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -109,7 +109,7 @@ u32 loadFirm(FirmwareType *firmType, FirmwareSource nandType, bool loadFromStora
|
|||||||
return firmVersion;
|
return firmVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 patchNativeFirm(u32 firmVersion, FirmwareSource nandType, u32 emuHeader, u32 devMode)
|
u32 patchNativeFirm(u32 firmVersion, FirmwareSource nandType, u32 emuHeader, bool isSdMode, u32 devMode)
|
||||||
{
|
{
|
||||||
u8 *arm9Section = (u8 *)firm + firm->section[2].offset,
|
u8 *arm9Section = (u8 *)firm + firm->section[2].offset,
|
||||||
*arm11Section1 = (u8 *)firm + firm->section[1].offset;
|
*arm11Section1 = (u8 *)firm + firm->section[1].offset;
|
||||||
@@ -148,7 +148,7 @@ u32 patchNativeFirm(u32 firmVersion, FirmwareSource nandType, u32 emuHeader, u32
|
|||||||
else if(ISA9LH || (ISFIRMLAUNCH && BOOTCFG_A9LH != 0)) ret += patchFirmWrites(process9Offset, process9Size);
|
else if(ISA9LH || (ISFIRMLAUNCH && BOOTCFG_A9LH != 0)) ret += patchFirmWrites(process9Offset, process9Size);
|
||||||
|
|
||||||
//Apply firmlaunch patches
|
//Apply firmlaunch patches
|
||||||
ret += patchFirmlaunches(process9Offset, process9Size, process9MemAddr);
|
ret += patchFirmlaunches(process9Offset, process9Size, process9MemAddr, isSdMode);
|
||||||
|
|
||||||
//11.0 FIRM patches
|
//11.0 FIRM patches
|
||||||
if(firmVersion >= (ISN3DS ? 0x21 : 0x52))
|
if(firmVersion >= (ISN3DS ? 0x21 : 0x52))
|
||||||
|
|||||||
+1
-1
@@ -25,7 +25,7 @@
|
|||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
u32 loadFirm(FirmwareType *firmType, FirmwareSource nandType, bool loadFromStorage, bool isSdMode);
|
u32 loadFirm(FirmwareType *firmType, FirmwareSource nandType, bool loadFromStorage, bool isSdMode);
|
||||||
u32 patchNativeFirm(u32 firmVersion, FirmwareSource nandType, u32 emuHeader, u32 devMode);
|
u32 patchNativeFirm(u32 firmVersion, FirmwareSource nandType, u32 emuHeader, bool isSdMode, u32 devMode);
|
||||||
u32 patchTwlFirm(u32 firmVersion, u32 devMode);
|
u32 patchTwlFirm(u32 firmVersion, u32 devMode);
|
||||||
u32 patchAgbFirm(u32 devMode);
|
u32 patchAgbFirm(u32 devMode);
|
||||||
u32 patch1x2xNativeAndSafeFirm(u32 devMode);
|
u32 patch1x2xNativeAndSafeFirm(u32 devMode);
|
||||||
|
|||||||
+1
-1
@@ -230,7 +230,7 @@ void main(void)
|
|||||||
switch(firmType)
|
switch(firmType)
|
||||||
{
|
{
|
||||||
case NATIVE_FIRM:
|
case NATIVE_FIRM:
|
||||||
res = patchNativeFirm(firmVersion, nandType, emuHeader, devMode);
|
res = patchNativeFirm(firmVersion, nandType, emuHeader, isSdMode, devMode);
|
||||||
break;
|
break;
|
||||||
case SAFE_FIRM:
|
case SAFE_FIRM:
|
||||||
case NATIVE_FIRM1X2X:
|
case NATIVE_FIRM1X2X:
|
||||||
|
|||||||
+2
-2
@@ -101,7 +101,7 @@ u32 patchSignatureChecks(u8 *pos, u32 size)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 patchFirmlaunches(u8 *pos, u32 size, u32 process9MemAddr)
|
u32 patchFirmlaunches(u8 *pos, u32 size, u32 process9MemAddr, bool isSdMode)
|
||||||
{
|
{
|
||||||
//Look for firmlaunch code
|
//Look for firmlaunch code
|
||||||
const u8 pattern[] = {0xE2, 0x20, 0x20, 0x90};
|
const u8 pattern[] = {0xE2, 0x20, 0x20, 0x90};
|
||||||
@@ -146,7 +146,7 @@ u32 patchFirmlaunches(u8 *pos, u32 size, u32 process9MemAddr)
|
|||||||
finalPath[i] = (u16)path[i];
|
finalPath[i] = (u16)path[i];
|
||||||
finalPath[pathSize] = 0;
|
finalPath[pathSize] = 0;
|
||||||
|
|
||||||
u8 *pos_path = memsearch(off, u"sd", reboot_bin_size, 4) + 0xA;
|
u8 *pos_path = memsearch(off, isSdMode ? u"sd" : u"na", reboot_bin_size, 4) + 0xA;
|
||||||
memcpy(pos_path, finalPath, (pathSize + 1) * 2);
|
memcpy(pos_path, finalPath, (pathSize + 1) * 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -34,7 +34,7 @@ u8 *getProcess9Info(u8 *pos, u32 size, u32 *process9Size, u32 *process9MemAddr);
|
|||||||
u32 *getKernel11Info(u8 *pos, u32 size, u32 *baseK11VA, u8 **freeK11Space, u32 **arm11SvcHandler, u32 **arm11ExceptionsPage);
|
u32 *getKernel11Info(u8 *pos, u32 size, u32 *baseK11VA, u8 **freeK11Space, u32 **arm11SvcHandler, u32 **arm11ExceptionsPage);
|
||||||
u32 patchSignatureChecks(u8 *pos, u32 size);
|
u32 patchSignatureChecks(u8 *pos, u32 size);
|
||||||
u32 patchTitleInstallMinVersionChecks(u8 *pos, u32 size, u32 firmVersion);
|
u32 patchTitleInstallMinVersionChecks(u8 *pos, u32 size, u32 firmVersion);
|
||||||
u32 patchFirmlaunches(u8 *pos, u32 size, u32 process9MemAddr);
|
u32 patchFirmlaunches(u8 *pos, u32 size, u32 process9MemAddr, bool isSdMode);
|
||||||
u32 patchFirmWrites(u8 *pos, u32 size);
|
u32 patchFirmWrites(u8 *pos, u32 size);
|
||||||
u32 patchOldFirmWrites(u8 *pos, u32 size);
|
u32 patchOldFirmWrites(u8 *pos, u32 size);
|
||||||
u32 reimplementSvcBackdoor(u8 *pos, u32 *arm11SvcTable, u32 baseK11VA, u8 **freeK11Space);
|
u32 reimplementSvcBackdoor(u8 *pos, u32 *arm11SvcTable, u32 baseK11VA, u8 **freeK11Space);
|
||||||
|
|||||||
+2
-2
@@ -56,7 +56,7 @@ u32 waitInput(void)
|
|||||||
|
|
||||||
void mcuReboot(void)
|
void mcuReboot(void)
|
||||||
{
|
{
|
||||||
if(ISFIRMLAUNCH && PDN_GPU_CNT != 1) clearScreens(true, true, false);
|
if(!ISFIRMLAUNCH && PDN_GPU_CNT != 1) clearScreens(true, true, 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();
|
||||||
@@ -67,7 +67,7 @@ void mcuReboot(void)
|
|||||||
|
|
||||||
void mcuPowerOff(void)
|
void mcuPowerOff(void)
|
||||||
{
|
{
|
||||||
if(ISFIRMLAUNCH && PDN_GPU_CNT != 1) clearScreens(true, true, false);
|
if(!ISFIRMLAUNCH && PDN_GPU_CNT != 1) clearScreens(true, true, 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();
|
||||||
|
|||||||
Reference in New Issue
Block a user