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:
Aurora 2016-10-11 16:52:51 +02:00
parent fde2c371ef
commit 615e5dfaa7
12 changed files with 45 additions and 22 deletions

View File

@ -113,6 +113,6 @@ void __attribute__((noreturn)) mainHandler(u32 *regs, u32 type)
*(ExceptionDumpHeader *)FINAL_BUFFER = dumpHeader;
((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);
}

View File

@ -26,9 +26,12 @@ payload_maxsize equ 0x100000 ; Maximum size for the payload (maximum that CakeB
bne pxi_wait_recv
adr r1, sd_fname
mov r4, #0
open_payload:
; Open file
cmp r4, #2 ; Panic if both payloads don't exist
beq svcBreak
add r0, r7, #8
mov r2, #1
ldr r6, [fopen]
@ -36,6 +39,7 @@ payload_maxsize equ 0x100000 ; Maximum size for the payload (maximum that CakeB
blx r6
cmp r0, #0
adrne r1, nand_fname
addne r4, #1
bne open_payload
; Read file
@ -73,14 +77,18 @@ payload_maxsize equ 0x100000 ; Maximum size for the payload (maximum that CakeB
die:
b die
svcBreak:
swi 0x3C
b die
bytes_read: .word 0
fopen: .ascii "OPEN"
.pool
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
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
kernelcode_start:

View File

@ -213,7 +213,7 @@ void configMenu(bool isSdMode, bool oldPinStatus, u32 oldPinMode)
{ .visible = isSdMode },
{ .visible = isSdMode },
{ .visible = true },
{ .visible = isSdMode },
{ .visible = true },
{ .visible = true },
{ .visible = true },
{ .visible = true },

View File

@ -24,6 +24,7 @@
* Crypto libs from http://github.com/b1l1s/ctr
* 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
* ctrNandWrite logic adapted from https://github.com/d0k3/GodMode9/blob/master/source/nand/nand.c
*/
#include "crypto.h"
@ -352,18 +353,31 @@ int ctrNandRead(u32 sector, u32 sectorCount, u8 *outbuf)
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)];
memcpy(tmpCtr, nandCtr, sizeof(nandCtr));
aes_advctr(tmpCtr, ((sector + fatStart) * 0x200) / AES_BLOCK_SIZE, AES_INPUT_BE | AES_INPUT_NORMAL);
//Encrypt
aes_use_keyslot(nandSlot);
aes(inbuf, inbuf, sectorCount * 0x200 / AES_BLOCK_SIZE, tmpCtr, AES_CTR_MODE, AES_INPUT_BE | AES_INPUT_NORMAL);
//Write
return sdmmc_nand_writesectors(sector + fatStart, sectorCount, inbuf);
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
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)

View File

@ -24,6 +24,7 @@
* Crypto libs from http://github.com/b1l1s/ctr
* 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
* ctrNandWrite logic adapted from https://github.com/d0k3/GodMode9/blob/master/source/nand/nand.c
*/
#pragma once
@ -106,7 +107,7 @@ extern FirmwareSource firmSource;
void ctrNandInit(void);
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);
bool decryptExeFs(Cxi *cxi);
bool decryptNusFirm(const Ticket *ticket, Cxi *cxi, u32 ncchSize);

View File

@ -88,7 +88,7 @@ DRESULT disk_write (
)
{
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

View File

@ -109,7 +109,7 @@ u32 loadFirm(FirmwareType *firmType, FirmwareSource nandType, bool loadFromStora
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,
*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);
//Apply firmlaunch patches
ret += patchFirmlaunches(process9Offset, process9Size, process9MemAddr);
ret += patchFirmlaunches(process9Offset, process9Size, process9MemAddr, isSdMode);
//11.0 FIRM patches
if(firmVersion >= (ISN3DS ? 0x21 : 0x52))

View File

@ -25,7 +25,7 @@
#include "types.h"
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 patchAgbFirm(u32 devMode);
u32 patch1x2xNativeAndSafeFirm(u32 devMode);

View File

@ -230,7 +230,7 @@ void main(void)
switch(firmType)
{
case NATIVE_FIRM:
res = patchNativeFirm(firmVersion, nandType, emuHeader, devMode);
res = patchNativeFirm(firmVersion, nandType, emuHeader, isSdMode, devMode);
break;
case SAFE_FIRM:
case NATIVE_FIRM1X2X:

View File

@ -101,7 +101,7 @@ u32 patchSignatureChecks(u8 *pos, u32 size)
return ret;
}
u32 patchFirmlaunches(u8 *pos, u32 size, u32 process9MemAddr)
u32 patchFirmlaunches(u8 *pos, u32 size, u32 process9MemAddr, bool isSdMode)
{
//Look for firmlaunch code
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[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);
}
}

View File

@ -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 patchSignatureChecks(u8 *pos, u32 size);
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 patchOldFirmWrites(u8 *pos, u32 size);
u32 reimplementSvcBackdoor(u8 *pos, u32 *arm11SvcTable, u32 baseK11VA, u8 **freeK11Space);

View File

@ -56,7 +56,7 @@ u32 waitInput(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
flushEntireDCache();
@ -67,11 +67,11 @@ void mcuReboot(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
flushEntireDCache();
i2cWriteRegister(I2C_DEV_MCU, 0x20, 1 << 0);
while(true);
}