diff --git a/README.md b/README.md index f4b2fe8..f569a7f 100644 --- a/README.md +++ b/README.md @@ -16,4 +16,11 @@ Why do these matter? You can create a new working NAND from scratch! No backups - I am including my own hostile and outdated fork of libfat. This is to block `nand_Startup()` during `fatMount()`. Without this having a NAND re-mount would run `nand_Startup()` more than once and break every NAND R/W function until reboot... - I do not use the release NandFirm/stage2/bootloader (v2435-8325). Instead I use newer NandFirms as listed below. These NandFirms are able to run unlaunch, however they will stop the installer from working ("unknown bootcode version"). Unlaunch installs carry a brick risk by sometimes erasing the Launcher TMD, so this will somewhat forcefully encourage users to move to a [safer installer](https://github.com/edo9300/unlaunch-installer). Normally I'm against intentionally breaking things but this will prevent future bricks. - v2265-9336 (prod) - - v2725-9336 (dev) \ No newline at end of file + - v2725-9336 (dev) +- My HWInfo Secure recovery works by searching specific locations for HWInfo. As far as I can tell an officially created HWInfo Secure will *only* start at one of the below 3 offsets. Homebrew (like this tool) will likely create it elsewhere. + - `0x790000`: retail and pandas + - `0x784000`: ISTC (needs confirmation) and ISTD + - `0x794000`: Happened when I deleted HWInfo and let SystemUpdater create it + +## Including system files +*B-b-but you have system files like the bootloader!* Sorry, these files are required to boot a DSi and almost always cannot be custom made due to signing. This is a tool meant to fix every possible software brick, and to do so in an accessible way. Most people are not going to know how to recover a bootloader, find the right FontTable for their region, or get the correct and safe wlanfirm/sysmenuVersion. Even given a well written guide, I know the "what's a hex editor" or "what's a byte" messages all too well. It is not safe to force people to chase after things they may not understand. Especially when one wrong file will cause a brick, and the owner will be none the wiser. \ No newline at end of file diff --git a/arm7/src/main.c b/arm7/src/main.c index b3b148b..4a4bb63 100644 --- a/arm7/src/main.c +++ b/arm7/src/main.c @@ -119,15 +119,15 @@ int main() if (isDSiMode() /*|| ((REG_SCFG_EXT & BIT(17)) && (REG_SCFG_EXT & BIT(18)))*/) { - vu8 *out=(vu8*)0x02300000; + u8 *out=(u8*)0x02300000; memset(out, 0, 16); //#if USENATIVECONSOLEID // first check whether we can read the console ID directly and it was not hidden by SCFG - if (((*(vu16*)0x04004000) & (1u << 10)) == 0 && ((*(vu8*)0x04004D08) & 0x1) == 0) + if (((*(vu16*)0x04004000) & (1u << 10)) == 0 && ((*(u8*)0x04004D08) & 0x1) == 0) { // The console id registers are readable, so use them! - memcpy(out, (vu8*)0x04004D00, 8); + memcpy(out, (u8*)0x04004D00, 8); } if(out[0] == 0 || out[1] == 0) { // For getting ConsoleID without reading from 0x4004D00... @@ -187,7 +187,7 @@ int main() batteryStatus = (readPowerManagement(PM_BATTERY_REG) & 1) ? 0x3 : 0xF; fifoSendValue32(FIFO_USER_03, batteryStatus); - fifoSendValue32(FIFO_USER_01, *(vu8*)0x04004024); + fifoSendValue32(FIFO_USER_01, *(u8*)0x04004024); swiWaitForVBlank(); } diff --git a/arm9/src/main.c b/arm9/src/main.c index 44932b7..826fb94 100644 --- a/arm9/src/main.c +++ b/arm9/src/main.c @@ -69,7 +69,6 @@ static int _mainMenu(int cursor) setMenuHeader(m, "TwlNandTool"); setListHeader(m, "START MENU"); - char modeStr[32]; addMenuItem(m, "FileSystem Menu", NULL, 0, "Options such as repairing MBR\n and formatting twl_main/photo."); addMenuItem(m, "NandFirm menu", NULL, 0, "NandFirm (stage2) installers\n and version testing."); addMenuItem(m, "---------------", NULL, 0, ""); @@ -236,7 +235,7 @@ int main(int argc, char **argv) } int debug1(void) { - + success = true; clearScreen(cSUB); iprintf("\n>> Debug1"); @@ -248,9 +247,11 @@ int debug1(void) { } exitFunction(); + return success; } int debug2(void) { + success = true; clearScreen(cSUB); iprintf("\n>> Corrupt MBR "); @@ -263,11 +264,13 @@ int debug2(void) { dsi_nand_crypt(sector_buf, sector_buf, 0, SECTOR_SIZE / AES_BLOCK_SIZE); if(!parse_mbr(sector_buf, is3DS)) { iprintf("\n\n \x1B[31mERROR!\x1B[30m Failed to break MBR."); + success = false; } else { iprintf("\n\x1B[32mMBR corrupted okay!\x1B[30m"); } exitFunction(); + return success; } int debug3(void) { diff --git a/arm9/src/nand/filesystem.c b/arm9/src/nand/filesystem.c index 4fd7341..9d0aa41 100644 --- a/arm9/src/nand/filesystem.c +++ b/arm9/src/nand/filesystem.c @@ -78,7 +78,6 @@ static int _fsMenu(int cursor) setMenuHeader(m, "TwlNandTool"); setListHeader(m, "FileSystem"); - char modeStr[32]; addMenuItem(m, "Read MBR", NULL, 0, "Test the Master Boot Record."); addMenuItem(m, "Repair MBR", NULL, 0, "Repair the Master Boot Record."); addMenuItem(m, "Format TWL_MAIN", NULL, 0, "Format the partition where the\n firmware, apps, and saves are\n installed.\n\n THIS WILL ERASE EVERYTHING."); @@ -463,7 +462,7 @@ bool filetestMain(void) { memset(sector_buf, 0, SECTOR_SIZE); - iprintf("\nOpening file..."); + iprintf("\nOpening test file..."); FILE *file2 = fopen(file_path, "rb"); if(file2) { iprintf("\nRead test..."); @@ -480,6 +479,8 @@ bool filetestMain(void) { success = false; iprintf("\nFile failed to open!"); } + + remove(file_path); } else { success = false; iprintf("\nTWL_MAIN is not mounted!"); diff --git a/arm9/src/nand/nandfirm.c b/arm9/src/nand/nandfirm.c index ade512c..af43c9b 100644 --- a/arm9/src/nand/nandfirm.c +++ b/arm9/src/nand/nandfirm.c @@ -23,11 +23,12 @@ void death(char *message, u8 *buffer){ static size_t i; enum { - MENUSTATE_CHECK_NF_VER, - MENUSTATE_IMPORT_NF, - MENUSTATE_IMPORT_NF_SDMC, - MENUSTATE_READ_CID, - BACK + NFMENU_CHECK_VER, + NFMENU_IMPORT, + NFMENU_IMPORT_SDMC, + NFMENU_READ_CID, + NFMENU_READ_CONSOLEID, + NFMENU_BACK }; static int _nfMenu(int cursor) @@ -37,11 +38,11 @@ static int _nfMenu(int cursor) setMenuHeader(m, "TwlNandTool"); setListHeader(m, "NandFirm"); - char modeStr[32]; addMenuItem(m, "Check NandFirm", NULL, 0, "Check the stage2 (bootloader)\n version and type."); addMenuItem(m, "Import NandFirm", NULL, 0, "Install the standard stage2\n (bootloader).\n\n This stage2 works normally,\n but it is an updated version:\n - v2265-9336 (prod)\n - v2725-9336 (dev)"); addMenuItem(m, "Import NandFirm (SDMC)", NULL, 0, "Install the SDMC Launcher\n stage2 (bootloader).\n\n SDMC will remove access to\n the firmware and SHOULD NOT\n BE USED unless otherwise\n told to do so."); addMenuItem(m, "CID Info", NULL, 0, "Get NAND chip information."); + addMenuItem(m, "ConsoleID Info", NULL, 0, "Get CPU information."); addMenuItem(m, "Back", NULL, 0, "Leave the NandFirm menu."); m->cursor = cursor; @@ -79,23 +80,27 @@ int nfMain(void) switch (cursor) { - case MENUSTATE_CHECK_NF_VER: + case NFMENU_CHECK_VER: nandFirmRead(); break; - case MENUSTATE_IMPORT_NF: + case NFMENU_IMPORT: nandFirmImport(false); break; - case MENUSTATE_IMPORT_NF_SDMC: + case NFMENU_IMPORT_SDMC: nandFirmImport(true); break; - case MENUSTATE_READ_CID: + case NFMENU_READ_CID: nandPrintInfo(); break; - case BACK: + case NFMENU_READ_CONSOLEID: + cpuPrintInfo(); + break; + + case NFMENU_BACK: programEnd = true; break; } @@ -112,8 +117,6 @@ bool nandFirmRead(void) { iprintf("\n>> NandFirm Version Checker "); iprintf("\n--------------------------------"); - - int fail=0; nand_ReadSectors(626, 1, sector_buf); @@ -123,7 +126,7 @@ bool nandFirmRead(void) { if (sector_buf[i] == 0x0A) { printf("-"); } else if (sector_buf[i] == 0x0D) { - printf(""); + // Print nothing } else { printf("%c", sector_buf[i]); } @@ -179,7 +182,11 @@ bool nandPrintInfo(void) { iprintf("\nProduct name : %s", nandInfo.NAND_PNM); iprintf("\nProduct revision : %02X", nandInfo.NAND_PRV); iprintf("\nProduct S/N : %02X%02X%02X%02X", nandInfo.NAND_PSN[0], nandInfo.NAND_PSN[1], nandInfo.NAND_PSN[2], nandInfo.NAND_PSN[3]); - iprintf("\nManufacturing date : %02X(%d 20%d)",nandInfo.NAND_MDT, nandInfo.NAND_MDT_MONTH, nandInfo.NAND_MDT_YEAR); + if (nandInfo.NAND_MDT_YEAR <= 9) { + iprintf("\nManufacturing date : %02X(%d 200%d)",nandInfo.NAND_MDT, nandInfo.NAND_MDT_MONTH, nandInfo.NAND_MDT_YEAR); + } else { + iprintf("\nManufacturing date : %02X(%d 20%d)",nandInfo.NAND_MDT, nandInfo.NAND_MDT_MONTH, nandInfo.NAND_MDT_YEAR); + } printf("\n\n "); for (i = 16; i > 0;) { i--; @@ -192,6 +199,28 @@ bool nandPrintInfo(void) { } } + exitFunction(); + return success; +} + +bool cpuPrintInfo(void) { + success = true; + extern nandData nandInfo; + clearScreen(cSUB); + iprintf("\n>> ConsoleID (CPU ID) "); + iprintf("\n--------------------------------"); + iprintf("\n\n "); + for (i = 8; i > 0;) { + i--; + if ((i + 1) % 2 == 0) { + printf(" "); + } + printf("%02X", consoleID[i]); + if (i == 8) { + printf("\n "); + } + } + exitFunction(); return success; } \ No newline at end of file diff --git a/arm9/src/nand/nandfirm.h b/arm9/src/nand/nandfirm.h index db288fa..9a4bb81 100644 --- a/arm9/src/nand/nandfirm.h +++ b/arm9/src/nand/nandfirm.h @@ -20,4 +20,5 @@ int nfMain(void); bool nandFirmRead(void); bool nandFirmImport(bool sdmc); -bool nandPrintInfo(void); \ No newline at end of file +bool nandPrintInfo(void); +bool cpuPrintInfo(void); \ No newline at end of file diff --git a/arm9/src/nand/nandio.c b/arm9/src/nand/nandio.c index fe26914..da7c769 100644 --- a/arm9/src/nand/nandio.c +++ b/arm9/src/nand/nandio.c @@ -26,6 +26,7 @@ u8 CID[16]; u8 consoleIDfixed[8]; nandData nandInfo = {0}; +cpuData cpuInfo = {0}; const DISC_INTERFACE io_dsi_nand = { NAND_DEVICENAME, @@ -50,11 +51,11 @@ static u8* crypt_buf = 0; static u32 fat_sig_fix_offset = 0; static u32 sector_buf32[SECTOR_SIZE/sizeof(u32)]; -extern u8 *sector_buf = (u8*)sector_buf32; +u8 *sector_buf = (u8*)sector_buf32; static u32 sector_buf232[SECTOR_SIZE/sizeof(u32)]; -extern u8 *sector_buf2 = (u8*)sector_buf232; +u8 *sector_buf2 = (u8*)sector_buf232; static u32 file_buf32[BUFFER_SIZE/sizeof(u32)]; -extern u8 *file_buf = (u8*)file_buf32; +u8 *file_buf = (u8*)file_buf32; void nandio_set_fat_sig_fix(u32 offset) { @@ -117,6 +118,43 @@ void nandGetInfo(void) { return; } +void cpuGetInfo(void) { + /* + +typedef struct { + uint8_t CPU_START_YEAR[2]; + uint8_t CPU_START_MONTH[1]; + uint8_t CPU_END_YEAR[2]; + uint8_t CPU_END_MONTH[2]; +} cpuData; + + + + 08a* ConsoleIDs (2008/10 to 2009/09): + + 08a16 is introduced around 2008/10 and phased out around 2009/01 + 08a17 is introduced around 2008/11 and phased out around 2009/01 + 08a18 is introduced around 2008/11 and phased out around 2009/01 + 08a19 is introduced around 2009/01 and phased out around 2009/02 + 08a20 is introduced around 2009/02 and phased out around 2009/05 + 08a21 is introduced around 2009/02 and phased out around 2009/05 + 08a22 is introduced around 2009/07 then turned dev only around 2009/07 + It is phased out later that month, but is re-introduced around 2010/06 and phased out around 2010/07 + Looks like old stock used for factory DSis? + 08a23 is introduced around 2009/07 and phased out around 2009/08 + 08a24 is introduced around 2009/09 and phased out around 2009/09 + + 082* ConsoleIDs (2009/08 to 2013/05): + + 08201 is introduced around 2009/08 and is phased out around 2010/06 + 08202 is introduced around 2010/06 and is phased out around 2012/01 + 08203 is introduced around 2010/11 and is phased out around 2011/03 + 08205 is introduced around 2010/12 and is phased out around 2013/05 + 08204 is introduced around 2011/06 and is phased out around 2011/07 + + */ +} + bool nandio_startup() { @@ -132,6 +170,7 @@ bool nandio_startup() consoleIDfixed[i] = consoleID[7-i]; } nandGetInfo(); + cpuGetInfo(); // iprintf("sector 0 is %s\n", is3DS ? "3DS" : "DSi"); dsi_crypt_init((const u8*)consoleIDfixed, (const u8*)0x2FFD7BC, is3DS); @@ -183,7 +222,12 @@ static bool read_sectors(sec_t start, sec_t len, void *buffer) // len is guaranteed <= CRYPT_BUF_LEN static bool write_sectors(sec_t start, sec_t len, const void *buffer) { + static u8 writeCopy[SECTOR_SIZE*16]; + if (len * SECTOR_SIZE > sizeof(writeCopy)) { + return false; + } + memcpy(writeCopy, buffer, len * SECTOR_SIZE); dsi_nand_crypt(crypt_buf, writeCopy, start * SECTOR_SIZE / AES_BLOCK_SIZE, len * SECTOR_SIZE / AES_BLOCK_SIZE); diff --git a/arm9/src/nand/nandio.h b/arm9/src/nand/nandio.h index 74f83b7..08f8f76 100644 --- a/arm9/src/nand/nandio.h +++ b/arm9/src/nand/nandio.h @@ -22,6 +22,7 @@ void nandio_set_fat_sig_fix(uint32_t offset); void getCID(u8 *CID); void getConsoleID(uint8_t *consoleID); void nandGetInfo(void); +void cpuGetInfo(void); typedef struct { uint8_t NAND_MID; @@ -35,11 +36,20 @@ typedef struct { uint8_t NAND_MDT_YEAR; } nandData; +typedef struct { + uint8_t CPU_START_YEAR[2]; + uint8_t CPU_START_MONTH[1]; + uint8_t CPU_END_YEAR[2]; + uint8_t CPU_END_MONTH[2]; +} cpuData; + + extern u8 *sector_buf; extern u8 *file_buf; extern bool is3DS; extern nandData nandInfo; +extern cpuData cpuInfo; extern u8 consoleID[8]; extern u8 CID[16]; diff --git a/arm9/src/nand/polarssl/bn_mul.h b/arm9/src/nand/polarssl/bn_mul.h index 9210dd1..f6bd21d 100644 --- a/arm9/src/nand/polarssl/bn_mul.h +++ b/arm9/src/nand/polarssl/bn_mul.h @@ -576,7 +576,7 @@ #if defined(__thumb__) && !defined(__thumb2__) -#pragma message "using ARM THUMB MULADDC" +// #pragma message "using ARM THUMB MULADDC" #define MULADDC_INIT \ asm( \ diff --git a/arm9/src/nand/twltool/dsi.c b/arm9/src/nand/twltool/dsi.c index 1f1091c..78d0d26 100644 --- a/arm9/src/nand/twltool/dsi.c +++ b/arm9/src/nand/twltool/dsi.c @@ -53,7 +53,7 @@ void dsi_set_ctr(dsi_context* ctx, const unsigned char ctr[16]) ctx->ctr[i] = ctr[15-i]; } -void dsi_init_ctr(dsi_context* ctx, const unsigned char key[16], const unsigned char ctr[12]) +void dsi_init_ctr(dsi_context* ctx, const unsigned char key[16], const unsigned char ctr[16]) { dsi_set_key(ctx, key); dsi_set_ctr(ctx, ctr); diff --git a/arm9/src/nand/twltool/dsi.h b/arm9/src/nand/twltool/dsi.h index f170509..10e3075 100644 --- a/arm9/src/nand/twltool/dsi.h +++ b/arm9/src/nand/twltool/dsi.h @@ -33,7 +33,7 @@ void dsi_add_ctr(dsi_context* ctx, unsigned int carry); void dsi_set_ctr(dsi_context* ctx, const unsigned char ctr[16]); -void dsi_init_ctr(dsi_context* ctx, const unsigned char key[16], const unsigned char ctr[12]); +void dsi_init_ctr(dsi_context* ctx, const unsigned char key[16], const unsigned char ctr[16]); void dsi_crypt_ctr(dsi_context* ctx, const void* in, void* out, unsigned int len); diff --git a/arm9/src/video.h b/arm9/src/video.h index 87e04eb..ea9ddb3 100755 --- a/arm9/src/video.h +++ b/arm9/src/video.h @@ -4,7 +4,7 @@ extern enum console { cMAIN= 1<<0, cSUB= 1<<1 -}; +}consolescreens; void videoInit (); void consoleHide (enum console c);