void DumpNandPartitions(){ int isEmuNand = checkEmuNAND() ? NandSwitch() : 0; if(isEmuNand == -1) return; char* p_name[] = { "twln.bin", "twlp.bin", "agb_save.bin", "firm0.bin", "firm1.bin", "ctrnand.bin" }; unsigned int p_size[] = { 0x08FB5200, 0x020B6600, 0x00030000, 0x00400000, 0x00400000, 0x2F3E3600}; unsigned int p_addr[] = { TWLN, TWLP, AGB_SAVE, FIRM0, FIRM1, CTRNAND }; int sect_row = 0x80; ConsoleInit(); ConsoleAddText(isEmuNand ? "EmuNAND Partitions Decryptor\n \n" : "NAND Partitions Decryptor\n \n"); for(int i = 3; i < 6; i++){ //Cutting out twln, twlp and agb_save. Todo: Properly decrypt them File out; sprintf(myString, isEmuNand ? "nand/emu_%s" : "nand/%s", p_name[i]); FileOpen(&out, myString, 1); sprintf(myString, "Dumping %s ...", p_name[i]); ConsoleAddText(myString); ConsoleShow(); for(int j = 0; j*0x200 < p_size[i]; j += sect_row){ sprintf(myString, "%08X / %08X", j*0x200, p_size[i]); int x, y; ConsoleGetXY(&x, &y); y += CHAR_WIDTH * 4; x += CHAR_WIDTH*2; DrawString(TOP_SCREEN, myString, x, y, ConsoleGetTextColor(), ConsoleGetBackgroundColor()); if(isEmuNand) emunand_readsectors(j, sect_row, BUF1, p_addr[i]); else nand_readsectors(j, sect_row, BUF1, p_addr[i]); FileWrite(&out, BUF1, sect_row*0x200, j*0x200); } FileClose(&out); } ConsoleAddText("\nPress A to exit"); ConsoleShow(); WaitForButton(BUTTON_A); }
//Just patches signatures check, loads in sysnand void DevMode(){ u8* firm = 0x24000000; nand_readsectors(0, 0xF0000/0x200, firm, FIRM0); if(strncmp((char*)firm, "FIRM", 4)) nand_readsectors(0, 0xF0000/0x200, firm, FIRM1); unsigned char sign1[] = {0xC1, 0x17, 0x49, 0x1C, 0x31, 0xD0, 0x68, 0x46, 0x01, 0x78, 0x40, 0x1C, 0x00, 0x29, 0x10, 0xD1}; unsigned char sign2[] = {0xC0, 0x1C, 0x76, 0xE7, 0x20, 0x00, 0x74, 0xE7, 0x22, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F}; unsigned char patch1[] = { 0x00, 0x20, 0x4E, 0xB0, 0x70, 0xBD }; unsigned char patch2[] = { 0x00, 0x20}; for(int i = 0; i < 0xF0000; i++){ if(!memcmp(firm + i, sign1, 16)){ memcpy(firm + i, patch1, 6); } if(!memcmp(firm + i, sign2, 16)){ memcpy(firm + i, patch2, 2); } } memcpy(0x080F0000, GetFilePack("reboot.bin"), 0x8000); _softreset(); }
//Just patches signatures check, loads in sysnand int PastaMode(){ /*PastaMode is ready for n3ds BUT there's an unresolved bug which affects nand reading functions, like nand_readsectors(0, 0xF0000 / 0x200, firm, FIRM0);*/ uint8_t* firm = (void*)FIRM_ADDR; nand_readsectors(0, 0xF0000 / 0x200, firm, FIRM0); if (strncmp((char*)firm, "FIRM", 4)) nand_readsectors(0, 0xF0000 / 0x200, firm, FIRM1); if(getMpInfo() == MPINFO_CTR) { //o3ds patches unsigned char sign1[] = { 0xC1, 0x17, 0x49, 0x1C, 0x31, 0xD0, 0x68, 0x46, 0x01, 0x78, 0x40, 0x1C, 0x00, 0x29, 0x10, 0xD1 }; unsigned char sign2[] = { 0xC0, 0x1C, 0x76, 0xE7, 0x20, 0x00, 0x74, 0xE7, 0x22, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F }; unsigned char patch1[] = { 0x00, 0x20, 0x4E, 0xB0, 0x70, 0xBD }; unsigned char patch2[] = { 0x00, 0x20 }; for (int i = 0; i < 0xF0000; i++){ if (!memcmp(firm + i, sign1, 16)){ memcpy(firm + i, patch1, 6); } if (!memcmp(firm + i, sign2, 16)){ memcpy(firm + i, patch2, 2); } } } else { //new 3ds patches decryptFirmKtrArm9((void *)FIRM_ADDR); uint8_t patch0[] = { 0x00, 0x20, 0x3B, 0xE0 }; uint8_t patch1[] = { 0x00, 0x20, 0x08, 0xE0 }; memcpy((uint32_t*)(FIRM_ADDR + 0xB39D8), patch0, 4); memcpy((uint32_t*)(FIRM_ADDR + 0xB9204), patch1, 4); } return loadExecReboot(); }
//Just patches signatures check, loads in sysnand int DevMode(){ /*DevMode is ready for n3ds BUT there's an unresolved bug which affects nand reading functions, like nand_readsectors(0, 0xF0000 / 0x200, firm, FIRM0);*/ u8* firm = (void*)0x24000000; nand_readsectors(0, 0xF0000 / 0x200, firm, FIRM0); if (strncmp((char*)firm, "FIRM", 4)) nand_readsectors(0, 0xF0000 / 0x200, firm, FIRM1); if(Platform_CheckUnit() == PLATFORM_3DS) { //o3ds patches unsigned char sign1[] = { 0xC1, 0x17, 0x49, 0x1C, 0x31, 0xD0, 0x68, 0x46, 0x01, 0x78, 0x40, 0x1C, 0x00, 0x29, 0x10, 0xD1 }; unsigned char sign2[] = { 0xC0, 0x1C, 0x76, 0xE7, 0x20, 0x00, 0x74, 0xE7, 0x22, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0F }; unsigned char patch1[] = { 0x00, 0x20, 0x4E, 0xB0, 0x70, 0xBD }; unsigned char patch2[] = { 0x00, 0x20 }; for (int i = 0; i < 0xF0000; i++){ if (!memcmp(firm + i, sign1, 16)){ memcpy(firm + i, patch1, 6); } if (!memcmp(firm + i, sign2, 16)){ memcpy(firm + i, patch2, 2); } } } else { //new 3ds patches u8 patch1[] = { 0x6D, 0x20, 0xCE, 0x77 }; u8 patch2[] = { 0x5A, 0xC5, 0x73, 0xC1 }; memcpy((u32*)0x08052FD8, patch1, 4); memcpy((u32*)0x08058804, patch2, 4); } return loadExecReboot(); }
void DumpNandPartitions(){ ConsoleSetTitle(strings[STR_DUMP], strings[STR_NAND_PARTITIONS]); int isEmuNand = SYS_NAND; if(checkEmuNAND() && (isEmuNand = NandSwitch()) == UNK_NAND) return; isEmuNand--; ConsoleInit(); ConsoleSetTitle(strings[STR_DUMP], strings[STR_NAND_PARTITIONS]); print(strings[STR_PROCESSING], isEmuNand ? strings[STR_EMUNAND] : strings[STR_SYSNAND]); wchar_t* p_name[] = { L"twln.bin", L"twlp.bin", L"agb_save.bin", L"firm0.bin", L"firm1.bin", L"ctrnand.bin" }; wchar_t* p_descr[] = { strings[STR_TWLN], strings[STR_TWLP], strings[STR_AGB_SAVE], strings[STR_FIRM0], strings[STR_FIRM1], strings[STR_CTRNAND] }; unsigned int p_size[] = { 0x08FB5200, 0x020B6600, 0x00030000, 0x00400000, 0x00400000, getMpInfo() == MPINFO_KTR ? 0x41D2D200 : 0x2F3E3600 }; unsigned int p_addr[] = { TWLN, TWLP, AGB_SAVE, FIRM0, FIRM1, CTRNAND }; int sect_row = 0x80; wchar_t tmp[_MAX_LFN]; for(int i = 3; i < 6; i++){ //Cutting out twln, twlp and agb_save. Todo: Properly decrypt them File out; swprintf(tmp, _MAX_LFN, L"rxTools/nand/%ls%ls", isEmuNand ? L"emu_" : L"", p_name[i]); FileOpen(&out, tmp, 1); print(strings[STR_DUMPING], p_descr[i], tmp); ConsoleShow(); for(int j = 0; j*0x200 < p_size[i]; j += sect_row){ swprintf(tmp, _MAX_LFN, L"%08X / %08X", j*0x200, p_size[i]); int x, y; ConsoleGetXY(&x, &y); y += FONT_HEIGHT * 3; x += FONT_HWIDTH*2; ConsoleShow(); DrawString(BOT_SCREEN, tmp, x, y, ConsoleGetTextColor(), ConsoleGetBackgroundColor()); if(isEmuNand) emunand_readsectors(j, sect_row, BUF1, p_addr[i]); else nand_readsectors(j, sect_row, BUF1, p_addr[i]); FileWrite(&out, BUF1, sect_row*0x200, j*0x200); } FileClose(&out); } print(strings[STR_PRESS_BUTTON_ACTION], strings[STR_BUTTON_A], strings[STR_CONTINUE]); ConsoleShow(); WaitForButton(BUTTON_A); }
DRESULT disk_read ( BYTE pdrv, /* Physical drive nmuber (0..) */ BYTE *buff, /* Data buffer to store read data */ DWORD sector, /* Sector address (LBA) */ UINT count /* Number of sectors to read (1..128) */ ) { switch(pdrv){ case DRV_SDMC: if (tmio_readsectors(TMIO_DEV_SDMC, sector,count,(uint8_t *)buff)) return RES_PARERR; break; case DRV_NAND: nand_readsectors(sector, count, (uint8_t *)buff, CTRNAND); break; case DRV_EMU: emunand_readsectors(sector, count, (uint8_t *)buff, CTRNAND); break; } return RES_OK; }
void DumpNandPartitions(){ int isEmuNand = SYS_NAND; if(checkEmuNAND() && (isEmuNand = NandSwitch()) == UNK_NAND) return; isEmuNand--; char* p_name[] = { "twln.bin", "twlp.bin", "agb_save.bin", "firm0.bin", "firm1.bin", "ctrnand.bin" }; unsigned int p_size[] = { 0x08FB5200, 0x020B6600, 0x00030000, 0x00400000, 0x00400000, 0x2F3E3600}; unsigned int p_addr[] = { TWLN, TWLP, AGB_SAVE, FIRM0, FIRM1, CTRNAND }; int sect_row = 0x80; ConsoleInit(); ConsoleSetTitle(L"%sNAND Partitions Decryptor", isEmuNand ? "emu" : "sys"); char tmp[256]; wchar_t wtmp[256]; for(int i = 3; i < 6; i++){ //Cutting out twln, twlp and agb_save. Todo: Properly decrypt them File out; sprintf(tmp, "rxTools/nand/%s%s", isEmuNand ? "emu_" : "", p_name[i]); FileOpen(&out, tmp, 1); print(L"Dumping %s ...\n", p_name[i]); ConsoleShow(); for(int j = 0; j*0x200 < p_size[i]; j += sect_row){ swprintf(wtmp, sizeof(wtmp)/sizeof(wtmp[0]), L"%08X / %08X", j*0x200, p_size[i]); int x, y; ConsoleGetXY(&x, &y); y += FONT_HEIGHT * 3; x += FONT_HWIDTH*2; DrawString(BOT_SCREEN, wtmp, x, y, ConsoleGetTextColor(), ConsoleGetBackgroundColor()); if(isEmuNand) emunand_readsectors(j, sect_row, BUF1, p_addr[i]); else nand_readsectors(j, sect_row, BUF1, p_addr[i]); FileWrite(&out, BUF1, sect_row*0x200, j*0x200); } FileClose(&out); } print(L"\nPress Ⓐ to exit\n"); ConsoleShow(); WaitForButton(BUTTON_A); }