diff --git a/source/filesys/fsperm.c b/source/filesys/fsperm.c index aea904d..45379a8 100644 --- a/source/filesys/fsperm.c +++ b/source/filesys/fsperm.c @@ -8,7 +8,8 @@ #define PATH_SYS_LVL1 "S:/twln.bin", "S:/twlp.bin" #define PATH_SYS_LVL2 "1:/rw/sys/LocalFriendCodeSeed_B", "1:/rw/sys/LocalFriendCodeSeed_A", \ "1:/rw/sys/SecureInfo_A", "1:/rw/sys/SecureInfo_B", \ - "1:/private/movable.sed", "S:/ctrnand_fat.bin", "S:/ctrnand_full.bin" + "1:/private/movable.sed", "1:/ro/sys/HWCAL0.dat", "1:/ro/sys/HWCAL1.dat", \ + "S:/ctrnand_fat.bin", "S:/ctrnand_full.bin" #define PATH_SYS_LVL3 "S:/firm0.bin", "S:/firm1.bin", "S:/nand.bin", "S:/nand_minsize.bin", "S:/nand_hdr.bin", \ "S:/sector0x96.bin", "S:/twlmbr.bin" #define PATH_EMU_LVL1 "E:/ctrnand_fat.bin", "E:/ctrnand_full.bin", "E:/nand.bin", "E:/nand_minsize.bin", "E:/nand_hdr.bin" diff --git a/source/nand/essentials.h b/source/nand/essentials.h index 4edc547..16573f3 100644 --- a/source/nand/essentials.h +++ b/source/nand/essentials.h @@ -10,6 +10,9 @@ // magic number for essential backup #define ESSENTIAL_MAGIC 'n', 'a', 'n', 'd', '_', 'h', 'd', 'r', 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00 +// size of /ro/sys/HWCAL0.dat and /ro/sys/HWCAL1.dat +#define SIZE_HWCAL 0x9D0 + // /rw/sys/LocalFriendCodeSeed_B (/_A) file // see: http://3dbrew.org/wiki/Nandrw/sys/LocalFriendCodeSeed_B typedef struct { @@ -44,13 +47,17 @@ typedef struct { ExeFsHeader header; u8 nand_hdr[0x200]; SecureInfo secinfo; - u8 padding_secinfo[0x200 - sizeof(SecureInfo)]; + u8 padding_secinfo[0x200 - (sizeof(SecureInfo)%0x200)]; MovableSed movable; - u8 padding_movable[0x200 - sizeof(MovableSed)]; + u8 padding_movable[0x200 - (sizeof(MovableSed)%0x200)]; LocalFriendCodeSeed frndseed; - u8 padding_frndseed[0x200 - sizeof(LocalFriendCodeSeed)]; + u8 padding_frndseed[0x200 - (sizeof(LocalFriendCodeSeed)%0x200)]; u8 nand_cid[0x10]; u8 padding_nand_cid[0x200 - 0x10]; u8 otp[0x100]; u8 padding_otp[0x200 - 0x100]; + u8 hwcal0[SIZE_HWCAL]; + u8 padding_hwcal0[0x200 - (SIZE_HWCAL%0x200)]; + u8 hwcal1[SIZE_HWCAL]; + u8 padding_hwcal1[0x200 - (SIZE_HWCAL%0x200)]; } __attribute__((packed)) EssentialBackup; diff --git a/source/nand/nandutil.c b/source/nand/nandutil.c index c2525b5..47e99ef 100644 --- a/source/nand/nandutil.c +++ b/source/nand/nandutil.c @@ -27,12 +27,14 @@ u32 ReadNandFile(FIL* file, void* buffer, u32 sector, u32 count, u32 keyslot) { u32 BuildEssentialBackup(const char* path, EssentialBackup* essential) { // prepare essential backup struct ExeFsFileHeader filelist[] = { - { "nand_hdr", 0x000, 0x200 }, - { "secinfo" , 0x200, 0x111 }, - { "movable" , 0x400, 0x140 }, - { "frndseed", 0x600, 0x110 }, - { "nand_cid", 0x800, 0x010 }, - { "otp" , 0xA00, 0x100 } + { "nand_hdr", 0x0000, 0x200 }, + { "secinfo" , 0x0200, 0x111 }, + { "movable" , 0x0400, 0x140 }, + { "frndseed", 0x0600, 0x110 }, + { "nand_cid", 0x0800, 0x010 }, + { "otp" , 0x0A00, 0x100 }, + { "hwcal0" , 0x0C00, 0x9D0 }, + { "hwcal1" , 0x1600, 0x9D0 } }; memset(essential, 0, sizeof(EssentialBackup)); memcpy(essential, filelist, sizeof(filelist)); @@ -59,16 +61,22 @@ u32 BuildEssentialBackup(const char* path, EssentialBackup* essential) { return 1; } + // HWCAL0.dat / HWCAL1.dat + if ((fvx_qread("7:/ro/sys/HWCAL0.dat", &(essential->hwcal0), 0, 0x1000, (UINT*) &(files[6].size)) != FR_OK) || + (fvx_qread("7:/ro/sys/HWCAL1.dat", &(essential->hwcal1), 0, 0x1000, (UINT*) &(files[7].size)) != FR_OK)) { + memset(&(filelist[6]), 0, 2 * sizeof(ExeFsFileHeader)); + } + // mount original file InitImgFS(path_bak); - + // fill nand cid / otp hash if (GetNandCid(&(essential->nand_cid)) != 0) return 1; - if (!IS_UNLOCKED) memset(&(filelist[5]), 0, sizeof(ExeFsFileHeader)); + if (!IS_UNLOCKED) memset(&(filelist[5]), 0, 3 * sizeof(ExeFsFileHeader)); else memcpy(&(essential->otp), (u8*) 0x10012000, 0x100); // calculate hashes - for (u32 i = 0; i < (IS_UNLOCKED ? 6 : 5); i++) + for (u32 i = 0; i < 8 && *(filelist[i].name); i++) sha_quick(essential->header.hashes[9-i], ((u8*) essential) + files[i].offset + sizeof(ExeFsHeader), files[i].size, SHA256_MODE);