Allow uninstalling on 11.0/11.1 or greater. On 11.0/11.1 it's possible to load 10.4 FIRM from SD card named as 'firm104.bin' in the a9lh folder

This commit is contained in:
Aurora 2016-10-17 16:22:35 +02:00
parent 68fce834fb
commit 1cc678adc3
3 changed files with 62 additions and 13 deletions

View File

@ -32,6 +32,11 @@ bool mountFs(bool isSd)
return isSd ? f_mount(&fs, "0:", 1) == FR_OK : f_mount(&fs, "1:", 1) == FR_OK; return isSd ? f_mount(&fs, "0:", 1) == FR_OK : f_mount(&fs, "1:", 1) == FR_OK;
} }
void unmountCtrNand(void)
{
f_mount(NULL, "1:", 1);
}
u32 fileRead(void *dest, const char *path, u32 maxSize) u32 fileRead(void *dest, const char *path, u32 maxSize)
{ {
FIL file; FIL file;
@ -118,7 +123,7 @@ u32 firmRead(void *dest)
} }
//FIRM is equal or newer than 11.0 //FIRM is equal or newer than 11.0
if(tempVersion >= (ISN3DS ? 0x21 : 0x52)) ret = 2; if(tempVersion >= (ISN3DS ? 0x21 : 0x52)) ret = tempVersion <= (ISN3DS ? 0x26 : 0x56) ? 5 : 2;
//Found an older cxi //Found an older cxi
if(tempVersion < firmVersion) firmVersion = tempVersion; if(tempVersion < firmVersion) firmVersion = tempVersion;
@ -132,7 +137,7 @@ u32 firmRead(void *dest)
concatenateStrings(path, "/00000000.app"); concatenateStrings(path, "/00000000.app");
//Convert back the .app name from integer to array //Convert back the .app name from integer to array
hexItoa(firmVersion, &path[35], 8); hexItoa(firmVersion, path + 35, 8);
if(!fileRead(dest, path, 0x100000)) ret = 3; if(!fileRead(dest, path, 0x100000)) ret = 3;
} }

View File

@ -25,6 +25,7 @@
#include "types.h" #include "types.h"
bool mountFs(bool isSd); bool mountFs(bool isSd);
void unmountCtrNand(void);
u32 fileRead(void *dest, const char *path, u32 maxSize); u32 fileRead(void *dest, const char *path, u32 maxSize);
bool fileWrite(const void *buffer, const char *path, u32 size); bool fileWrite(const void *buffer, const char *path, u32 size);
u32 firmRead(void *dest); u32 firmRead(void *dest);

View File

