mirror of
https://github.com/rvtr/SafeNANDManager.git
synced 2026-01-26 13:43:04 -05:00
Add NAND restore option
Sectors are compared before writing one to NAND
This commit is contained in:
parent
5871c63a7d
commit
c24113f20d
6
.gitignore
vendored
Normal file
6
.gitignore
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
*/build
|
||||
*.nds
|
||||
*.elf
|
||||
data/*
|
||||
.vscode
|
||||
*.DS_Store
|
||||
6
Makefile
6
Makefile
@ -13,9 +13,9 @@ export TOPDIR := $(CURDIR)
|
||||
NITRO_FILES :=
|
||||
|
||||
# These set the information text in the nds file
|
||||
GAME_TITLE := dumpTool
|
||||
GAME_SUBTITLE1 := zoogie
|
||||
GAME_SUBTITLE2 := Dump DSi NAND w/ nocash footer
|
||||
GAME_TITLE := SafeNANDManager
|
||||
GAME_SUBTITLE1 := Dump or Restore DSi NAND
|
||||
GAME_SUBTITLE2 := zoogie & Rocket Robz
|
||||
|
||||
include $(DEVKITARM)/ds_rules
|
||||
|
||||
|
||||
@ -71,7 +71,7 @@ int dumpNAND(nocash_footer_t *footer){
|
||||
u32 rwTotal=nand_GetSize()*0x200; //240MB or 245.5MB
|
||||
printf("NAND size: %.2fMB\n", (float)rwTotal/(float)0x100000);
|
||||
|
||||
if(rwTotal != 0xF000000 && rwTotal != 0xF580000) death("Unknown NAND size. Please\ncontact zoogie at:\nhttps://github.com/zoogie/dumpTool/issues"); //there's no documented nand chip with sizes different from these two.
|
||||
if(rwTotal != 0xF000000 && rwTotal != 0xF580000) death("Unknown NAND size."); //there's no documented nand chip with sizes different from these two.
|
||||
|
||||
while(getBatteryLevel() < 0x4){
|
||||
iprintf("Battery low: plug in to proceed\r"); //user can charge to 2 bars or more OR just plug in the charger. charging state adds +0x80 to battery level. low 4 bits are the battery charge level.
|
||||
@ -143,6 +143,63 @@ int dumpNAND(nocash_footer_t *footer){
|
||||
return fail;
|
||||
}
|
||||
|
||||
int restoreNAND(nocash_footer_t *footer){
|
||||
|
||||
u32 rwTotal=nand_GetSize()*0x200; //240MB or 245.5MB
|
||||
printf("NAND size: %.2fMB\n", (float)rwTotal/(float)0x100000);
|
||||
|
||||
if(rwTotal != 0xF000000 && rwTotal != 0xF580000) death("Unknown NAND size."); //there's no documented nand chip with sizes different from these two.
|
||||
|
||||
while(getBatteryLevel() < 0x4){
|
||||
iprintf("Battery low: plug in to proceed\r"); //user can charge to 2 bars or more OR just plug in the charger. charging state adds +0x80 to battery level. low 4 bits are the battery charge level.
|
||||
wait(60); //don't spam getbatterylevel too much
|
||||
}
|
||||
|
||||
char *filename="nand.bin";
|
||||
int fail=0;
|
||||
|
||||
FILE *f = fopen("nand.bin", "rb");
|
||||
if(!f) death("Could not open nand file");
|
||||
|
||||
iprintf("Restoring... \n");
|
||||
iprintf("Do not turn off the power.\n");
|
||||
iprintf("Progress: 0%% \r");
|
||||
|
||||
for(int i=0;i<rwTotal;i+=0x200){ //read nand dump from sd, compare sectors, and write to nand
|
||||
if(nand_ReadSectors(i / 0x200, 1, workbuffer) == false){
|
||||
iprintf("Nand read error\nOffset: %08X\nAborting...", (int)i);
|
||||
fclose(f);
|
||||
fail=1;
|
||||
break;
|
||||
}
|
||||
if(fread(workbuffer+0x200, 1, 0x200, f) < 0x200){
|
||||
iprintf("Sdmc read error\nOffset: %08X\nAborting...", (int)i);
|
||||
fclose(f);
|
||||
fail=1;
|
||||
break;
|
||||
}
|
||||
if(memcmp(workbuffer, workbuffer+0x200, 0x200) != 0){
|
||||
if(nand_WriteSectors(i / 0x200, 1, workbuffer+0x200) == false){
|
||||
iprintf("Nand write error\nOffset: %08X\nAborting...", (int)i);
|
||||
fclose(f);
|
||||
fail=1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
iprintf("Progress: %lu%% \r", (i+0x200)/(rwTotal/100));
|
||||
}
|
||||
|
||||
if(!fail)
|
||||
{
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
iprintf("\nDone.\nPress START to exit");
|
||||
done=1;
|
||||
|
||||
return fail;
|
||||
}
|
||||
|
||||
int verifyNocashFooter(nocash_footer_t *footer){
|
||||
u8 out[0x200]={0};
|
||||
u8 sha1[20]={0};
|
||||
@ -176,7 +233,8 @@ int verifyNocashFooter(nocash_footer_t *footer){
|
||||
|
||||
int main(void) {
|
||||
consoleDemoInit();
|
||||
iprintf("dumpTool v1.0 - zoogie\n");
|
||||
iprintf("SafeNANDManager v1.0\n");
|
||||
iprintf("by Rocket Robz\n");
|
||||
|
||||
workbuffer=(u8*)malloc(CHUNKSIZE);
|
||||
if(!workbuffer) death("Could not allocate workbuffer");
|
||||
@ -202,19 +260,26 @@ int main(void) {
|
||||
mkdir(dirname, 0777);
|
||||
chdir(dirname);
|
||||
|
||||
bool nandFound = (access("nand.bin", F_OK) == 0);
|
||||
|
||||
iprintf("Verifying nocash_footer: ");
|
||||
iprintf("%s\n", verifyNocashFooter(&nocash_footer) ? "GOOD":"BAD\nThis dump can't be decrypted\nwith this footer!");
|
||||
iprintf("\n");
|
||||
if (nandFound) {
|
||||
iprintf("Press Y to begin NAND restore\n");
|
||||
}
|
||||
iprintf("Press A to begin NAND dump\nPress START to exit\n\n");
|
||||
|
||||
while(1) {
|
||||
|
||||
swiWaitForVBlank();
|
||||
scanKeys();
|
||||
if (keysDown() & KEY_A && !done) dumpNAND(&nocash_footer);
|
||||
if ((keysDown() & KEY_Y) && nandFound && !done) restoreNAND(&nocash_footer);
|
||||
if ((keysDown() & KEY_A) && !done) dumpNAND(&nocash_footer);
|
||||
else if (keysDown() & KEY_START) break;
|
||||
}
|
||||
|
||||
free(workbuffer);
|
||||
|
||||
return 0;
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user