diff --git a/source/filesys/vff.c b/source/filesys/vff.c index 096c958..4c8c7fc 100644 --- a/source/filesys/vff.c +++ b/source/filesys/vff.c @@ -81,11 +81,13 @@ FRESULT fvx_stat (const TCHAR* path, FILINFO* fno) { if (GetVirtualSource(path)) { VirtualFile vfile; if (!GetVirtualFile(&vfile, path)) return FR_NO_PATH; - fno->fsize = vfile.size; - fno->fdate = fno->ftime = 0; - fno->fattrib = (vfile.flags & VFLAG_DIR) ? (AM_DIR|AM_VRT) : AM_VRT; - // could be better... - if (_USE_LFN != 0) GetVirtualFilename(fno->fname, &vfile, _MAX_LFN + 1); + if (fno) { + fno->fsize = vfile.size; + fno->fdate = fno->ftime = 0; + fno->fattrib = (vfile.flags & VFLAG_DIR) ? (AM_DIR|AM_VRT) : AM_VRT; + // could be better... + if (_USE_LFN != 0) GetVirtualFilename(fno->fname, &vfile, _MAX_LFN + 1); + } return FR_OK; } else return fa_stat( path, fno ); } diff --git a/source/godmode.c b/source/godmode.c index c651d95..e0db1ee 100644 --- a/source/godmode.c +++ b/source/godmode.c @@ -1382,6 +1382,16 @@ u32 GodMode() { clipboard->n_entries = 0; memset(panedata, 0x00, 0x10000); + // check for embedded essential backup + if (IS_SIGHAX && !PathExist("S:/essential.exefs") && CheckGenuineNandNcsd() && + ShowPrompt(true, "Essential files backup not found.\nCreate one now?")) { + if (EmbedEssentialBackup("S:/nand.bin") == 0) { + u32 flags = BUILD_PATH | SKIP_ALL; + PathCopy(OUTPUT_PATH, "S:/essential.exefs", &flags); + ShowPrompt(false, "Backup embedded in SysNAND\nand written to " OUTPUT_PATH "."); + } + } + while(timer_sec( timer ) < 1); // show splash for at least 1 sec ClearScreenF(true, true, COLOR_STD_BG); // clear splash diff --git a/source/nand/nand.c b/source/nand/nand.c index 6b552b7..658c9b6 100644 --- a/source/nand/nand.c +++ b/source/nand/nand.c @@ -214,6 +214,25 @@ bool CheckSector0x96Crypto(void) return (sha_cmp(KEY95_SHA256, buffer, 16, SHA256_MODE) == 0); } +bool CheckGenuineNandNcsd(void) +{ + u8 gen_o3ds_hash[0x20] = { + 0xCD, 0xB8, 0x2B, 0xF3, 0xE0, 0xC7, 0xA3, 0xC7, 0x58, 0xDF, 0xDC, 0x4E, 0x27, 0x63, 0xBE, 0xE8, + 0xBE, 0x2B, 0x1D, 0xF4, 0xBA, 0x97, 0xAF, 0x7F, 0x19, 0x70, 0x99, 0xDB, 0x66, 0xF7, 0x2F, 0xD7 + }; + u8 gen_n3ds_hash[0x20] = { + 0x49, 0xB7, 0x4A, 0xF1, 0xFD, 0xB7, 0xCF, 0x5B, 0x76, 0x8F, 0xA2, 0x94, 0x0D, 0xB2, 0xB3, 0xE2, + 0xA4, 0xBD, 0x25, 0x03, 0x06, 0x03, 0x47, 0x0B, 0x24, 0x5A, 0x86, 0x6A, 0x43, 0x60, 0xBC, 0x84, + }; + + u8 gen_hdr[0x100]; + if ((ReadNandBytes(gen_hdr, 0x100, 0x100, 0xFF, NAND_SYSNAND) != 0) || + (ReadNandBytes(gen_hdr + 0xBE, 0x1BE, 0x42, 0x03, NAND_SYSNAND) != 0)) + return false; + + return (sha_cmp((IS_O3DS) ? gen_o3ds_hash : gen_n3ds_hash, gen_hdr, 0x100, SHA256_MODE) == 0); +} + void CryptNand(void* buffer, u32 sector, u32 count, u32 keyslot) { u32 mode = (keyslot != 0x03) ? AES_CNT_CTRNAND_MODE : AES_CNT_TWLNAND_MODE; // somewhat hacky diff --git a/source/nand/nand.h b/source/nand/nand.h index f6a3c7a..e6289c3 100644 --- a/source/nand/nand.h +++ b/source/nand/nand.h @@ -59,6 +59,7 @@ typedef struct { bool InitNandCrypto(void); bool CheckSlot0x05Crypto(void); bool CheckSector0x96Crypto(void); +bool CheckGenuineNandNcsd(void); void CryptNand(void* buffer, u32 sector, u32 count, u32 keyslot); void CryptSector0x96(void* buffer, bool encrypt);