diff --git a/README.md b/README.md index a616505..ae1d7e2 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,13 @@ Incognito_RCM = Incognito_RCM is a bare metal Nintendo Switch payload that derives encryption keys for de- and encrypting PRODINFO partition (sysnand and emummc) and wiping personal information from your Nintendo Switch as to go online while worrying slightly less about a ban. +It has a builtin backup and restore functionality. It is heavily based on [Lockpick_RCM](https://github.com/shchmue/Lockpick_RCM) and takes inspiration from [incognito](https://github.com/blawar/incognito). Massive Thanks to CTCaer, shchmue and blawar! -This project is in early stage, so have a nand backup!! There is not much of error handling going on. +This project is in early stage, so have a nand backup!! Usage = @@ -15,7 +16,16 @@ Usage * Choose either Incognito (sysNAND) or Incognito (emuMMC) to wipe personal information * If you ever want to revert, choose restore menu points -Keep in mind that backups will be overwritten, so don't backup after applying Incognito! +Screenshots += + +Main | Incognito +:-------------------------:|:-------------------------: +![](/res/main.png) | ![](/res/incognito.png) + +Backup | Restore +:-------------------------:|:-------------------------: +![](/res/backup.png) | ![](/res/restore.png) Building = diff --git a/res/backup.png b/res/backup.png new file mode 100644 index 0000000..ff66ff6 Binary files /dev/null and b/res/backup.png differ diff --git a/res/incognito.png b/res/incognito.png new file mode 100644 index 0000000..9c3cbfe Binary files /dev/null and b/res/incognito.png differ diff --git a/res/main.png b/res/main.png new file mode 100644 index 0000000..e406d66 Binary files /dev/null and b/res/main.png differ diff --git a/res/restore.png b/res/restore.png new file mode 100644 index 0000000..7cc574e Binary files /dev/null and b/res/restore.png differ diff --git a/source/gfx/gfx.c b/source/gfx/gfx.c index 71e2179..a8d7598 100644 --- a/source/gfx/gfx.c +++ b/source/gfx/gfx.c @@ -600,7 +600,7 @@ u8 *gfx_bmp_screenshot(u32 *size) bih.planes = 1; bih.bit_count = 24; bih.compression = 0; - bih.image_size = file_size; + bih.image_size = 0; bih.ppm_x = ppm; bih.ppm_y = ppm; bih.clr_used = 0; diff --git a/source/keys/keys.c b/source/keys/keys.c index 0ef0a52..1957b70 100644 --- a/source/keys/keys.c +++ b/source/keys/keys.c @@ -273,7 +273,17 @@ bool dump_keys() se_aes_key_set(8, bis_key[0] + 0x00, 0x10); se_aes_key_set(9, bis_key[0] + 0x10, 0x10); - gfx_printf("%kGot keys!\n", COLOR_GREEN); + gfx_printf("%kGot keys!\n%kValidate...", COLOR_GREEN,COLOR_YELLOW); + const char magic[4] = "CAL0"; + char buffer[4]; + readData((u8 *)buffer, 0, 4, NULL); + if(memcmp(magic, buffer, 4) == 0){ + gfx_printf("%kOK!\n", COLOR_GREEN); + } else { + gfx_printf("%kError!\n", COLOR_RED); + return false; + } + char serial[15]; readData((u8 *)serial, 0x250, 15, NULL); @@ -294,7 +304,7 @@ bool erase(u32 offset, u32 length) bool writeSerial() { const char *junkSerial; - if (!emu_cfg.enabled || h_cfg.emummc_force_disable) + if (isSysNAND()) { junkSerial = "XAW00000000000"; } @@ -311,7 +321,7 @@ bool incognito() gfx_printf("%kChecking if backup exists...\n", COLOR_YELLOW); if (!checkBackupExists()) { - gfx_printf("%kI'm sorry Dave, I'm afraid I can't do that...\n%kWill make a backup first...\n", COLOR_RED, COLOR_YELLOW); + gfx_printf("%kI'm sorry Dave, I'm afraid I can't do that..\n%kWill make a backup first...\n", COLOR_RED, COLOR_YELLOW); if (!backupProdinfo()) return false; } @@ -357,7 +367,7 @@ bool incognito() return false; - gfx_printf("\n%kIncognito done!\n\n", COLOR_GREEN); + gfx_printf("\n%kIncognito done!\n", COLOR_GREEN); return true; } @@ -396,7 +406,6 @@ static inline u32 _read_le_u32(const void *buffer, u32 offset) bool readData(u8 *buffer, u32 offset, u32 length, void (*progress_callback)(u32, u32)) { - if (progress_callback != NULL) { (*progress_callback)(0, length); @@ -583,26 +592,22 @@ out: return result; } -void test() +void screenshot(const char *filename) { - // u32 size = 262144; - // gfx_printf("%kTest reading %d bytes\n", COLOR_ORANGE, size); - // u8 *buffer = (u8 *)malloc(NX_EMMC_BLOCKSIZE); - // u8* bigBuffer = (u8 *)malloc(size); - // u32 offset = 0; - // readData(bigBuffer, 0, size, ENCRYPTED); - // while(size > NX_EMMC_BLOCKSIZE){ - // readData(buffer, offset, NX_EMMC_BLOCKSIZE, ENCRYPTED); - // if(memcmp(buffer, bigBuffer + offset, NX_EMMC_BLOCKSIZE) != 0){ - // gfx_printf("arry mismatch on offset %d", offset); + sd_mount(); - // } - // size -= NX_EMMC_BLOCKSIZE; - // offset += NX_EMMC_BLOCKSIZE; - // } - // free(buffer); - // free(bigBuffer); - // gfx_printf("%Reading Done!\n", COLOR_ORANGE, size); + FIL fp; + if (f_open(&fp, filename, FA_CREATE_ALWAYS | FA_WRITE) != FR_OK) + { + gfx_printf("\n%kCannot write image!\n", COLOR_RED); + return; + } + u32 size; + u8 *buffer = gfx_bmp_screenshot(&size); + + f_write(&fp, buffer, size, NULL); + f_close(&fp); + free(buffer); } bool verifyHash(u32 hashOffset, u32 offset, u32 sz) @@ -670,7 +675,6 @@ bool verifyClientCertHash() bool verifyProdinfo() { - gfx_printf("%kVerifying client cert hash and CAL0 hash...\n", COLOR_YELLOW); if (verifyClientCertHash() && verifyCal0Hash()) @@ -712,38 +716,43 @@ void print_progress(u32 count, u32 max) gfx_con.y = cur_y; } -bool getLastBackup() +// bool getLastBackup() +// { +// DIR dir; +// //char* path = "sd:/incognito"; +// char path[255]; +// strcpy(path, "sd:/incognito"); +// FILINFO fno; +// FRESULT res; + +// res = f_opendir(&dir, path); /* Open the directory */ +// if (res == FR_OK) +// { +// for (;;) +// { +// res = f_readdir(&dir, &fno); /* Read a directory item */ +// if (res != FR_OK || fno.fname[0] == 0) +// break; /* Break on error or end of dir */ +// if ((fno.fattrib & AM_DIR) == 0) +// { /* It is not a directory */ +// gfx_printf("%s/%s\n", path, fno.fname); +// } +// } +// f_closedir(&dir); +// } + +// return res; +// } + +bool isSysNAND() { - DIR dir; - //char* path = "sd:/incognito"; - char path[255]; - strcpy(path, "sd:/incognito"); - FILINFO fno; - FRESULT res; - - res = f_opendir(&dir, path); /* Open the directory */ - if (res == FR_OK) - { - for (;;) - { - res = f_readdir(&dir, &fno); /* Read a directory item */ - if (res != FR_OK || fno.fname[0] == 0) - break; /* Break on error or end of dir */ - if ((fno.fattrib & AM_DIR) == 0) - { /* It is not a directory */ - gfx_printf("%s/%s\n", path, fno.fname); - } - } - f_closedir(&dir); - } - - return res; + return (!emu_cfg.enabled || h_cfg.emummc_force_disable); } bool checkBackupExists() { char *name; - if (!emu_cfg.enabled || h_cfg.emummc_force_disable) + if (isSysNAND()) { name = BACKUP_NAME_SYSNAND; } @@ -758,7 +767,7 @@ bool backupProdinfo() { bool result = false; char *name; - if (!emu_cfg.enabled || h_cfg.emummc_force_disable) + if (isSysNAND()) { name = BACKUP_NAME_SYSNAND; } @@ -779,7 +788,7 @@ bool backupProdinfo() filenameSuffix++; } while (f_stat(newName, NULL) == FR_OK); f_rename(name, newName); - gfx_printf("%kOld backup renamed to %s\n", COLOR_YELLOW, newName); + gfx_printf("%kOld backup renamed to:\n%s\n", COLOR_YELLOW, newName); } FIL fp; @@ -806,7 +815,7 @@ bool backupProdinfo() f_sync(&fp); result = true; - gfx_printf("\n%kBackup to %s done!\n\n", COLOR_GREEN, name); + gfx_printf("\n%kBackup to %s done!\n", COLOR_GREEN, name); out: f_close(&fp); @@ -821,7 +830,7 @@ bool restoreProdinfo() sd_mount(); char *name; - if (!emu_cfg.enabled || h_cfg.emummc_force_disable) + if (isSysNAND()) { name = BACKUP_NAME_SYSNAND; } @@ -829,7 +838,7 @@ bool restoreProdinfo() { name = BACKUP_NAME_EMUNAND; } - + gfx_printf("%kRestoring from %s...\n", COLOR_YELLOW, name); FIL fp; diff --git a/source/keys/keys.h b/source/keys/keys.h index d1bbbb0..ce9bb9e 100644 --- a/source/keys/keys.h +++ b/source/keys/keys.h @@ -19,10 +19,12 @@ #include "../utils/types.h" + //testing -void test(); +void screenshot(const char* suffix); //testing +bool isSysNAND(); bool dump_keys(); bool incognito(); void cleanUp();