@ -36,6 +36,14 @@ static const u8 sectorHash[SHA_256_HASH_SIZE] = {
firm1Hash[SHA_256_HASH_SIZE] = { firm1Hash[SHA_256_HASH_SIZE] = {
0xD2, 0x53, 0xC1, 0xCC, 0x0A, 0x5F, 0xFA, 0xC6, 0xB3, 0x83, 0xDA, 0xC1, 0x82, 0x7C, 0xFB, 0x3B, 0xD2, 0x53, 0xC1, 0xCC, 0x0A, 0x5F, 0xFA, 0xC6, 0xB3, 0x83, 0xDA, 0xC1, 0x82, 0x7C, 0xFB, 0x3B,
0x2D, 0x3D, 0x56, 0x6C, 0x6A, 0x1A, 0x8E, 0x52, 0x54, 0xE3, 0x89, 0xC2, 0x95, 0x06, 0x23, 0xE5 0x2D, 0x3D, 0x56, 0x6C, 0x6A, 0x1A, 0x8E, 0x52, 0x54, 0xE3, 0x89, 0xC2, 0x95, 0x06, 0x23, 0xE5
},
firm104O3DSHash[SHA_256_HASH_SIZE] = {
0x5D, 0x33, 0xD9, 0xCE, 0xE3, 0x39, 0x05, 0xD5, 0xCE, 0x37, 0xFE, 0xFB, 0xB5, 0xEC, 0x73, 0x6A,
0xA0, 0x10, 0xAD, 0x87, 0xF8, 0xDC, 0x55, 0x39, 0xFD, 0xDB, 0x48, 0x69, 0xAC, 0x5F, 0x3C, 0x2B
},
firm104N3DSHash[SHA_256_HASH_SIZE] = {
0x2D, 0x6B, 0xCC, 0xCE, 0x3B, 0x81, 0xD7, 0xCA, 0x67, 0x17, 0x90, 0x33, 0x35, 0x4D, 0xFA, 0xA5,
0x70, 0xF4, 0x7A, 0x99, 0xBB, 0x60, 0x0C, 0x2F, 0x34, 0x90, 0xFF, 0x10, 0xD4, 0x4C, 0x97, 0x42
}; };
u32 posY; u32 posY;
@ -47,8 +55,8 @@ void main(void)
initScreens(); initScreens();
drawString(TITLE, 10, 10, COLOR_TITLE); posY = drawString(TITLE, 10, 10, COLOR_TITLE);
posY = drawString("Thanks to delebile, #cakey and StandardBus", 10, 40, COLOR_WHITE); posY = drawString("Thanks to delebile, #cakey and StandardBus", 10, posY + SPACING_Y, COLOR_WHITE);
if(!sdmmc_sdcard_init(isOtpless)) if(!sdmmc_sdcard_init(isOtpless))
shutdown(1, "Error: failed to initialize SD and NAND"); shutdown(1, "Error: failed to initialize SD and NAND");
@ -235,7 +243,7 @@ static inline void installer(bool isOtpless)
if(missingStage1Hash || missingStage2Hash) if(missingStage1Hash || missingStage2Hash)
{ {
posY = drawString("Couldn't verify stage1 and/or stage2 integrity!", 10, posY + 10, COLOR_RED); posY = drawString("Couldn't verify stage1 and/or stage2 integrity!", 10, posY + SPACING_Y, COLOR_RED);
posY = drawString("Continuing might be dangerous!", 10, posY, COLOR_RED); posY = drawString("Continuing might be dangerous!", 10, posY, COLOR_RED);
inputSequence(); inputSequence();
} }
@ -267,10 +275,6 @@ static inline void uninstaller(void)
{ {
u8 keySector[512]; u8 keySector[512];
posY = drawString("You are about to uninstall A9LH!", 10, posY + 10, COLOR_RED);
posY = drawString("Doing this will require having 9.0 to reinstall!", 10, posY, COLOR_RED);
inputSequence();
//New 3DSes need a key sector with a proper key2, Old 3DSes have a blank key sector //New 3DSes need a key sector with a proper key2, Old 3DSes have a blank key sector
if(ISN3DS) if(ISN3DS)
{ {
@ -291,13 +295,41 @@ static inline void uninstaller(void)
shutdown(1, "Error: failed to mount CTRNAND"); shutdown(1, "Error: failed to mount CTRNAND");
//Read FIRM cxi from CTRNAND //Read FIRM cxi from CTRNAND
switch(firmRead((void *)FIRM0_OFFSET)) u32 firmSize = 0,
result = firmRead((void *)FIRM0_OFFSET);
switch(result)
{ {
case 1: case 1:
shutdown(1, "Error: more than one FIRM cxi has been detected"); shutdown(1, "Error: more than one FIRM cxi has been detected");
break; break;
case 5:
posY = drawString("FIRM 11.0 or 11.1 has been detected!", 10, posY + SPACING_Y, COLOR_RED);
posY = drawString("Press SELECT to load 10.4 FIRM from SD", 10, posY + SPACING_Y, COLOR_WHITE);
posY = drawString("Press any other button to load FIRM from CTRNAND", 10, posY, COLOR_RED);
if(waitInput() == BUTTON_SELECT)
{
const char *firm104Path = "a9lh/firm104.bin";
u32 firm104Size = ISN3DS ? 0xF2000 : 0xEA000;
unmountCtrNand();
if(!mountFs(true)) shutdown(1, "Error: failed to mount the SD card");
if(fileRead((void *)FIRM0_OFFSET, firm104Path, firm104Size) != firm104Size)
shutdown(1, "Error: firm104.bin doesn't exist or has a wrong size");
if(!verifyHash((void *)FIRM0_OFFSET, firm104Size, ISN3DS ? firm104N3DSHash : firm104O3DSHash))
shutdown(1, "Error: firm104.bin is invalid or corrupted");
firmSize = firm104Size;
break;
}
case 2: case 2:
shutdown(1, "Error: a FIRM equal or newer than 11.0\nhas been detected"); if(result == 2) posY = drawString("A FIRM newer than 11.1 has been detected!", 10, posY + SPACING_Y, COLOR_RED);
posY = drawString("You are about to uninstall A9LH!", 10, posY + SPACING_Y, COLOR_RED);
posY = drawString("To reinstall you'll need an hardmod or a DSi dg!", 10, posY, COLOR_RED);
break; break;
case 3: case 3:
shutdown(1, "Error: the CTRNAND FIRM is too large"); shutdown(1, "Error: the CTRNAND FIRM is too large");
@ -309,9 +341,20 @@ static inline void uninstaller(void)
break; break;
} }
if(firmSize != 0 || !result)
{
posY = drawString("You are about to uninstall A9LH!", 10, posY + SPACING_Y, COLOR_RED);
posY = drawString("To reinstall you'll need 9.2 or lower!", 10, posY, COLOR_RED);
}
inputSequence();
//Decrypt it and get its size //Decrypt it and get its size
u32 firmSize = decryptExeFs((Cxi *)FIRM0_OFFSET); if(!firmSize)
{
firmSize = decryptExeFs((Cxi *)FIRM0_OFFSET);
if(firmSize == 0) shutdown(1, "Error: couldn't decrypt the CTRNAND FIRM"); if(firmSize == 0) shutdown(1, "Error: couldn't decrypt the CTRNAND FIRM");
}
//writeFirm encrypts in-place, so we need two copies //writeFirm encrypts in-place, so we need two copies
memcpy((void *)FIRM1_OFFSET, (void *)FIRM0_OFFSET, firmSize); memcpy((void *)FIRM1_OFFSET, (void *)FIRM0_OFFSET, firmSize);