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:
parent
fde2c371ef
commit
615e5dfaa7
@ -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);
|
||||||
}
|
}
|
@ -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,6 +77,10 @@ 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
|
||||||
@ -80,7 +88,7 @@ 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:
|
||||||
|
@ -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 },
|
||||||
|
@ -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);
|
||||||
|
aes_use_keyslot(nandSlot);
|
||||||
|
|
||||||
|
int result = 0;
|
||||||
|
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
|
//Encrypt
|
||||||
aes_use_keyslot(nandSlot);
|
aes(buffer, buffer, tempAmount * 0x200 / AES_BLOCK_SIZE, tmpCtr, AES_CTR_MODE, AES_INPUT_BE | AES_INPUT_NORMAL);
|
||||||
aes(inbuf, inbuf, sectorCount * 0x200 / AES_BLOCK_SIZE, tmpCtr, AES_CTR_MODE, AES_INPUT_BE | AES_INPUT_NORMAL);
|
|
||||||
|
|
||||||
//Write
|
//Write
|
||||||
return sdmmc_nand_writesectors(sector + fatStart, sectorCount, inbuf);
|
result = sdmmc_nand_writesectors(i + sector + fatStart, tempAmount, buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void set6x7xKeys(void)
|
void set6x7xKeys(void)
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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))
|
||||||
|
@ -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);
|
||||||
|
@ -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:
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
@ -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