mirror of
https://github.com/Scandal-UK/Incognito_RCM.git
synced 2024-11-22 20:06:42 +00:00
update readme and add screenshots
This commit is contained in:
parent
c62341b117
commit
8afd9a8693
8 changed files with 80 additions and 59 deletions
14
README.md
14
README.md
|
@ -1,12 +1,13 @@
|
||||||
Incognito_RCM
|
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.
|
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).
|
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!
|
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
|
Usage
|
||||||
=
|
=
|
||||||
|
@ -15,7 +16,16 @@ Usage
|
||||||
* Choose either Incognito (sysNAND) or Incognito (emuMMC) to wipe personal information
|
* Choose either Incognito (sysNAND) or Incognito (emuMMC) to wipe personal information
|
||||||
* If you ever want to revert, choose restore menu points
|
* 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
|
Building
|
||||||
=
|
=
|
||||||
|
|
BIN
res/backup.png
Normal file
BIN
res/backup.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 52 KiB |
BIN
res/incognito.png
Normal file
BIN
res/incognito.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 80 KiB |
BIN
res/main.png
Normal file
BIN
res/main.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 41 KiB |
BIN
res/restore.png
Normal file
BIN
res/restore.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 56 KiB |
|
@ -600,7 +600,7 @@ u8 *gfx_bmp_screenshot(u32 *size)
|
||||||
bih.planes = 1;
|
bih.planes = 1;
|
||||||
bih.bit_count = 24;
|
bih.bit_count = 24;
|
||||||
bih.compression = 0;
|
bih.compression = 0;
|
||||||
bih.image_size = file_size;
|
bih.image_size = 0;
|
||||||
bih.ppm_x = ppm;
|
bih.ppm_x = ppm;
|
||||||
bih.ppm_y = ppm;
|
bih.ppm_y = ppm;
|
||||||
bih.clr_used = 0;
|
bih.clr_used = 0;
|
||||||
|
|
|
@ -273,7 +273,17 @@ bool dump_keys()
|
||||||
se_aes_key_set(8, bis_key[0] + 0x00, 0x10);
|
se_aes_key_set(8, bis_key[0] + 0x00, 0x10);
|
||||||
se_aes_key_set(9, bis_key[0] + 0x10, 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];
|
char serial[15];
|
||||||
readData((u8 *)serial, 0x250, 15, NULL);
|
readData((u8 *)serial, 0x250, 15, NULL);
|
||||||
|
|
||||||
|
@ -294,7 +304,7 @@ bool erase(u32 offset, u32 length)
|
||||||
bool writeSerial()
|
bool writeSerial()
|
||||||
{
|
{
|
||||||
const char *junkSerial;
|
const char *junkSerial;
|
||||||
if (!emu_cfg.enabled || h_cfg.emummc_force_disable)
|
if (isSysNAND())
|
||||||
{
|
{
|
||||||
junkSerial = "XAW00000000000";
|
junkSerial = "XAW00000000000";
|
||||||
}
|
}
|
||||||
|
@ -311,7 +321,7 @@ bool incognito()
|
||||||
gfx_printf("%kChecking if backup exists...\n", COLOR_YELLOW);
|
gfx_printf("%kChecking if backup exists...\n", COLOR_YELLOW);
|
||||||
if (!checkBackupExists())
|
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())
|
if (!backupProdinfo())
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -357,7 +367,7 @@ bool incognito()
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
||||||
gfx_printf("\n%kIncognito done!\n\n", COLOR_GREEN);
|
gfx_printf("\n%kIncognito done!\n", COLOR_GREEN);
|
||||||
return true;
|
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))
|
bool readData(u8 *buffer, u32 offset, u32 length, void (*progress_callback)(u32, u32))
|
||||||
{
|
{
|
||||||
|
|
||||||
if (progress_callback != NULL)
|
if (progress_callback != NULL)
|
||||||
{
|
{
|
||||||
(*progress_callback)(0, length);
|
(*progress_callback)(0, length);
|
||||||
|
@ -583,26 +592,22 @@ out:
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void test()
|
void screenshot(const char *filename)
|
||||||
{
|
{
|
||||||
// u32 size = 262144;
|
sd_mount();
|
||||||
// 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);
|
|
||||||
|
|
||||||
// }
|
FIL fp;
|
||||||
// size -= NX_EMMC_BLOCKSIZE;
|
if (f_open(&fp, filename, FA_CREATE_ALWAYS | FA_WRITE) != FR_OK)
|
||||||
// offset += NX_EMMC_BLOCKSIZE;
|
{
|
||||||
// }
|
gfx_printf("\n%kCannot write image!\n", COLOR_RED);
|
||||||
// free(buffer);
|
return;
|
||||||
// free(bigBuffer);
|
}
|
||||||
// gfx_printf("%Reading Done!\n", COLOR_ORANGE, size);
|
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)
|
bool verifyHash(u32 hashOffset, u32 offset, u32 sz)
|
||||||
|
@ -670,7 +675,6 @@ bool verifyClientCertHash()
|
||||||
|
|
||||||
bool verifyProdinfo()
|
bool verifyProdinfo()
|
||||||
{
|
{
|
||||||
|
|
||||||
gfx_printf("%kVerifying client cert hash and CAL0 hash...\n", COLOR_YELLOW);
|
gfx_printf("%kVerifying client cert hash and CAL0 hash...\n", COLOR_YELLOW);
|
||||||
|
|
||||||
if (verifyClientCertHash() && verifyCal0Hash())
|
if (verifyClientCertHash() && verifyCal0Hash())
|
||||||
|
@ -712,38 +716,43 @@ void print_progress(u32 count, u32 max)
|
||||||
gfx_con.y = cur_y;
|
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;
|
return (!emu_cfg.enabled || h_cfg.emummc_force_disable);
|
||||||
//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 checkBackupExists()
|
bool checkBackupExists()
|
||||||
{
|
{
|
||||||
char *name;
|
char *name;
|
||||||
if (!emu_cfg.enabled || h_cfg.emummc_force_disable)
|
if (isSysNAND())
|
||||||
{
|
{
|
||||||
name = BACKUP_NAME_SYSNAND;
|
name = BACKUP_NAME_SYSNAND;
|
||||||
}
|
}
|
||||||
|
@ -758,7 +767,7 @@ bool backupProdinfo()
|
||||||
{
|
{
|
||||||
bool result = false;
|
bool result = false;
|
||||||
char *name;
|
char *name;
|
||||||
if (!emu_cfg.enabled || h_cfg.emummc_force_disable)
|
if (isSysNAND())
|
||||||
{
|
{
|
||||||
name = BACKUP_NAME_SYSNAND;
|
name = BACKUP_NAME_SYSNAND;
|
||||||
}
|
}
|
||||||
|
@ -779,7 +788,7 @@ bool backupProdinfo()
|
||||||
filenameSuffix++;
|
filenameSuffix++;
|
||||||
} while (f_stat(newName, NULL) == FR_OK);
|
} while (f_stat(newName, NULL) == FR_OK);
|
||||||
f_rename(name, newName);
|
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;
|
FIL fp;
|
||||||
|
@ -806,7 +815,7 @@ bool backupProdinfo()
|
||||||
f_sync(&fp);
|
f_sync(&fp);
|
||||||
|
|
||||||
result = true;
|
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:
|
out:
|
||||||
f_close(&fp);
|
f_close(&fp);
|
||||||
|
@ -821,7 +830,7 @@ bool restoreProdinfo()
|
||||||
sd_mount();
|
sd_mount();
|
||||||
|
|
||||||
char *name;
|
char *name;
|
||||||
if (!emu_cfg.enabled || h_cfg.emummc_force_disable)
|
if (isSysNAND())
|
||||||
{
|
{
|
||||||
name = BACKUP_NAME_SYSNAND;
|
name = BACKUP_NAME_SYSNAND;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,10 +19,12 @@
|
||||||
|
|
||||||
#include "../utils/types.h"
|
#include "../utils/types.h"
|
||||||
|
|
||||||
|
|
||||||
//testing
|
//testing
|
||||||
void test();
|
void screenshot(const char* suffix);
|
||||||
//testing
|
//testing
|
||||||
|
|
||||||
|
bool isSysNAND();
|
||||||
bool dump_keys();
|
bool dump_keys();
|
||||||
bool incognito();
|
bool incognito();
|
||||||
void cleanUp();
|
void cleanUp();
|
||||||
|
|
Loading…
Reference in a new issue