diff --git a/rxtools/Makefile b/rxtools/Makefile index ee00e0e1..1f3bdfdb 100644 --- a/rxtools/Makefile +++ b/rxtools/Makefile @@ -39,16 +39,13 @@ CFLAGS := -g -O2 -std=c99 $(CWARNING) $(CFORCE) $(CMACHINE) $(CPPFLAGS) -DVERSIO # Use Thumb libraries because sbrk of ARM newlib in devkitPro doesn't work. LDFLAGS := -nostartfiles -g $(CMACHINE) -mthumb -mthumb-interwork -Wl,-Tstub.ld -CCOBJS := $(addprefix $(BUILD)/,main.o features/CTRDecryptor.o \ - features/NandDumper.o features/TitleKeyDecrypt.o \ - features/install.o features/downgradeapp.o \ - features/AdvancedFileManager.o features/firm.o \ - features/nandtools.o features/padgen.o features/screenshot.o \ +CCOBJS := $(addprefix $(BUILD)/,main.o features/decryption.o \ + features/install.o features/firm.o features/screenshot.o \ lib/fatfs/diskio.o lib/fatfs/ff.o lib/fatfs/option/unicode.o \ lib/media/nand.o lib/media/tmio/tmio.o \ lib/polarssl/padlock.o lib/polarssl/sha2.o lib/polarssl/aes.o \ lib/ui/console.o lib/ui/draw.o lib/cfg.o lib/crypto.o lib/fs.o lib/hid.o \ - lib/lang.o lib/log.o lib/i2c.o lib/jsmn/jsmn.o lib/menu.o lib/ncch.o) + lib/lang.o lib/log.o lib/i2c.o lib/jsmn/jsmn.o lib/ncch.o) OBJS := $(CCOBJS) $(addprefix $(BUILD)/, start.o font_ascii.o lib/delay.o) DEPS := $(subst $(BUILD)/,$(DEPS_DIR)/,$(CCOBJS)) diff --git a/rxtools/source/MainMenu.h b/rxtools/source/MainMenu.h deleted file mode 100644 index 559031b9..00000000 --- a/rxtools/source/MainMenu.h +++ /dev/null @@ -1,409 +0,0 @@ -/* - * Copyright (C) 2015 The PASTA Team - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef MY_MENU -#define MY_MENU - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static void ShutDown(int arg){ - i2cWriteRegister(I2C_DEV_MCU, 0x20, (arg) ? (uint8_t)(1<<0):(uint8_t)(1<<2)); - while(1); -} - -static Menu DecryptMenu = { - L"Decryption Options", - .Option = (MenuEntry[6]){ - { L" Decrypt CTR Titles", &CTRDecryptor, L"dec0.bin" }, - { L" Decrypt Title Keys", &DecryptTitleKeys, L"dec1.bin" }, - { L" Decrypt encTitleKeys.bin", &DecryptTitleKeyFile, L"dec2.bin" }, - { L" Generate Xorpads", &PadGen, L"dec3.bin" }, - { L" Decrypt partitions", &DumpNandPartitions, L"dec4.bin" }, - { L" Generate fat16 Xorpad", &GenerateNandXorpads, L"dec5.bin" }, - }, - 6, - 0, - 0 -}; - -static Menu DumpMenu = { - L"Dumping Options", - .Option = (MenuEntry[3]){ - { L" Create NAND dump", &NandDumper, L"dmp0.bin" }, - { L" Dump System Titles", &DumpNANDSystemTitles, L"dmp1.bin" }, - { L" Dump NAND Files", &dumpCoolFiles, L"dmp2.bin" }, - }, - 3, - 0, - 0 -}; - -static Menu InjectMenu = { - L"Injection Options", - .Option = (MenuEntry[2]){ - { L" Inject EmuNAND partitions", &RebuildNand, L"inj0.bin" }, - { L" Inject NAND Files", &restoreCoolFiles, L"inj1.bin" }, - }, - 2, - 0, - 0 -}; - -static Menu AdvancedMenu = { - L"Other Options", - .Option = (MenuEntry[5]){ - { L" Downgrade MSET on SysNAND", &downgradeMSET, L"adv0.bin" }, - { L" Install FBI over H&S App", &installFBI, L"adv1.bin" }, - { L" Restore original H&S App", &restoreHS, L"adv2.bin" }, - { L" Launch PastaMode", (void(*)())&PastaMode, L"adv3.bin" }, - { L" Advanced File Manager", &AdvFileManagerMain, L"adv4.bin" }, - }, - 5, - 0, - 0 -}; - -static Menu SettingsMenu = { - L" SETTINGS", - .Option = (MenuEntry[9]){ - { L"Force UI boot ", NULL, L"app.bin" }, - { L"Selected theme: ", NULL, L"app.bin" }, - { L"Random theme: ", NULL, L"app.bin" }, - { L"Show AGB_FIRM BIOS: ", NULL, L"app.bin" }, - { L"Enable 3D UI: ", NULL, L"app.bin" }, - { L"Autoboot into sysNAND: ", NULL, L"app.bin" }, - { L"Console language: ", NULL, L"app.bin" }, - { L"Reboot ", NULL, L"app.bin" }, - { L"Shutdown ", NULL, L"app.bin" }, - }, - 9, - 0, - 0 -}; - -void DecryptMenuInit(){ - MenuInit(&DecryptMenu); - MenuShow(); - while (true) { - uint32_t pad_state = InputWait(); - if(pad_state & BUTTON_DOWN) MenuNextSelection(); - if(pad_state & BUTTON_UP) MenuPrevSelection(); - if(pad_state & BUTTON_A) MenuSelect(); - if(pad_state & BUTTON_B) { MenuClose(); break; } - TryScreenShot(); - MenuShow(); - } -} - -void DumpMenuInit(){ - MenuInit(&DumpMenu); - MenuShow(); - while (true) { - uint32_t pad_state = InputWait(); - if(pad_state & BUTTON_DOWN) MenuNextSelection(); - if(pad_state & BUTTON_UP) MenuPrevSelection(); - if(pad_state & BUTTON_A) MenuSelect(); - if(pad_state & BUTTON_B) { MenuClose(); break; } - TryScreenShot(); - MenuShow(); - } -} - -void InjectMenuInit(){ - MenuInit(&InjectMenu); - MenuShow(); - while (true) { - uint32_t pad_state = InputWait(); - if(pad_state & BUTTON_DOWN) MenuNextSelection(); - if(pad_state & BUTTON_UP) MenuPrevSelection(); - if(pad_state & BUTTON_A) MenuSelect(); - if(pad_state & BUTTON_B) { MenuClose(); break; } - TryScreenShot(); - MenuShow(); - } -} - -void AdvancedMenuInit(){ - MenuInit(&AdvancedMenu); - MenuShow(); - while (true) { - uint32_t pad_state = InputWait(); - if(pad_state & BUTTON_DOWN) MenuNextSelection(); - if(pad_state & BUTTON_UP) MenuPrevSelection(); - if(pad_state & BUTTON_A) MenuSelect(); - if(pad_state & BUTTON_B) { MenuClose(); break; } - TryScreenShot(); - MenuShow(); - } -} - -void SettingsMenuInit(){ - MenuInit(&SettingsMenu); - DIR d; - FILINFO fno; - wchar_t str[_MAX_LFN]; - wchar_t strl[_MAX_LFN]; - wchar_t strr[_MAX_LFN]; - const unsigned int maxLangNum = 16; - TCHAR langs[maxLangNum][CFG_STR_MAX_LEN]; - unsigned char theme_num = 0; - unsigned int curLang, langNum; - - curLang = 0; - langNum = 0; - - if (!f_opendir(&d, langPath)) { - mbstowcs(str, cfgs[CFG_LANG].val.s, _MAX_LFN); - - while (langNum < maxLangNum) { - fno.lfname = langs[langNum]; - fno.lfsize = CFG_STR_MAX_LEN; - - if (f_readdir(&d, &fno)) - break; - - if (fno.lfname[0] == 0) - break; - - if (!wcscmp(fno.lfname, str)) - curLang = langNum; - - langNum++; - } - - f_closedir(&d); - } - - while (true) { - //UPDATE SETTINGS GUI - swprintf(MyMenu->Name, CONSOLE_MAX_TITLE_LENGTH+1, L"%ls Build: %s", strings[STR_SETTINGS], VERSION); - swprintf(MyMenu->Option[0].Str, CONSOLE_MAX_LINE_LENGTH+1, strings[STR_FORCE_UI_BOOT], cfgs[CFG_GUI].val.i ? strings[STR_ENABLED] : strings[STR_DISABLED]); - swprintf(MyMenu->Option[1].Str, CONSOLE_MAX_LINE_LENGTH+1, strings[STR_SELECTED_THEME], cfgs[CFG_THEME].val.i + '0'); - swprintf(MyMenu->Option[2].Str, CONSOLE_MAX_LINE_LENGTH+1, strings[STR_RANDOM], cfgs[CFG_RANDOM].val.i ? strings[STR_ENABLED] : strings[STR_DISABLED]); - swprintf(MyMenu->Option[3].Str, CONSOLE_MAX_LINE_LENGTH+1, strings[STR_SHOW_AGB], cfgs[CFG_AGB].val.i ? strings[STR_ENABLED] : strings[STR_DISABLED]); - swprintf(MyMenu->Option[4].Str, CONSOLE_MAX_LINE_LENGTH+1, strings[STR_ENABLE_3D_UI], cfgs[CFG_3D].val.i ? strings[STR_ENABLED] : strings[STR_DISABLED]); - swprintf(MyMenu->Option[5].Str, CONSOLE_MAX_LINE_LENGTH+1, strings[STR_ABSYSN], cfgs[CFG_ABSYSN].val.i ? strings[STR_ENABLED] : strings[STR_DISABLED]); - swprintf(MyMenu->Option[6].Str, CONSOLE_MAX_LINE_LENGTH+1, strings[STR_MENU_LANGUAGE], strings[STR_LANG_NAME]); - swprintf(MyMenu->Option[7].Str, CONSOLE_MAX_LINE_LENGTH+1, strings[STR_SHUTDOWN]); - swprintf(MyMenu->Option[8].Str, CONSOLE_MAX_LINE_LENGTH+1, strings[STR_REBOOT]); - MenuRefresh(); - - uint32_t pad_state = InputWait(); - if (pad_state & BUTTON_DOWN) - { - if(MyMenu->Current == 7) MenuNextSelection(); - MenuNextSelection(); - } - if (pad_state & BUTTON_UP) - { - if(MyMenu->Current == 0) MenuPrevSelection(); - MenuPrevSelection(); - } - if (pad_state & BUTTON_LEFT || pad_state & BUTTON_RIGHT) - { - if (MyMenu->Current == 0) - { - cfgs[CFG_GUI].val.i ^= 1; - } - else if (MyMenu->Current == 1) //theme selection - { - /* Jump to the next available theme */ - File AppBin; - bool found = false; - unsigned char i; - - if (pad_state & BUTTON_LEFT && theme_num > 0) - { - for (i = theme_num - 1; i > 0; i--) - { - swprintf(str, _MAX_LFN, L"/rxTools/Theme/%u/app.bin", i); - if (FileOpen(&AppBin, str, 0)) - { - FileClose(&AppBin); - found = true; - break; - } - } - - if (i == 0) found = true; - } else - if (pad_state & BUTTON_RIGHT && theme_num < 9) - { - for (i = theme_num + 1; i <= 9; i++) - { - swprintf(str, _MAX_LFN, L"/rxTools/Theme/%u/app.bin", i); - if (FileOpen(&AppBin, str, 0)) - { - FileClose(&AppBin); - found = true; - break; - } - } - } - - if (found) - { - theme_num = i; - swprintf(str, _MAX_LFN, L"/rxTools/Theme/%u/TOP.bin", theme_num); - if (cfgs[CFG_3D].val.i) - { - swprintf(strl, _MAX_LFN, L"/rxTools/Theme/%u/TOPL.bin", theme_num); - swprintf(strr, _MAX_LFN, L"/rxTools/Theme/%u/TOPR.bin", theme_num); - DrawTopSplash(str, strl, strr); - } - else - { - swprintf(str, _MAX_LFN, L"/rxTools/Theme/%u/TOP.bin", theme_num); - DrawTopSplash(str, str, str); - } - - cfgs[CFG_THEME].val.i = theme_num; - trySetLangFromTheme(1); - } - } - else if (MyMenu->Current == 2) cfgs[CFG_RANDOM].val.i ^= 1; - else if (MyMenu->Current == 3) cfgs[CFG_AGB].val.i ^= 1; - else if (MyMenu->Current == 4) - { - cfgs[CFG_3D].val.i ^= 1; - swprintf(str, _MAX_LFN, L"/rxTools/Theme/%u/TOP.bin", theme_num); - if(cfgs[CFG_3D].val.i) - { - swprintf(strl, _MAX_LFN, L"/rxTools/Theme/%u/TOPL.bin", theme_num); - swprintf(strr, _MAX_LFN, L"/rxTools/Theme/%u/TOPR.bin", theme_num); - DrawTopSplash(str, strl, strr); - } - else - { - swprintf(str, _MAX_LFN, L"/rxTools/Theme/%u/TOP.bin", theme_num); - DrawTopSplash(str, str, str); - } - } - else if (MyMenu->Current == 5) - { - cfgs[CFG_ABSYSN].val.i ^= 1; - } - else if (MyMenu->Current == 6) - { - if (pad_state & BUTTON_LEFT && curLang > 0) - curLang--; - else if (pad_state & BUTTON_RIGHT && curLang + 1 < langNum) - curLang++; - - wcstombs(cfgs[CFG_LANG].val.s, langs[curLang], - CFG_STR_MAX_LEN); - switchStrings(); - } - else if (MyMenu->Current == 7) - { - MenuNextSelection(); - } - else if (MyMenu->Current == 8) - { - MenuPrevSelection(); - } - } - else if (pad_state & BUTTON_A) - { - if (MyMenu->Current == 7) - { - fadeOut(); - ShutDown(1); - } - else if (MyMenu->Current == 8) - { - fadeOut(); - ShutDown(0); - } - } - if (pad_state & BUTTON_B) - { - //Code to save settings - writeCfg(); - MenuClose(); - break; - } - - TryScreenShot(); - - } -} - -void BootMenuInit(){ - wchar_t str[_MAX_LFN]; - - //SHOW ONLY SYSYNAND IF EMUNAND IS NOT FOUND - swprintf(str, _MAX_LFN, L"/rxTools/Theme/%u/boot%c.bin", - cfgs[CFG_THEME].val.i, checkEmuNAND() ? L'0' : L'S'); - DrawBottomSplash(str); - while (true) { - uint32_t pad_state = InputWait(); - if ((pad_state & BUTTON_Y) && checkEmuNAND()) { - rxModeWithSplash(1); //Boot emunand (only if found) - DrawBottomSplash(str); - } else if (pad_state & BUTTON_X) { - rxModeWithSplash(0); //Boot sysnand - DrawBottomSplash(str); - } else if (pad_state & BUTTON_B) - break; - } - - MenuClose(); -} - -void CreditsMenuInit(){ - wchar_t str[_MAX_LFN]; - swprintf(str, _MAX_LFN, L"/rxTools/Theme/%u/credits.bin", - cfgs[CFG_THEME].val.i); - DrawBottomSplash(str); - WaitForButton(BUTTON_B); - OpenAnimation(); -} - -static Menu MainMenu = { - L"rxTools - Roxas75 [v3.0]", - .Option = (MenuEntry[7]){ - { L" Launch rxMode", &BootMenuInit, L"menu0.bin" }, - { L" Decryption Options", &DecryptMenuInit, L"menu1.bin" }, - { L" Dumping Options", &DumpMenuInit, L"menu2.bin" }, - { L" Injection Options", &InjectMenuInit, L"menu3.bin" }, - { L" Advanced Options", &AdvancedMenuInit, L"menu4.bin" }, - { L" Settings", &SettingsMenuInit, L"menu5.bin" }, - { L" Credits", &CreditsMenuInit, L"menu6.bin" }, - }, - 7, - 0, - 0 - }; - -#endif diff --git a/rxtools/source/features/AdvancedFileManager.c b/rxtools/source/features/AdvancedFileManager.c deleted file mode 100644 index 554e1de2..00000000 --- a/rxtools/source/features/AdvancedFileManager.c +++ /dev/null @@ -1,277 +0,0 @@ -/* - * Copyright (C) 2015 The PASTA Team - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - #define FILE_ACTIONS 2 - -//---- GLOBAL VARIABLES ---- -int i; -void *screentmp = (void*)0x27000000; - - -size_t AdvFileManagerList(const TCHAR *path, TCHAR ***ls) { - size_t count = 0; - - if (wcscmp(path, L"")) - { - DIR myDir; - FILINFO curInfo; - memset(&myDir, 0, sizeof(DIR)); - memset(&curInfo, 0, sizeof(FILINFO)); - FILINFO *myInfo = &curInfo; - - int res = f_opendir(&myDir, path); - if (res == FR_NO_FILE) { - print(strings[STR_ERROR_OPENING], path); - return 0; - } - *ls = NULL; - *ls = calloc(1000, sizeof(char *)); - count = 0; - f_readdir(&myDir, myInfo); - - while (!myInfo->fname[0] == 0) - { - (*ls)[count++] = wcsdup(myInfo->fname); - f_readdir(&myDir, myInfo); - } - - f_closedir(&myDir); - } - else - { - *ls = calloc(3, sizeof(char *)); - (*ls)[count++] = wcsdup(L"0"); - (*ls)[count++] = wcsdup(L"1"); - (*ls)[count++] = wcsdup(L"2"); - } - return count; -} - -void AdvFileManagerShow(panel_t* Panel, int x){ - - //Title - wchar_t tmp[_MAX_LFN]; - swprintf(tmp, _MAX_LFN, L"%ls", Panel->dir); - DrawString(screentmp, tmp, 15 + x, FONT_HEIGHT * 2, ConsoleGetTextColor(), TRANSPARENT); - - //FileList - if (Panel->count != 0) - { - int n = 0; - int divisions = Panel->count % 10 == 0 ? Panel->count / 10 : Panel->count / 10 + 1; - int list[divisions]; - for (n = 0; ncount % 10 != 0)list[n] = Panel->count - (Panel->count / 10) * 10; - else list[n] = 10; - } - - int i = 0; - for (i = Panel->beginning; i < Panel->beginning + list[(Panel->pointer / 10)]; i++) { - swprintf(tmp, _MAX_LFN, L"%ls %ls", (i == Panel->pointer && Panel->enabled == 1) ? strings[STR_CURSOR] : strings[STR_NO_CURSOR], Panel->files[i]); - DrawString(screentmp, tmp, 15 + x, FONT_HEIGHT * 3 + FONT_HEIGHT * (i - Panel->beginning + 1), ConsoleGetTextColor(), TRANSPARENT); - } - } -} - -void AdvFileManagerNextSelection(panel_t* Panel){ - if (Panel->pointer != Panel->count - 1) Panel->pointer++; -} - -void AdvFileManagerPrevSelection(panel_t* Panel){ - if (Panel->pointer != 0) Panel->pointer--; -} - -void AdvFileManagerBack(panel_t* Panel){ - //go back - int u; - if (Panel->openedFolder == 1) wcscpy(Panel->dir, L""); - else{ - Panel->dir[wcslen(Panel->dir) - 1] = 'f'; //just a casual letter - for (u = wcslen(Panel->dir); u >= 0; u--) - if (Panel->dir[u] == '/' || Panel->dir[u] == ':') { Panel->dir[u] = '\0'; break; } - } - Panel->beginning = 0; - Panel->pointer = 0; - Panel->openedFolder--; - Panel->count = AdvFileManagerList(Panel->dir, &Panel->files); -} - - -void AdvFileManagerSelect(panel_t* Panel){ - //enter file/folder - int u; - int isafile = 0; - for (u = 0; u < wcslen(Panel->files[Panel->pointer]); u++) - { - if (Panel->files[Panel->pointer][u] == '.') isafile = 1; - } - if (isafile){ - //Open a file - FIRMS only for now - wchar_t filePath[_MAX_LFN]; - swprintf(filePath, _MAX_LFN, L"%ls%ls%ls", - Panel->dir, // Opened folder - Panel->openedFolder == 0 ? L"" : L"/", // '/' or nothing - Panel->files[Panel->pointer]); // File name - - AdvFileManagerFileAction(filePath); - } - else - { - //enter folder - if (Panel->openedFolder != 0) wcscat(Panel->dir, L"/"); - wcscat(Panel->dir, Panel->files[Panel->pointer]); - if (Panel->openedFolder == 0) wcscat(Panel->dir, L":"); - Panel->beginning = 0; - Panel->pointer = 0; - Panel->openedFolder++; - Panel->count = AdvFileManagerList(Panel->dir, &Panel->files); - } -} - -void AdvFileManagerFileAction(TCHAR filePath[]) -{ - FILINFO fno; - memset(&fno, 0, sizeof(FILINFO)); - FILINFO *myInfo = &fno; - f_stat(filePath, myInfo); - - int actions_idx = 0; - while (true) - { - //DRAW GUI - ConsoleInit(); - ConsoleSetTitle(myInfo->fname); - wchar_t* beg; - for (i = 0; i < FILE_ACTIONS; i++) - { - if (i == actions_idx) beg = strings[STR_CURSOR]; - else beg = strings[STR_NO_CURSOR]; - - if (i == 0)print(L"%ls Launch as firm\n", beg); - if (i == 1)print(L"%ls File info\n", beg); - if (i == 2)print(L"%ls Something...\n", beg); - } - ConsoleShow(); - - //APP CONTROLS - uint32_t pad_state = InputWait(); - if (pad_state & BUTTON_DOWN) - { - if (actions_idx != FILE_ACTIONS - 1) actions_idx++; //MOVE DOWN - else actions_idx = 0; //MOVE DOWN While at bottom -> go to top - } - else if (pad_state & BUTTON_UP) - { - if (actions_idx != 0) actions_idx--; //MOVE UP - else actions_idx = FILE_ACTIONS - 1; //MOVE UP While at top -> go to bottom - } - else if (pad_state & BUTTON_A) - { - switch(actions_idx) - { - case 0: - FirmLoader(filePath); - return; - - case 1: - while(!(pad_state & BUTTON_B)) - { - ConsoleInit(); - ConsoleSetTitle(L"File Info"); - print(L"Name: %ls\n", myInfo->fname); - print(L"Size: %lu byte\n", myInfo->fsize); - print(L"Timestamp: %u/%02u/%02u, %02u:%02u\n", (myInfo->fdate >> 9) + 1980, myInfo->fdate >> 5 & 15, myInfo->fdate & 31, myInfo->ftime >> 11, myInfo->ftime >> 5 & 63); - ConsoleShow(); - pad_state = InputWait(); - } - break; - - case 2: - //Something.... - return; - } - } - else if (pad_state & BUTTON_B) break; - } -} - -/*Advanced File Manager main code*/ - -void AdvFileManagerMain(){ - panel_t Panels[2]; - int currentPanel = 0; - - //Reset both panels - for (i = 0; i < 2; i++) - { - Panels[i].pointer = 0; - Panels[i].beginning = 0; - Panels[i].openedFolder = 0; - Panels[i].enabled = 0; - wcscpy(Panels[i].dir, L""); - Panels[i].count = AdvFileManagerList(Panels[i].dir, &Panels[i].files); - } - Panels[0].enabled = 1; - - - - while (true) - { - //Background - wchar_t str[_MAX_LFN]; - swprintf(str, _MAX_LFN, L"/rxTools/Theme/%u/FM.bin", cfgs[CFG_THEME].val.i); - DrawSplash(screentmp, str); - - AdvFileManagerShow(&Panels[0], 0); - AdvFileManagerShow(&Panels[1], 155); - memcpy(BOT_SCREEN, screentmp, SCREEN_SIZE); //Trick to avoid screen flickering - - uint32_t pad_state = InputWait(); - if (pad_state & BUTTON_DOWN) AdvFileManagerNextSelection(&Panels[currentPanel]); - else if (pad_state & BUTTON_UP) AdvFileManagerPrevSelection(&Panels[currentPanel]); - else if (pad_state & BUTTON_A) AdvFileManagerSelect(&Panels[currentPanel]); - else if (pad_state & BUTTON_B) - { - if (Panels[currentPanel].openedFolder == 0) break; - else AdvFileManagerBack(&Panels[currentPanel]); - } - else if (pad_state & BUTTON_LEFT) currentPanel = 0; - else if (pad_state & BUTTON_RIGHT)currentPanel = 1; - - //Change page - if (Panels[currentPanel].pointer - Panels[currentPanel].beginning == 10)Panels[currentPanel].beginning += 10; - if (Panels[currentPanel].pointer -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "stdio.h" -#include -#include - -#define BUFFER_ADDR ((uint8_t*)0x21000000) -#define BLOCK_SIZE (8*1024*1024) - -char str[100]; - -uint32_t DecryptPartition(PartitionInfo* info){ - if(info->keyY != NULL) - setup_aeskey(info->keyslot, AES_BIG_INPUT|AES_NORMAL_INPUT, info->keyY); - use_aeskey(info->keyslot); - - uint8_t ctr[16] __attribute__((aligned(32))); - memcpy(ctr, info->ctr, 16); - - uint32_t size_bytes = info->size; - for (uint32_t i = 0; i < size_bytes; i += BLOCK_SIZE) { - uint32_t j; - for (j = 0; (j < BLOCK_SIZE) && (i+j < size_bytes); j+= 16) { - set_ctr(AES_BIG_INPUT|AES_NORMAL_INPUT, ctr); - aes_decrypt((void*)info->buffer+j, (void*)info->buffer+j, ctr, 1, AES_CTR_MODE); - add_ctr(ctr, 1); - TryScreenShot(); //Putting it here allows us to take screenshots at any decryption point, since everyting loops in this - } - } - return 0; -} - -void ProcessExeFS(PartitionInfo* info){ //We expect Exefs to take just a block. Why? No exefs right now reached 8MB. - if(info->keyslot == 0x2C){ - DecryptPartition(info); - }else if(info->keyslot == 0x25){ //The new keyX is a bit tricky, 'couse only .code is encrypted with it - PartitionInfo myInfo; - memcpy((void*)&myInfo, (void*)info, sizeof(PartitionInfo)); - uint8_t OriginalCTR[16]; memcpy(OriginalCTR, info->ctr, 16); - myInfo.keyslot = 0x2C; myInfo.size = 0x200; - DecryptPartition(&myInfo); add_ctr(myInfo.ctr, 0x200 / 16); - if(myInfo.buffer[0] == '.' && myInfo.buffer[1] == 'c' && myInfo.buffer[2] == 'o' && myInfo.buffer[3] == 'd' && myInfo.buffer[4] == 'e'){ - //The 7.xKey encrypted .code partition - uint32_t codeSize = *((unsigned int*)(myInfo.buffer + 0x0C)); - uint32_t nextSection = *((unsigned int*)(myInfo.buffer + 0x18)) + 0x200; - myInfo.buffer += 0x200; myInfo.size = codeSize; myInfo.keyslot = 0x25; - DecryptPartition(&myInfo); - //The rest is normally encrypted - memcpy((void*)&myInfo, (void*)info, sizeof(PartitionInfo)); - myInfo.buffer += nextSection; myInfo.size -= nextSection; myInfo.keyslot = 0x2C; - myInfo.ctr = OriginalCTR; - add_ctr(myInfo.ctr, nextSection/16); - DecryptPartition(&myInfo); - }else{ - myInfo.size = info->size-0x200; - myInfo.buffer += 0x200; - DecryptPartition(&myInfo); - } - } -} - -int ProcessCTR(TCHAR* path){ - PartitionInfo myInfo; - File myFile; - if(FileOpen(&myFile, path, 0)){ - ConsoleInit(); - ConsoleSetTitle(strings[STR_DECRYPT], strings[STR_CTR]); - unsigned int ncch_base = 0x100; - unsigned char magic[] = { 0, 0, 0, 0, 0}; - FileRead(&myFile, magic, 4, ncch_base); - if(magic[0] == 'N' && magic[1] == 'C' && magic[2] == 'S' && magic[3] == 'D'){ - ncch_base = 0x4000; - FileRead(&myFile, magic, 4, ncch_base+0x100); - if(!(magic[0] == 'N' && magic[1] == 'C' && magic[2] == 'C' && magic[3] == 'H')){ - FileClose(&myFile); - return 2; - } - }else if(magic[0] == 'N' && magic[1] == 'C' && magic[2] == 'C' && magic[3] == 'H'){ - ncch_base = 0x0; - }else{ - FileClose(&myFile); - return 2; - } - ctr_ncchheader NCCH; unsigned int mediaunitsize = 0x200; - FileRead(&myFile, &NCCH, 0x200, ncch_base); - - print(L"%s\n", (char*)NCCH.productcode); - unsigned int NEWCRYPTO = 0, CRYPTO = 1; - if(NCCH.flags[3] != 0) NEWCRYPTO = 1; - if(NCCH.flags[7] & 4) CRYPTO = 0; - if(NEWCRYPTO){ - print(strings[STR_CRYPTO_TYPE], strings[STR_KEY7]); - }else if(CRYPTO){ - print(strings[STR_CRYPTO_TYPE], strings[STR_SECURE]); - }else{ - print(strings[STR_CRYPTO_TYPE], strings[STR_NONE]); - print(strings[STR_COMPLETED]); - FileClose(&myFile); - ConsoleShow(); - return 3; - } - - uint8_t CTR[16]; - if(getle32(NCCH.extendedheadersize) > 0){ - print(strings[STR_DECRYPTING], strings[STR_EXHEADER]); - ConsoleShow(); - ncch_get_counter(NCCH, CTR, 1); - FileRead(&myFile, BUFFER_ADDR, 0x800, ncch_base + 0x200); - myInfo.buffer = BUFFER_ADDR; - myInfo.size = 0x800; - myInfo.keyslot = 0x2C; - myInfo.ctr = CTR; - myInfo.keyY = NCCH.signature; - DecryptPartition(&myInfo); - FileWrite(&myFile, BUFFER_ADDR, 0x800, ncch_base + 0x200); - } - if(getle32(NCCH.exefssize) > 0){ - print(strings[STR_DECRYPTING], strings[STR_EXEFS]); - ConsoleShow(); - ncch_get_counter(NCCH, CTR, 2); - myInfo.buffer = BUFFER_ADDR; - myInfo.keyslot = NEWCRYPTO ? 0x25 : 0x2C; - myInfo.ctr = CTR; - myInfo.keyY = NCCH.signature; - - size_t bytesRead = FileRead(&myFile, BUFFER_ADDR, getle32(NCCH.exefssize) * mediaunitsize, ncch_base + getle32(NCCH.exefsoffset) * mediaunitsize); - myInfo.size = bytesRead; - ProcessExeFS(&myInfo); //Explanation at function definition - FileWrite(&myFile, BUFFER_ADDR, getle32(NCCH.exefssize) * mediaunitsize, ncch_base + getle32(NCCH.exefsoffset) * mediaunitsize); - } - if(getle32(NCCH.romfssize) > 0){ - print(strings[STR_DECRYPTING], strings[STR_ROMFS]); - ConsoleShow(); - ncch_get_counter(NCCH, CTR, 3); - myInfo.buffer = BUFFER_ADDR; - myInfo.keyslot = NEWCRYPTO ? 0x25 : 0x2C; - myInfo.ctr = CTR; - myInfo.keyY = NCCH.signature; - for(int i = 0; i < (getle32(NCCH.romfssize) * mediaunitsize + BLOCK_SIZE - 1) / BLOCK_SIZE; i++){ - print(L"%3d%%\b\b\b\b", - (int)((i*BLOCK_SIZE)/(getle32(NCCH.romfssize) * mediaunitsize/ 100))); - size_t bytesRead = FileRead(&myFile, BUFFER_ADDR, i*BLOCK_SIZE <= (getle32(NCCH.romfssize) * mediaunitsize) ? BLOCK_SIZE : (getle32(NCCH.romfssize) * mediaunitsize) % BLOCK_SIZE, ncch_base + getle32(NCCH.romfsoffset) * mediaunitsize + i*BLOCK_SIZE); - myInfo.size = bytesRead; - DecryptPartition(&myInfo); - add_ctr(myInfo.ctr, bytesRead/16); - FileWrite(&myFile, BUFFER_ADDR, bytesRead, ncch_base + getle32(NCCH.romfsoffset) * mediaunitsize + i*BLOCK_SIZE); - } - print(L"\n"); - } - NCCH.flags[7] |= 4; //Disable encryption - NCCH.flags[3] = 0; //Disable 7.XKey usage - FileWrite(&myFile, &NCCH, 0x200, ncch_base); - if(ncch_base == 0x4000) FileWrite(&myFile, ((uint8_t*)&NCCH) + 0x100, 0x100, 0x1100); //Only for NCSD - FileClose(&myFile); - print(strings[STR_COMPLETED]); - ConsoleShow(); - return 0; - }else return 1; -} - -int ExploreFolders(wchar_t* folder){ - int nfiles = 0; - DIR myDir; - FILINFO curInfo; - memset(&myDir, 0, sizeof(DIR)); - memset(&curInfo, 0, sizeof(FILINFO)); - FILINFO *myInfo = &curInfo; - - myInfo->fname[0] = 'A'; - while(f_opendir(&myDir, folder) != FR_OK); - for(int i = 0; myInfo->fname[0] != 0; i++){ - if( f_readdir(&myDir, myInfo)) break; - if(myInfo->fname[0] == '.' || !wcscmp(myInfo->fname, L"NINTEN~1")) continue; - - wchar_t path[_MAX_LFN]; - swprintf(path, _MAX_LFN, L"%ls/%ls", folder, myInfo->fname); - if(path[wcslen(path) - 1] == '/') break; - - if(myInfo->fattrib & AM_DIR){ - nfiles += ExploreFolders(path); - }else if(true){ - if(ProcessCTR(path) == 0){ - nfiles++; - } - } - - } - f_closedir(&myDir); - return nfiles; -} - -void CTRDecryptor(){ - ConsoleInit(); - ConsoleSetTitle(strings[STR_DECRYPT], strings[STR_CTR]); - ConsoleShow(); - - int nfiles = ExploreFolders(L""); - - ConsoleInit(); - print(strings[STR_DECRYPTED], nfiles, strings[STR_FILES]); - print(strings[STR_PRESS_BUTTON_ACTION], strings[STR_BUTTON_A], strings[STR_CONTINUE]); - - ConsoleShow(); - WaitForButton(BUTTON_A); -} diff --git a/rxtools/source/features/NandDumper.c b/rxtools/source/features/NandDumper.c deleted file mode 100644 index 7a392ab1..00000000 --- a/rxtools/source/features/NandDumper.c +++ /dev/null @@ -1,284 +0,0 @@ -/* - * Copyright (C) 2015 The PASTA Team - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "stdio.h" - -#define NAND_SECTOR_SIZE 0x200 -#define BUF1 (void*)0x21000000 -#define PROGRESS_WIDTH 16 - -static size_t getNandSize() -{ - return getMpInfo() == MPINFO_KTR ? 0x4D800000 : 0x3AF00000; -} - -int NandSwitch(){ - if(!checkEmuNAND()) return 0; //If No EmuNAND, we force to work on SysNAND - ConsoleInit(); - print(strings[STR_CHOOSE], strings[STR_NAND]); - print(strings[STR_BLANK_BUTTON_ACTION], strings[STR_BUTTON_X], strings[STR_SYSNAND]); - print(strings[STR_BLANK_BUTTON_ACTION], strings[STR_BUTTON_Y], strings[STR_EMUNAND]); - print(strings[STR_BLANK_BUTTON_ACTION], strings[STR_BUTTON_B], strings[STR_CANCEL]); - - ConsoleShow(); - while (true) { - uint32_t pad_state = InputWait(); - if(pad_state & BUTTON_X) return SYS_NAND; - if(pad_state & BUTTON_Y) return EMU_NAND; - if(pad_state & BUTTON_B) return UNK_NAND; - } -} - -void NandDumper(){ - ConsoleSetTitle(strings[STR_DUMP], strings[STR_NAND]); - File myFile; - int isEmuNand = SYS_NAND; - if(checkEmuNAND() && (isEmuNand = NandSwitch()) == UNK_NAND) return; - isEmuNand--; - ConsoleInit(); - ConsoleSetTitle(strings[STR_DUMP], strings[STR_NAND]); - unsigned char* buf = BUF1; - unsigned int nsectors = NAND_SECTOR_SIZE; //sectors in a row - wchar_t tmpstr[STR_MAX_LEN]; - wchar_t ProgressBar[41] = {0,}; - for(int i=0; i -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "stdio.h" - -#define BUF1 (uint8_t*)0x21000000 -#define TITLES (uint8_t*)0x22000000 - -#define PROGRESS_WIDTH 16 - -int nTicket = 0; -int nKey = 0; -int nullbyte = 0; - -int isEqual(uint8_t *tid1, uint8_t *tid2) { - for (int i = 0; i < 8; i++) { - if (tid1[i] != tid2[i]) { return 0; } - } - return 1; -} - -int isAlreadyDumped(uint8_t *titleid) { - if (nKey == 0) { return 0; } - for (int i = 0; i < nKey; i++) { - uint8_t *stored = TITLES + 8 * i; - if (isEqual(stored, titleid)) { - return 1; - } - } - return 0; -} - -int DecryptTitleKey(uint8_t *titleid, uint8_t *key, uint32_t index) { - const size_t blockSize = 16; - static struct { - uint8_t key[blockSize]; - uint32_t pad; - } *keyYList = NULL; - uint8_t ctr[blockSize] __attribute__((aligned(32))); - uint8_t keyY[blockSize] __attribute__((aligned(32))); - uint8_t titleId[8] __attribute__((aligned(32))); - uintptr_t p; - - memcpy(titleId, titleid, 8); - memset(ctr, 0, blockSize); - memcpy(ctr, titleId, 8); - set_ctr(AES_BIG_INPUT | AES_NORMAL_INPUT, ctr); - - if (keyYList == NULL) { - p = 0x08080000; - while (((uint8_t *)p)[0] != 0xD0 || ((uint8_t *)p)[1] != 0x7B) { - p++; - if (p >= 0x080A0000) - return 1; - } - - keyYList = (void *)p; - } - - memcpy(keyY, keyYList[index].key, sizeof(keyY)); - setup_aeskey(0x3D, AES_BIG_INPUT | AES_NORMAL_INPUT, keyY); - use_aeskey(0x3D); - aes_decrypt(key, key, ctr, 1, AES_CBC_DECRYPT_MODE); - return 0; -} - -void DecryptTitleKeys() { - ConsoleInit(); - ConsoleSetTitle(strings[STR_DECRYPT], strings[STR_TITLE_KEYS]); - File tick; - File dump; - const TCHAR *filename=_T("rxTools/decTitleKeys.bin"); - print(strings[STR_OPENING], "ticket.db"); - FileOpen(&dump, filename, 1); - uint32_t tick_size = 0xD0000; //Chunk size - nKey = 0; int nullbyte = 0; - if (FileOpen(&tick, _T("1:dbs/ticket.db"), 0)) { - print(strings[STR_DECRYPTING], strings[STR_TITLE_KEYS], filename); - ConsoleShow(); - uint8_t *buf = BUF1; - int pos = 0; - for (;;) { - int rb = FileRead(&tick, buf, tick_size, pos); - if (rb == 0) { break; } /* error or eof */ - pos += rb; - for (int j = 0; j < tick_size; j++) { - if (!strcmp((char *)buf + j, "Root-CA00000003-XS0000000c")) { - uint8_t *titleid = buf + j + 0x9C; - uint32_t kindex = *(buf + j + 0xB1); - uint8_t Key[16]; memcpy(Key, BUF1 + j + 0x7F, 16); - if (!isAlreadyDumped(titleid)) { - memcpy(TITLES + nKey * 8, titleid, 8); - FileWrite(&dump, &kindex, 4, 0x10 + nKey * 0x20); - FileWrite(&dump, &nullbyte, 4, 0x10 + nKey * 0x20 + 4); - FileWrite(&dump, titleid, 8, 0x10 + nKey * 0x20 + 8); - DecryptTitleKey(titleid, Key, kindex); - FileWrite(&dump, Key, 16, 0x10 + nKey * 0x20 + 16); - nKey++; - } - } - } - } - FileClose(&dump); - FileClose(&tick); - } else { - print(strings[STR_FAILED]); - } - FileWrite(&dump, &nKey, 4, 0); - FileWrite(&dump, &nullbyte, 4, 4); - FileWrite(&dump, &nullbyte, 4, 8); - FileWrite(&dump, &nullbyte, 4, 12); - FileClose(&dump); - print(strings[STR_PRESS_BUTTON_ACTION], strings[STR_BUTTON_A], strings[STR_CONTINUE]); - ConsoleShow(); - WaitForButton(BUTTON_A); -} - -/** This decrypts the encTitleKeys.bin inside RxTools directory on SD. */ -void DecryptTitleKeyFile(void) { - ConsoleInit(); - ConsoleSetTitle(strings[STR_DECRYPT], strings[STR_TITLE_KEYS_FILE]); - FIL tick, dump; - FRESULT rr = 0; - UINT br = 0; - const TCHAR *filename = _T("rxTools/encTitleKeys.bin"); - const TCHAR *filename2 = _T("rxTools/decTitleKeys.bin"); - const TCHAR *filename3 = _T("rxTools/decTitleKeysA.bin"); - print(strings[STR_OPENING], filename); - ConsoleShow(); - //decTitleKeys.bin that generated from other stuff can be handled streamly. - FileOpen(&dump, filename2, 1); - rr = f_open(&dump, filename3, FA_WRITE | FA_CREATE_ALWAYS); - if (rr != FR_OK) { - f_close(&dump); - print(strings[STR_ERROR_OPENING], filename3); - print(strings[STR_PRESS_BUTTON_ACTION], strings[STR_BUTTON_A], strings[STR_CONTINUE]); - ConsoleShow(); - WaitForButton(BUTTON_A); - return; - } - rr = f_open(&tick, filename, FA_READ | FA_OPEN_EXISTING); - if (rr != FR_OK) { - f_close(&tick); f_close(&dump); - print(strings[STR_ERROR_OPENING], filename); - print(strings[STR_PRESS_BUTTON_ACTION], strings[STR_BUTTON_A], strings[STR_CONTINUE]); - ConsoleShow(); - WaitForButton(BUTTON_A); - return; - } - - uint32_t line[4] = {0,}; - uint32_t keycount = 0, i = 0; - uint32_t kindex = 0, nkeys = 0; - uint8_t titleid[8] = {0,}; - uint8_t key[16] = {0,}; - wchar_t progressbar[41] = {0,}; - wchar_t* progress = progressbar; - for(i=0; i> 24) & 0xff) | ((low << 8) & 0xff0000) | ((low >> 8) & 0xff00) | ((low << 24) & 0xff000000); - uint32_t tid_high = ((high >> 24) & 0xff) | ((high << 8) & 0xff0000) | ((high >> 8) & 0xff00) | ((high << 24) & 0xff000000); - uint32_t tick_size = 0x200; //Chunk size - - wchar_t path[_MAX_LFN] = {0}; - int r; - - swprintf(path, _MAX_LFN, L"%d:dbs/ticket.db", drive); - - if (FileOpen(&tick, path, 0)) { - uint8_t *buf = TITLES; - int pos = 0; - for (;;) { - int rb = FileRead(&tick, buf, tick_size, pos); - if (rb == 0) { break; } /* error or eof */ - pos += rb; - if (buf[0] == 'T' && buf[1] == 'I' && buf[2] == 'C' && buf[3] == 'K') { - tick_size = 0xD0000; - continue; - } - for (int j = 0; j < tick_size; j++) { - if (!strcmp((char *)buf + j, "Root-CA00000003-XS0000000c")) { - uint8_t *titleid = buf + j + 0x9C; - uint32_t kindex = *(buf + j + 0xB1); - uint8_t Key[16]; memcpy(Key, buf + j + 0x7F, 16); - if (*((uint32_t *)titleid) == tid_low && *((uint32_t *)(titleid + 4)) == tid_high) { - r = DecryptTitleKey(titleid, Key, kindex); - if (!r) - memcpy(TitleKey, Key, 16); - FileClose(&tick); - return r; - } - } - } - } - FileClose(&tick); - } - return 1; -} - -static FRESULT seekRead(FIL *fp, DWORD ofs, void *buff, UINT btr) -{ - FRESULT r; - UINT br; - - r = f_lseek(fp, ofs); - if (r != FR_OK) - return r; - - r = f_read(fp, buff, btr, &br); - return br < btr ? (r == FR_OK ? EOF : r) : FR_OK; -} - -#define CETK_MEMBER_SIZE(member) (sizeof(((TicketHdr *)NULL)->member)) -#define CETK_READ_MEMBER(fp, member, buff) \ - (seekRead((fp), 0x140 + offsetof(TicketHdr, member), buff, \ - CETK_MEMBER_SIZE(member))) - -int getTitleKeyWithCetk(uint8_t dst[16], const TCHAR *path) -{ - uint8_t id[CETK_MEMBER_SIZE(titleId)]; - uint8_t index; - FRESULT r; - FIL f; - - r = f_open(&f, path, FA_READ); - if (r != FR_OK) - return r; - - r = CETK_READ_MEMBER(&f, titleKey, dst); - if (r != FR_OK) { - f_close(&f); - return r; - } - - r = CETK_READ_MEMBER(&f, titleId, id); - if (r != FR_OK) { - f_close(&f); - return r; - } - - r = CETK_READ_MEMBER(&f, keyIndex, &index); - if (r != FR_OK) { - f_close(&f); - return r; - } - - f_close(&f); - return DecryptTitleKey(id, dst, index); -} diff --git a/rxtools/source/features/decryption.c b/rxtools/source/features/decryption.c new file mode 100644 index 00000000..fd3fead9 --- /dev/null +++ b/rxtools/source/features/decryption.c @@ -0,0 +1,284 @@ +/* + * Copyright (C) 2015 The PASTA Team + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "stdio.h" +#include +#include +#include +#include +#include + +#define TITLES (uint8_t*)0x22000000 +#define BUFFER_ADDR ((uint8_t*)0x21000000) +#define BLOCK_SIZE (8*1024*1024) + +char str[100]; + +int decryptFirmKtrArm9(void *p) +{ + uint8_t key[AES_BLOCK_SIZE]; + PartitionInfo info; + Arm9Hdr *hdr; + FirmSeg *seg, *btm; + + seg = ((FirmHdr *)p)->segs; + for (btm = seg + FIRM_SEG_NUM; seg->isArm11; seg++) + if (seg == btm) + return -1; + + hdr = (void *)(p + seg->offset); + + info.ctr = hdr->ctr; + info.buffer = (uint8_t *)hdr + 0x800; + info.keyY = hdr->keyY; + info.size = atoi(hdr->size); + + use_aeskey(0x11); + if (hdr->ext.pad[0] == 0xFFFFFFFF) { + info.keyslot = 0x15; + aes_decrypt(hdr->keyX, key, NULL, 1, AES_ECB_DECRYPT_MODE); + setup_aeskeyX(info.keyslot, key); + } else { + info.keyslot = 0x16; + aes_decrypt(hdr->ext.s.keyX_0x16, key, NULL, 1, AES_ECB_DECRYPT_MODE); + } + + return DecryptPartition(&info); +} + +uint8_t* decryptFirmTitleNcch(uint8_t* title, size_t *size) +{ + const size_t sector = 512; + const size_t header = 512; + ctr_ncchheader NCCH; + uint8_t CTR[16]; + PartitionInfo INFO; + NCCH = *((ctr_ncchheader*)title); + if(memcmp(NCCH.magic, "NCCH", 4) != 0) return NULL; + ncch_get_counter(NCCH, CTR, 2); + INFO.ctr = CTR; INFO.buffer = title + getle32(NCCH.exefsoffset)*sector; INFO.keyY = NCCH.signature; INFO.size = getle32(NCCH.exefssize)*sector; INFO.keyslot = 0x2C; + DecryptPartition(&INFO); + + if (size != NULL) + *size = INFO.size - header; + + uint8_t* firm = (uint8_t*)(INFO.buffer + header); + + if (getMpInfo() == MPINFO_KTR) + if (decryptFirmKtrArm9(firm)) + return NULL; + + return firm; +} + +uint8_t *decryptFirmTitle(uint8_t *title, size_t size, size_t *firmSize, uint8_t key[16]) +{ + aes_context aes_ctxt; + + uint8_t iv[16] = { 0 }; + aes_setkey_dec(&aes_ctxt, &key[0], 0x80); + aes_crypt_cbc(&aes_ctxt, AES_DECRYPT, size, iv, title, title); + return decryptFirmTitleNcch(title, firmSize); +} + +int DecryptTitleKey(uint8_t *titleid, uint8_t *key, uint32_t index) { + const size_t blockSize = 16; + static struct { + uint8_t key[blockSize]; + uint32_t pad; + } *keyYList = NULL; + uint8_t ctr[blockSize] __attribute__((aligned(32))); + uint8_t keyY[blockSize] __attribute__((aligned(32))); + uint8_t titleId[8] __attribute__((aligned(32))); + uintptr_t p; + + memcpy(titleId, titleid, 8); + memset(ctr, 0, blockSize); + memcpy(ctr, titleId, 8); + set_ctr(AES_BIG_INPUT | AES_NORMAL_INPUT, ctr); + + if (keyYList == NULL) { + p = 0x08080000; + while (((uint8_t *)p)[0] != 0xD0 || ((uint8_t *)p)[1] != 0x7B) { + p++; + if (p >= 0x080A0000) + return 1; + } + + keyYList = (void *)p; + } + + memcpy(keyY, keyYList[index].key, sizeof(keyY)); + setup_aeskey(0x3D, AES_BIG_INPUT | AES_NORMAL_INPUT, keyY); + use_aeskey(0x3D); + aes_decrypt(key, key, ctr, 1, AES_CBC_DECRYPT_MODE); + return 0; +} + + +int getTitleKey(uint8_t *TitleKey, uint32_t low, uint32_t high, int drive) { + File tick; + uint32_t tid_low = ((low >> 24) & 0xff) | ((low << 8) & 0xff0000) | ((low >> 8) & 0xff00) | ((low << 24) & 0xff000000); + uint32_t tid_high = ((high >> 24) & 0xff) | ((high << 8) & 0xff0000) | ((high >> 8) & 0xff00) | ((high << 24) & 0xff000000); + uint32_t tick_size = 0x200; //Chunk size + + wchar_t path[_MAX_LFN] = {0}; + int r; + + swprintf(path, _MAX_LFN, L"%d:dbs/ticket.db", drive); + + if (FileOpen(&tick, path, 0)) { + uint8_t *buf = TITLES; + int pos = 0; + for (;;) { + int rb = FileRead(&tick, buf, tick_size, pos); + if (rb == 0) { break; } /* error or eof */ + pos += rb; + if (buf[0] == 'T' && buf[1] == 'I' && buf[2] == 'C' && buf[3] == 'K') { + tick_size = 0xD0000; + continue; + } + for (int j = 0; j < tick_size; j++) { + if (!strcmp((char *)buf + j, "Root-CA00000003-XS0000000c")) { + uint8_t *titleid = buf + j + 0x9C; + uint32_t kindex = *(buf + j + 0xB1); + uint8_t Key[16]; memcpy(Key, buf + j + 0x7F, 16); + if (*((uint32_t *)titleid) == tid_low && *((uint32_t *)(titleid + 4)) == tid_high) { + r = DecryptTitleKey(titleid, Key, kindex); + if (!r) + memcpy(TitleKey, Key, 16); + FileClose(&tick); + return r; + } + } + } + } + FileClose(&tick); + } + return 1; +} + +static FRESULT seekRead(FIL *fp, DWORD ofs, void *buff, UINT btr) +{ + FRESULT r; + UINT br; + + r = f_lseek(fp, ofs); + if (r != FR_OK) + return r; + + r = f_read(fp, buff, btr, &br); + return br < btr ? (r == FR_OK ? EOF : r) : FR_OK; +} + +#define CETK_MEMBER_SIZE(member) (sizeof(((TicketHdr *)NULL)->member)) +#define CETK_READ_MEMBER(fp, member, buff) \ + (seekRead((fp), 0x140 + offsetof(TicketHdr, member), buff, \ + CETK_MEMBER_SIZE(member))) + +int getTitleKeyWithCetk(uint8_t dst[16], const TCHAR *path) +{ + uint8_t id[CETK_MEMBER_SIZE(titleId)]; + uint8_t index; + FRESULT r; + FIL f; + + r = f_open(&f, path, FA_READ); + if (r != FR_OK) + return r; + + r = CETK_READ_MEMBER(&f, titleKey, dst); + if (r != FR_OK) { + f_close(&f); + return r; + } + + r = CETK_READ_MEMBER(&f, titleId, id); + if (r != FR_OK) { + f_close(&f); + return r; + } + + r = CETK_READ_MEMBER(&f, keyIndex, &index); + if (r != FR_OK) { + f_close(&f); + return r; + } + + f_close(&f); + return DecryptTitleKey(id, dst, index); +} + +uint32_t DecryptPartition(PartitionInfo* info){ + if(info->keyY != NULL) + setup_aeskey(info->keyslot, AES_BIG_INPUT|AES_NORMAL_INPUT, info->keyY); + use_aeskey(info->keyslot); + + uint8_t ctr[16] __attribute__((aligned(32))); + memcpy(ctr, info->ctr, 16); + + uint32_t size_bytes = info->size; + for (uint32_t i = 0; i < size_bytes; i += BLOCK_SIZE) { + uint32_t j; + for (j = 0; (j < BLOCK_SIZE) && (i+j < size_bytes); j+= 16) { + set_ctr(AES_BIG_INPUT|AES_NORMAL_INPUT, ctr); + aes_decrypt((void*)info->buffer+j, (void*)info->buffer+j, ctr, 1, AES_CTR_MODE); + add_ctr(ctr, 1); + TryScreenShot(); //Putting it here allows us to take screenshots at any decryption point, since everyting loops in this + } + } + return 0; +} + +void ProcessExeFS(PartitionInfo* info){ //We expect Exefs to take just a block. Why? No exefs right now reached 8MB. + if(info->keyslot == 0x2C){ + DecryptPartition(info); + }else if(info->keyslot == 0x25){ //The new keyX is a bit tricky, 'couse only .code is encrypted with it + PartitionInfo myInfo; + memcpy((void*)&myInfo, (void*)info, sizeof(PartitionInfo)); + uint8_t OriginalCTR[16]; memcpy(OriginalCTR, info->ctr, 16); + myInfo.keyslot = 0x2C; myInfo.size = 0x200; + DecryptPartition(&myInfo); add_ctr(myInfo.ctr, 0x200 / 16); + if(myInfo.buffer[0] == '.' && myInfo.buffer[1] == 'c' && myInfo.buffer[2] == 'o' && myInfo.buffer[3] == 'd' && myInfo.buffer[4] == 'e'){ + //The 7.xKey encrypted .code partition + uint32_t codeSize = *((unsigned int*)(myInfo.buffer + 0x0C)); + uint32_t nextSection = *((unsigned int*)(myInfo.buffer + 0x18)) + 0x200; + myInfo.buffer += 0x200; myInfo.size = codeSize; myInfo.keyslot = 0x25; + DecryptPartition(&myInfo); + //The rest is normally encrypted + memcpy((void*)&myInfo, (void*)info, sizeof(PartitionInfo)); + myInfo.buffer += nextSection; myInfo.size -= nextSection; myInfo.keyslot = 0x2C; + myInfo.ctr = OriginalCTR; + add_ctr(myInfo.ctr, nextSection/16); + DecryptPartition(&myInfo); + }else{ + myInfo.size = info->size-0x200; + myInfo.buffer += 0x200; + DecryptPartition(&myInfo); + } + } +} \ No newline at end of file diff --git a/rxtools/source/features/downgradeapp.c b/rxtools/source/features/downgradeapp.c deleted file mode 100644 index 7777417b..00000000 --- a/rxtools/source/features/downgradeapp.c +++ /dev/null @@ -1,774 +0,0 @@ -/* - * Copyright (C) 2015 The PASTA Team - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "stdio.h" - -#define bswap_16(a) ((((a) << 8) & 0xff00) | (((a) >> 8) & 0xff)) -#define bswap_32(a) ((((a) << 24) & 0xff000000) | (((a) << 8) & 0xff0000) | (((a) >> 8) & 0xff00) | (((a) >> 24) & 0xff)) - -typedef struct { - uint32_t id; - uint16_t index; - uint16_t type; - uint64_t size; - uint8_t signature[0x20]; -} tmd_chunk_struct; - -unsigned char region = 0; - -wchar_t tmpstr[_MAX_LFN]; -FILINFO curInfo; -DIR myDir; - -wchar_t sprint_sha256_char(char val) { - if (val < 10) return val + L'0'; - else return val - 10 + L'A'; -} -void sprint_sha256(wchar_t *str, unsigned char hash[32]) { - uint32_t i=0; - for (i=0;i<32;i++) { - if ((i)&&((i%8)==0)) {*str = L'\n'; str ++;} - *str = sprint_sha256_char(hash[i]>> 4); str ++; - *str = sprint_sha256_char(hash[i]&0xF); str ++; - } -} - - -int FindApp(AppInfo *info) -{ - wchar_t *folder = tmpstr; - - DIR* curDir = &myDir; - memset((unsigned char*)curDir, 0, sizeof(DIR)); - - FILINFO *myInfo = &curInfo; - memset((unsigned char*)myInfo, 0, sizeof(FILINFO)); - myInfo->fname[0] = 'A'; - - swprintf(folder, _MAX_LFN, L"%d:title/%08" PRIx32 "/%08" PRIx32 "/content", - info->drive, info->tidHi, info->tidLo); - - if (f_opendir(curDir, folder) != FR_OK) return 0; - - wchar_t path[_MAX_LFN]; - unsigned short latest_ver = 0, cur_ver = 0; - bool is_v0 = false; - - while (f_readdir(curDir, myInfo) == FR_OK) - { - if (myInfo->fname[0] == 0) - break; - - if (myInfo->fname[0] == '.') continue; - - if (wcsstr(myInfo->fname, L".tmd") || wcsstr(myInfo->fname, L".TMD")) - { - swprintf(path, _MAX_LFN, L"%ls/%ls", folder, myInfo->fname); - - File tmp; - if (!FileOpen(&tmp, path, 0)) continue; - - unsigned int size = FileGetSize(&tmp); - if (size < 0xB34) - { - FileClose(&tmp); - continue; - } - - /* Get the TMD version */ - /* There can be some instances in which more than one TMD/content file is available */ - /* Of course, we want to use the latest one */ - if (FileRead(&tmp, &cur_ver, 2, 0x1DC) != 2) - { - FileClose(&tmp); - continue; - } - - /* Change Endianness */ - cur_ver = bswap_16(cur_ver); - - /* Verify the version number */ - if ((latest_ver == 0 && !is_v0) || cur_ver > latest_ver) - { - tmd_chunk_struct tmd_entry; - memset(&tmd_entry, 0xFF, 0x30); - - int cont = 0; - unsigned int b_read = 0; - while (tmd_entry.index != 0) - { - cont++; - b_read = FileRead(&tmp, &tmd_entry, 0x30, size - (cont * 0x30)); - if (b_read != 0x30) break; - } - - FileClose(&tmp); - - if (b_read != 0x30) continue; - - swprintf(path, _MAX_LFN, L"%ls/%08x.app", folder, bswap_32(tmd_entry.id)); // Change Endianness - - if (FileOpen(&tmp, path, 0)) - { - FileClose(&tmp); - latest_ver = cur_ver; - if (cur_ver == 0) is_v0 = true; - - /* Save TMD and content paths */ - swprintf(info->tmd, _MAX_LFN, L"%ls/%ls", folder, myInfo->fname); - swprintf(info->content, _MAX_LFN, L"%ls/%08x.app", folder, bswap_32(tmd_entry.id)); - } - } else { - FileClose(&tmp); - } - } else { - continue; - } - } - - f_closedir(curDir); - if (latest_ver == 0 && !is_v0) return 0; - return 1; -} - -int CheckRegion(int drive) -{ - File secureinfo; - const wchar_t *filename=L"SecureInfo_A"; - swprintf(tmpstr, _MAX_LFN, L"%d:rw/sys/%ls", drive, filename); - print(strings[STR_OPENING], filename); - ConsoleShow(); - if (!FileOpen(&secureinfo, tmpstr, 0)) - { - filename=L"SecureInfo_B"; - swprintf(tmpstr, _MAX_LFN, L"%d:rw/sys/SecureInfo_B", drive); - print(strings[STR_FAILED]); - print(strings[STR_OPENING], filename); - ConsoleShow(); - if (!FileOpen(&secureinfo, tmpstr, 0)) - { - print(strings[STR_FAILED]); - ConsoleShow(); - return -1; - } - } - - ConsoleFlush(); - print(strings[STR_COMPLETED]); - ConsoleShow(); - FileRead(&secureinfo, ®ion, 1, 0x100); - FileClose(&secureinfo); - - if (region > 0x06) - { - print(strings[STR_WRONG], L"", strings[STR_REGION]); - ConsoleShow(); - return -1; - } else { - /* Avoid problems with the unused "AUS" region code */ - if (region >= 3) region--; - print(strings[STR_REGION_], strings[STR_JAPAN+region]); - ConsoleShow(); - } - - return 0; -} - -int CheckRegionSilent(int drive) -{ - File secureinfo; - swprintf(tmpstr, _MAX_LFN, L"%d:rw/sys/SecureInfo_A", drive); - if (!FileOpen(&secureinfo, tmpstr, 0)) - { - memset(&tmpstr, 0, 256); - swprintf(tmpstr, _MAX_LFN, L"%d:rw/sys/SecureInfo_B", drive); - if (!FileOpen(&secureinfo, tmpstr, 0)) - { - print(strings[STR_ERROR_OPENING], tmpstr); - ConsoleShow(); - return -1; - } - } - - FileRead(&secureinfo, ®ion, 1, 0x100); - FileClose(&secureinfo); - - if (region > 0x06) - { - print(strings[STR_WRONG], L"", strings[STR_REGION]); - ConsoleShow(); - return -1; - } else { - /* Avoid problems with the unused "AUS" region code */ - if (region >= 3) region--; - } - - return 0; -} - -static unsigned int HashGen(unsigned char* file, unsigned int size) -{ - unsigned tbl[256]; - unsigned crc; - for (unsigned i = 0; i < 256; i++) - { - crc = i << 24; - for (unsigned j = 8; j > 0; j--) - { - if (crc & 0x80000000) - crc = (crc << 1) ^ 0x04c11db7; - else - crc = (crc << 1); - tbl[i] = crc; - } - } - crc = 0; - for (unsigned i = 0; i < size; i++) - crc = (crc << 8) ^ tbl[((crc >> 24) ^ *file++) & 0xFF]; - for (; size; size >>= 8) - crc = (crc << 8) ^ tbl[((crc >> 24) ^ size) & 0xFF]; - return ~crc; -} - -int checkDgFile(TCHAR* path, unsigned int hash) -{ - unsigned char* buf = (unsigned char*)0x21000000; - unsigned int rb, fixedsize = 0x00400000; - - File fp; - if (FileOpen(&fp, path, 0)) - { - rb = FileRead(&fp, buf, fixedsize, 0); - FileClose(&fp); - if (HashGen(buf, rb) != hash) return 0; - } else { - return 0; - } - - return 1; -} - -void downgradeMSET() -{ - File dg; - TCHAR *dgpath = _T("0:msetdg.bin"); - unsigned int titleid_low[6] = { 0x00020000, 0x00021000, 0x00022000, 0x00026000, 0x00027000, 0x00028000 }; //JPN, USA, EUR, CHN, KOR, TWN - unsigned int mset_hash[10] = { 0x96AEC379, 0xED315608, 0x3387F2CD, 0xEDAC05D7, 0xACC1BE62, 0xF0FF9F08, 0x565BCF20, 0xA04654C6, 0x2164C3C0, 0xD40B12F4 }; //JPN, USA, EUR, CHN, KOR, TWN - unsigned short mset_ver[10] = { 3074, 5127, 3078, 5128, 3075, 5127, 8, 1026, 2049, 8 }; - unsigned short mset_dg_ver = 0; - unsigned int checkLoop = 0; - AppInfo info; - - ConsoleInit(); - ConsoleSetTitle(strings[STR_DOWNGRADE], strings[STR_MSET]); - - CheckRegionSilent(SYS_NAND); - - print(strings[STR_CHOOSE], strings[STR_MSET]); - print(strings[STR_BLANK_BUTTON_ACTION], strings[STR_BUTTON_X], strings[STR_MSET4]); - if( region != 3 && region != 5 ) - { - print(strings[STR_BLANK_BUTTON_ACTION], strings[STR_BUTTON_Y], strings[STR_MSET6]); - } - print(strings[STR_BLANK_BUTTON_ACTION], strings[STR_BUTTON_B], strings[STR_CANCEL]); - ConsoleShow(); - - while( checkLoop < 1 ) - { - uint32_t pad_state = InputWait(); - if ((pad_state & BUTTON_X)) - { - switch(region){ - case 0: - mset_dg_ver = 0; - break; - case 1: - mset_dg_ver = 2; - break; - case 2: - mset_dg_ver = 4; - break; - case 3: - mset_dg_ver = 6; - break; - case 4: - mset_dg_ver = 7; - break; - case 5: - mset_dg_ver = 9; - break; - } - checkLoop = 1; - } - else if ((pad_state & BUTTON_Y) && region != 3 && region != 5) - { - switch(region){ - case 0: - mset_dg_ver = 1; - break; - case 1: - mset_dg_ver = 3; - break; - case 2: - mset_dg_ver = 5; - break; - case 4: - mset_dg_ver = 8; - break; - } - checkLoop = 1; - } - else if (pad_state & BUTTON_B) - { - checkLoop = 1; - return; - } - } - if( mset_dg_ver == 0 ) - { - print(strings[STR_WRONG], L"", strings[STR_REGION]); - } - ConsoleShow(); - - print(strings[STR_PROCESSING], strings[STR_MSET]); - ConsoleShow(); - - if (CheckRegion(SYS_NAND) == 0) - { - info.drive = SYS_NAND; - info.tidLo = titleid_low[region]; - info.tidHi = 0x00040010; - if (FindApp(&info)) // SysNAND only - { - if (FileOpen(&dg, info.tmd, 0)) - { - /* Get the MSET TMD version */ - unsigned short tmd_ver; - FileRead(&dg, &tmd_ver, 2, 0x1DC); - tmd_ver = bswap_16(tmd_ver); - FileClose(&dg); - - /* Verify version number */ - if (tmd_ver != mset_ver[mset_dg_ver]) - { - /* Open MSET content file */ - if (FileOpen(&dg, info.content, 0)) - { - unsigned int check_val; - FileRead(&dg, &check_val, 4, 0x130); - FileClose(&dg); - - if (check_val != 0) - { - if (checkDgFile(dgpath, mset_hash[mset_dg_ver])) - { - print(strings[STR_PROCESSING], strings[STR_DOWNGRADE_PACK]); - ConsoleShow(); - if (FileOpen(&dg, dgpath, 0)) - { - unsigned int dgsize = FileGetSize(&dg); - unsigned char *buf = (unsigned char*)0x21000000; - FileRead(&dg, buf, dgsize, 0); - - /* Downgrade pack decryption */ - uint8_t iv[0x10] = {0}; - uint8_t Key[0x10] = {0}; - - getTitleKey(&Key[0], info.tidHi, info.tidLo, info.drive); - - aes_context aes_ctxt; - aes_setkey_dec(&aes_ctxt, Key, 0x80); - aes_crypt_cbc(&aes_ctxt, AES_DECRYPT, dgsize, iv, buf, buf); - - FileWrite(&dg, buf, dgsize, 0); - FileClose(&dg); - - if (*((unsigned int*)(buf + 0x100)) == 0x4843434E) // "NCCH" magic word - { - print(strings[STR_DOWNGRADING], L""); - ConsoleShow(); - if (FSFileCopy(info.content, dgpath) != 0) - { - print(strings[STR_FAILED]); - } - print(strings[STR_DELETING], dgpath); - ConsoleShow(); - f_unlink(dgpath); - } else { - print(strings[STR_WRONG], L"", strings[STR_DOWNGRADE_PACK]); - } - } else { - print(strings[STR_ERROR_OPENING], dgpath); - } - } else { - print(strings[STR_WRONG], L"", strings[STR_DOWNGRADE_PACK]); - } - } else { - print(strings[STR_DOWNGRADING_NOT_NEEDED], strings[STR_MSET]); - } - } else { - print(strings[STR_ERROR_OPENING], info.content); - } - } else { - print(strings[STR_DOWNGRADING_NOT_NEEDED], strings[STR_MSET]); - } - } else { - print(strings[STR_ERROR_OPENING], info.tmd); - } - } else { - print(strings[STR_MISSING], strings[STR_MSET]); - } - } - - print(strings[STR_BLANK_BUTTON_ACTION], strings[STR_BUTTON_A], strings[STR_CONTINUE]); - ConsoleShow(); - WaitForButton(BUTTON_A); -} - -void manageFBI(bool restore) -{ - unsigned int titleid_low[6] = { 0x00020300, 0x00021300, 0x00022300, 0x00026300, 0x00027300, 0x00028300 }; //JPN, USA, EUR, CHN, KOR, TWN - wchar_t *backup_path = L"rxTools/h&s_backup"; - wchar_t *fbi = L"FBI"; - - File tmp; - wchar_t path[_MAX_LFN] = {0}; - wchar_t path2[_MAX_LFN] = {0}; - wchar_t wtmp[67]; - unsigned char *buf = (unsigned char *)0x21000000; - - unsigned int size; - unsigned short tmd_ver; - unsigned int sd_cntsize; - unsigned short sd_tmd_ver; - - unsigned char TmdCntInfoRecSum[32] = {0}; - unsigned char CntInfoRecSum[32] = {0}; - unsigned char TmdCntChnkRecSum[32] = {0}; - unsigned char CntChnkRecSum[32] = {0}; - unsigned char TmdCntDataSum[32] = {0}; - unsigned char CntDataSum[32] = {0}; - - unsigned short checkLoop; - bool noHalt = true; - - AppInfo info; - - info.drive = NandSwitch(); - if (info.drive == UNK_NAND) - return; - - info.tidHi = 0x00040010; - - ConsoleInit(); - if (restore) - { - ConsoleSetTitle(strings[STR_RESTORE], strings[STR_HEALTH_AND_SAFETY]); - ConsoleShow(); - } - else - { - ConsoleSetTitle(strings[STR_INJECT], strings[STR_FBI]); - print(strings[STR_CHOOSE], ""); - print(strings[STR_BLANK_BUTTON_ACTION], strings[STR_BUTTON_B], strings[STR_CHECK_TMD_ONLY]); - print(strings[STR_BLANK_BUTTON_ACTION], strings[STR_BUTTON_Y], strings[STR_INJECT_FBI]); - ConsoleShow(); - checkLoop = 0; - - while(checkLoop < 1) - { - uint32_t pad_state = InputWait(); - if (pad_state & BUTTON_Y) - { - noHalt = true; - checkLoop = 1; - } - else if (pad_state & BUTTON_B) - { - noHalt = false; - checkLoop = 1; - - CheckRegion(info.drive); - - info.tidLo = titleid_low[region]; - if (FindApp(&info)) - { - /* Open the NAND H&S TMD */ - FileOpen(&tmp, info.tmd, 0); - FileRead(&tmp, buf, 0xB34, 0); - FileClose(&tmp); - - /* Get the title version from the TMD */ - tmd_ver = (unsigned short)((buf[0x1DC] << 8) | buf[0x1DD]); - print(strings[STR_VERSION_OF], strings[STR_TMD], tmd_ver); - } - } - } - } - - if(noHalt) - { - - if (CheckRegion(info.drive) == 0) - { - info.tidLo = titleid_low[region]; - if (FindApp(&info)) - { - /* Open the NAND H&S TMD */ - FileOpen(&tmp, info.tmd, 0); - FileRead(&tmp, buf, 0xB34, 0); - FileClose(&tmp); - - /* Get the title version from the TMD */ - tmd_ver = (unsigned short)((buf[0x1DC] << 8) | buf[0x1DD]); - print(strings[STR_VERSION_OF], strings[STR_TMD], tmd_ver); - ConsoleShow(); - - if (!restore) - { - /* Get the stored content size from the TMD */ - unsigned int cntsize = (unsigned int)((buf[0xB10] << 24) | (buf[0xB11] << 16) | (buf[0xB12] << 8) | buf[0xB13]); - - /* Open the NAND H&S content file and read it to the memory buffer */ - FileOpen(&tmp, info.content, 0); - FileRead(&tmp, buf + 0x1000, cntsize, 0); - FileClose(&tmp); - - /* Create the Health & Safety data backup directory */ - f_mkdir(backup_path); - - memset(&tmpstr, 0, 256); - swprintf(tmpstr, _MAX_LFN, L"%ls/%ls", backup_path, strings[STR_JAPAN+region]); - f_mkdir(tmpstr); - - memset(&tmpstr, 0, 256); - swprintf(tmpstr, _MAX_LFN, L"%ls/%ls/v%u", backup_path, strings[STR_JAPAN+region], tmd_ver); - f_mkdir(tmpstr); - - /* Backup the H&S TMD */ - ConsoleFlush(); - print(strings[STR_BACKING_UP], strings[STR_HEALTH_AND_SAFETY]); - ConsoleShow(); - swprintf(path, _MAX_LFN, L"0:%ls/%.12ls", tmpstr, info.tmd+34); - if (FileOpen(&tmp, path, 1)) - { - size = FileWrite(&tmp, buf, 0xB34, 0); - FileClose(&tmp); - if (size == 0xB34) - { - /* Backup the H&S content file */ - memset(&path, 0, 256); - swprintf(path, _MAX_LFN, L"0:%ls/%.12ls", tmpstr, info.content+34); - if (FileOpen(&tmp, path, 1)) - { - size = FileWrite(&tmp, buf + 0x1000, cntsize, 0); - FileClose(&tmp); - if (size != cntsize) - { - print(strings[STR_ERROR_WRITING], path); - goto out; - } - } else { - print(strings[STR_ERROR_CREATING], path); - goto out; - } - } else { - print(strings[STR_ERROR_WRITING], path); - goto out; - } - } else { - print(strings[STR_ERROR_CREATING], path); - goto out; - } - - /* Generate the FBI data paths */ - swprintf(path, _MAX_LFN, L"0:fbi_inject.tmd"); - swprintf(path2, _MAX_LFN, L"0:fbi_inject.app"); - - print(strings[STR_INJECTING], fbi, strings[STR_HEALTH_AND_SAFETY]); - } else { - /* Generate the H&S backup data paths */ - memset(&tmpstr, 0, 256); - swprintf(tmpstr, _MAX_LFN, L"%ls/%ls/v%u", - backup_path, - strings[STR_JAPAN+region], - tmd_ver); - swprintf(path, _MAX_LFN, L"0:%ls/%.12ls", - tmpstr, info.tmd+34); - swprintf(path2, _MAX_LFN, L"0:%ls/%.12ls", - tmpstr, info.content+34); - - print(strings[STR_RESTORING], strings[STR_HEALTH_AND_SAFETY]); - } - ConsoleShow(); - - /* Open the SD TMD */ - if (FileOpen(&tmp, path, 0)) - { - size = FileGetSize(&tmp); - if (size == 0xB34) - { - FileRead(&tmp, buf, 0xB34, 0); - FileClose(&tmp); - - /* Get the SD TMD version and stored content size */ - sd_tmd_ver = (unsigned short)((buf[0x1DC] << 8) | buf[0x1DD]); - sd_cntsize = (unsigned int)((buf[0xB10] << 24) | (buf[0xB11] << 16) | (buf[0xB12] << 8) | buf[0xB13]); - - if (sd_tmd_ver == tmd_ver) - { - /* Get the SHA-256 hashes */ - memcpy(TmdCntInfoRecSum, buf + 0x1E4, 32); - memcpy(TmdCntChnkRecSum, buf + 0x208, 32); - memcpy(TmdCntDataSum, buf + 0xB14, 32); - - /* Verify the Content Info Record hash */ - sha2(buf + 0x204, 0x900, CntInfoRecSum, 0); - if (memcmp(CntInfoRecSum, TmdCntInfoRecSum, 32) == 0) - { - /* Verify the Content Chunk Record hash */ - sha2(buf + 0xB04, 0x30, CntChnkRecSum, 0); - if (memcmp(CntChnkRecSum, TmdCntChnkRecSum, 32) == 0) - { - /* Open the SD content file */ - if (FileOpen(&tmp, path2, 0)) - { - size = FileGetSize(&tmp); - if (size == sd_cntsize) - { - FileRead(&tmp, buf + 0x1000, sd_cntsize, 0); - FileClose(&tmp); - - /* Verify the Content Data hash */ - sha2(buf + 0x1000, sd_cntsize, CntDataSum, 0); - if (memcmp(CntDataSum, TmdCntDataSum, 32) == 0) - { - /* Now we are ready to rock 'n roll */ - if (FSFileCopy(info.tmd, path) == 0) - { - if (FSFileCopy(info.content, path2) == 0) - { - print(strings[STR_CHOOSE], strings[STR_SOURCE_ACTION]); - print(strings[STR_BLANK_BUTTON_ACTION], strings[STR_BUTTON_B], strings[STR_KEEP]); - print(strings[STR_BLANK_BUTTON_ACTION], strings[STR_BUTTON_X], strings[STR_DELETE]); - ConsoleShow(); - checkLoop = 0; - - while (checkLoop < 1) - { - uint32_t pad_state = InputWait(); - if (pad_state & BUTTON_B) - { - checkLoop = 1; - } - else if (pad_state & BUTTON_X) - { - print(strings[STR_DELETING], path); - ConsoleShow(); - f_unlink(path); - print(strings[STR_DELETING], path2); - ConsoleShow(); - f_unlink(path2); - checkLoop = 1; - } - } - } else { - print(strings[STR_ERROR_COPYING], path2, info.content); - } - } else { - print(strings[STR_ERROR_COPYING], path, info.tmd); - } - } else { - print(strings[STR_WRONG], L"", strings[STR_HASH]); - sprint_sha256(wtmp, CntDataSum); - print(strings[STR_GOT], wtmp); - sprint_sha256(wtmp, TmdCntDataSum); - print(strings[STR_EXPECTED], wtmp); - } - } else { - FileClose(&tmp); - print(strings[STR_WRONG], L"", strings[STR_SIZE]); - swprintf(wtmp, sizeof(wtmp)/sizeof(wtmp[0]), L"%u", size); - print(strings[STR_GOT], wtmp); - swprintf(wtmp, sizeof(wtmp)/sizeof(wtmp[0]), L"%u", sd_cntsize); - print(strings[STR_EXPECTED], wtmp); - } - } else { - print(strings[STR_ERROR_OPENING], path2); - } - } else { - print(strings[STR_WRONG], L"", strings[STR_HASH]); - sprint_sha256(wtmp, CntChnkRecSum); - print(strings[STR_GOT], wtmp); - sprint_sha256(wtmp, TmdCntChnkRecSum); - print(strings[STR_EXPECTED], wtmp); - } - } else { - print(strings[STR_WRONG], L"", strings[STR_HASH]); - sprint_sha256(wtmp, CntInfoRecSum); - print(strings[STR_GOT], wtmp); - sprint_sha256(wtmp, TmdCntInfoRecSum); - print(strings[STR_EXPECTED], wtmp); - } - } else { - print(strings[STR_WRONG], L"", strings[STR_TMD_VERSION]); - } - } else { - FileClose(&tmp); - print(strings[STR_WRONG], L"", strings[STR_TMD_SIZE]); - } - } else { - print(strings[STR_ERROR_OPENING], path); - } - } else { - print(strings[STR_MISSING], strings[STR_HEALTH_AND_SAFETY]); - } - } - } -out: - print(strings[STR_BLANK_BUTTON_ACTION], strings[STR_BUTTON_A], strings[STR_CONTINUE]); - ConsoleShow(); - WaitForButton(BUTTON_A); -} - -void installFBI() -{ - /* Injects FBI TMD and content file to the Health & Safety App */ - manageFBI(false); -} - -void restoreHS() -{ - /* Restores original Health & Safety TMD and content file to the NAND */ - manageFBI(true); -} diff --git a/rxtools/source/features/fileexplorer.c b/rxtools/source/features/fileexplorer.c deleted file mode 100644 index 352bf5e6..00000000 --- a/rxtools/source/features/fileexplorer.c +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Copyright (C) 2015 The PASTA Team - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -//---- GLOBAL VARIABLES ---- -int pointer = 0; -TCHAR **files; -size_t count; -int i; -int beginning = 0; -TCHAR dir[1000] = L"/"; -int opened_folder = 0; - - -size_t file_list(const TCHAR *path, TCHAR ***ls) { - size_t count = 0; - DIR myDir; - FILINFO curInfo; - memset(&myDir, 0, sizeof(DIR)); - memset(&curInfo, 0, sizeof(FILINFO)); - FILINFO *myInfo = &curInfo; - - int res=f_opendir(&myDir, dir); - if (res == FR_NO_FILE) { - print(strings[STR_ERROR_OPENING], path); - return 0; - } - *ls = NULL; - *ls = calloc(1000, sizeof(char *)); - count = 0; - f_readdir(&myDir, myInfo); - - while (!myInfo->fname[0] == 0) - { - (*ls)[count++] = wcsdup(myInfo->fname); - f_readdir(&myDir, myInfo); - } - - f_closedir(&myDir); - return count; -} - -void FileExplorerShow(){ - ConsoleInit(); - ConsoleSetTitle(strings[STR_DIRECTORY], dir); - if (count != 0) - { - int n = 0; - int divisions = count % 7 == 0 ? count / 7 : count / 7 + 1; - int list[divisions]; - for (n = 0; n= 0; u--) - { - if (dir[u] == '/') { - if(opened_folder==1) dir[u + 1] = '\0'; - else dir[u] = '\0'; - break; - } - } - beginning = 0; - pointer = 0; - opened_folder--; - count = file_list(dir, &files); - } -} - -/* This writes the path to p if it is a file. -It returns written bytes to p if it succeeded in opening file or directory. -Otherwise it returns a negative value */ -int FileExplorerSelect(TCHAR *p, size_t n){ - //enter file/folder - int u; - int isafile = 0; - for (u = 0; u < wcslen(files[pointer]); u++) - { - if (files[pointer][u] == '.') isafile = 1; - } - if (isafile){ - //Open file - return swprintf(p, n, L"%ls%ls%ls", dir, - opened_folder == 0 ? L"" : L"/", files[pointer]) > n ? - -1 : n; - } - else - { - //enter folder - if (opened_folder != 0) wcscat(dir, L"/"); - wcscat(dir, files[pointer]); - beginning = 0; - pointer = 0; - opened_folder++; - count = file_list(dir, &files); - } - return 0; -} - -/*File explorer main code -Can be called from where you want and returns the selected file! -*/ - -int FileExplorerMain(TCHAR *p, size_t n){ - count = file_list(dir, &files); - while (true) - { - FileExplorerShow(); - - uint32_t pad_state = InputWait(); - if (pad_state & BUTTON_DOWN) FileExplorerNextSelection(); - else if (pad_state & BUTTON_UP) FileExplorerPrevSelection(); - else if (pad_state & BUTTON_A) - { - if (FileExplorerSelect(p, n) > 0)return 0; - } - else if (pad_state & BUTTON_B) - { - if (opened_folder == 0)return -1; - else FileExplorerBack(); - } - - if (pointer - beginning == 7)beginning += 7; - if (pointer #include #include -#include -#include -#include -#include +#include #include const wchar_t firmPathFmt[] = _T("") FIRM_PATH_FMT; const wchar_t firmPatchPathFmt[] = _T("") FIRM_PATCH_PATH_FMT; -unsigned int emuNandMounted = 0; _Noreturn void (* const _softreset)() = (void *)0x080F0000; static FRESULT loadExecReboot() @@ -80,73 +76,6 @@ static int loadFirm(TCHAR *path, UINT *fsz) return ((FirmHdr *)FIRM_ADDR)->magic == 0x4D524946 ? 0 : -1; } -static int decryptFirmKtrArm9(void *p) -{ - uint8_t key[AES_BLOCK_SIZE]; - PartitionInfo info; - Arm9Hdr *hdr; - FirmSeg *seg, *btm; - - seg = ((FirmHdr *)p)->segs; - for (btm = seg + FIRM_SEG_NUM; seg->isArm11; seg++) - if (seg == btm) - return -1; - - hdr = (void *)(p + seg->offset); - - info.ctr = hdr->ctr; - info.buffer = (uint8_t *)hdr + 0x800; - info.keyY = hdr->keyY; - info.size = atoi(hdr->size); - - use_aeskey(0x11); - if (hdr->ext.pad[0] == 0xFFFFFFFF) { - info.keyslot = 0x15; - aes_decrypt(hdr->keyX, key, NULL, 1, AES_ECB_DECRYPT_MODE); - setup_aeskeyX(info.keyslot, key); - } else { - info.keyslot = 0x16; - aes_decrypt(hdr->ext.s.keyX_0x16, key, NULL, 1, AES_ECB_DECRYPT_MODE); - } - - return DecryptPartition(&info); -} - -uint8_t* decryptFirmTitleNcch(uint8_t* title, size_t *size) -{ - const size_t sector = 512; - const size_t header = 512; - ctr_ncchheader NCCH; - uint8_t CTR[16]; - PartitionInfo INFO; - NCCH = *((ctr_ncchheader*)title); - if(memcmp(NCCH.magic, "NCCH", 4) != 0) return NULL; - ncch_get_counter(NCCH, CTR, 2); - INFO.ctr = CTR; INFO.buffer = title + getle32(NCCH.exefsoffset)*sector; INFO.keyY = NCCH.signature; INFO.size = getle32(NCCH.exefssize)*sector; INFO.keyslot = 0x2C; - DecryptPartition(&INFO); - - if (size != NULL) - *size = INFO.size - header; - - uint8_t* firm = (uint8_t*)(INFO.buffer + header); - - if (getMpInfo() == MPINFO_KTR) - if (decryptFirmKtrArm9(firm)) - return NULL; - - return firm; -} - -uint8_t *decryptFirmTitle(uint8_t *title, size_t size, size_t *firmSize, uint8_t key[16]) -{ - aes_context aes_ctxt; - - uint8_t iv[16] = { 0 }; - aes_setkey_dec(&aes_ctxt, &key[0], 0x80); - aes_crypt_cbc(&aes_ctxt, AES_DECRYPT, size, iv, title, title); - return decryptFirmTitleNcch(title, firmSize); -} - static void setAgbBios() { File agb_firm; @@ -300,16 +229,6 @@ int rxMode(int emu) goto fail; } -void rxModeWithSplash(int emu) -{ - wchar_t s[_MAX_LFN]; - - swprintf(s, _MAX_LFN, L"/rxTools/Theme/%u/boot.bin", - cfgs[CFG_THEME].val.i); - DrawBottomSplash(s); - rxMode(emu); -} - //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);*/ @@ -348,29 +267,3 @@ int PastaMode(){ return loadExecReboot(); } - -void FirmLoader(TCHAR firm_path[]){ - - UINT fsz; - if (loadFirm(firm_path, &fsz)) - { - ConsoleInit(); - ConsoleSetTitle(strings[STR_LOAD], strings[STR_FIRMWARE_FILE]); - print(strings[STR_WRONG], L"", strings[STR_FIRMWARE_FILE]); - print(strings[STR_PRESS_BUTTON_ACTION], strings[STR_BUTTON_A], strings[STR_CONTINUE]); - ConsoleShow(); - WaitForButton(BUTTON_A); - return; - } - if (loadExecReboot()) - { - ConsoleInit(); - ConsoleSetTitle(strings[STR_LOAD], strings[STR_FIRMWARE_FILE]); - print(strings[STR_ERROR_LAUNCHING], strings[STR_FIRMWARE_FILE]); - print(strings[STR_PRESS_BUTTON_ACTION], strings[STR_BUTTON_A], strings[STR_CONTINUE]); - ConsoleShow(); - WaitForButton(BUTTON_A); - return; - } -} - diff --git a/rxtools/source/features/install.c b/rxtools/source/features/install.c index 01dca889..1318a09e 100644 --- a/rxtools/source/features/install.c +++ b/rxtools/source/features/install.c @@ -20,7 +20,7 @@ #include #include #include -#include +#include #include #include #include @@ -35,9 +35,7 @@ #include #include #include -#include #include "stdio.h" -#include #define DATA_PATH _T("rxtools/data") #define KEYFILENAME "slot0x25KeyX.bin" @@ -105,49 +103,6 @@ static int processFirmFile(uint32_t lo) return -1; } -static int processFirmInstalled(uint32_t lo) -{ - void *buff, *firm; - AppInfo appInfo; - UINT size; - FRESULT r; - FIL f; - - appInfo.drive = 1; - appInfo.tidLo = lo; - appInfo.tidHi = TID_HI_FIRM; - FindApp(&appInfo); - if (f_open(&f, appInfo.content, FA_READ) != FR_OK) { - appInfo.drive = 2; - FindApp(&appInfo); - r = f_open(&f, appInfo.content, FA_READ); - if (r != FR_OK) - return r; - } - - size = f_size(&f); - buff = __builtin_alloca(size); - - r = f_read(&f, buff, size, &size); - f_close(&f); - if (r != FR_OK) - return r; - - firm = decryptFirmTitleNcch(buff, &size); - return firm == NULL ? -1 : saveFirm(lo, firm, size); -} - -static int processFirm(uint32_t lo) -{ - int r; - - r = processFirmFile(lo); - if (r && processFirmInstalled(lo)) - return r; - - return 0; -} - typedef struct { wchar_t str[16]; wchar_t *cur; @@ -201,7 +156,7 @@ static int InstallData() f_mkdir(DATA_PATH); incBar(&b); - r = processFirm(getMpInfo() == MPINFO_CTR ? + r = processFirmFile(getMpInfo() == MPINFO_CTR ? TID_CTR_NATIVE_FIRM : TID_KTR_NATIVE_FIRM); if (r) return r; @@ -209,13 +164,13 @@ static int InstallData() incBar(&b); if (getMpInfo() == MPINFO_CTR) { - r = processFirm(TID_CTR_AGB_FIRM); + r = processFirmFile(TID_CTR_AGB_FIRM); if (r) return r; incBar(&b); - r = processFirm(TID_CTR_TWL_FIRM); + r = processFirmFile(TID_CTR_TWL_FIRM); if (r != FR_OK) return r; diff --git a/rxtools/source/features/nandtools.c b/rxtools/source/features/nandtools.c deleted file mode 100644 index 252abdcd..00000000 --- a/rxtools/source/features/nandtools.c +++ /dev/null @@ -1,246 +0,0 @@ -/* - * Copyright (C) 2015 The PASTA Team - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "stdio.h" - -#define nCoolFiles sizeof(CoolFiles)/sizeof(CoolFiles[0]) - -uint32_t selectedFile; -void SelectFile(); - -static struct { - TCHAR* name; - TCHAR* path; -} CoolFiles[] = { - {_T("movable.sed"), _T("private")}, - {_T("SecureInfo_A"), _T("rw/sys")}, - {_T("LocalFriendCodeSeed_B"), _T("rw/sys")}, - {_T("rand_seed"), _T("rw/sys")}, - {_T("ticket.db"), _T("dbs")}, - {_T("import.db"), _T("dbs")}, -}; - -static Menu CoolFilesMenu = { - L"Choose the file to work on", - .Option = (MenuEntry[nCoolFiles]){ - { L" movable.sed", &SelectFile, L"fil0.bin" }, - { L" SecureInfo_A", &SelectFile, L"fil1.bin" }, - { L" LocalFriendCodeSeed_B", &SelectFile, L"fil2.bin" }, - { L" rand_seed", &SelectFile, L"fil3.bin" }, - { L" ticket.db", &SelectFile, L"fil4.bin" }, - { L" import.db", &SelectFile, L"fil5.bin" }, - }, - nCoolFiles, - 0, - 0 -}; - -void SelectFile(){ - selectedFile = CoolFilesMenu.Current; -} - -void dumpCoolFiles() -{ - int nandtype = NandSwitch(); - if (nandtype == UNK_NAND) return; - - selectedFile = -1; - MenuInit(&CoolFilesMenu); - MenuShow(); - - while (true) - { - uint32_t pad_state = InputWait(); - if (pad_state & BUTTON_DOWN) MenuNextSelection(); - if (pad_state & BUTTON_UP) MenuPrevSelection(); - if (pad_state & BUTTON_A) { MenuSelect(); break; } - if (pad_state & BUTTON_B) break; - TryScreenShot(); - MenuShow(); - } - - if (selectedFile == -1) return; - ConsoleInit(); - ConsoleSetTitle(strings[STR_DUMP], strings[STR_FILES]); - - wchar_t dest[_MAX_LFN], tmpstr[_MAX_LFN]; - swprintf(dest, _MAX_LFN, L"rxTools/%ls", CoolFiles[selectedFile].name); - swprintf(tmpstr, _MAX_LFN, L"%d:%ls/%ls", - nandtype, CoolFiles[selectedFile].path, - CoolFiles[selectedFile].name); - print(strings[STR_DUMPING], tmpstr, dest); - ConsoleShow(); - - unsigned int res = FSFileCopy(dest, tmpstr); - if (res != 0 && (selectedFile == 1 || selectedFile == 2)){ - if (selectedFile == 1) - { - /* Fix for SecureInfo_B */ - swprintf(dest, _MAX_LFN, L"rxTools/%.11ls%c", - CoolFiles[selectedFile].name, 'B'); - - swprintf(tmpstr, _MAX_LFN, L"%d:%ls/%.11ls%c", - nandtype, CoolFiles[selectedFile].path, - CoolFiles[selectedFile].name, 'B'); - } - else if (selectedFile == 2) - { - /* Fix for LocalFriendCodeSeed_A */ - swprintf(dest, _MAX_LFN, L"rxTools/%.20ls%c", - CoolFiles[selectedFile].name, 'A'); - swprintf(tmpstr, _MAX_LFN, L"%d:%ls/%.20ls%c", - nandtype, CoolFiles[selectedFile].path, - CoolFiles[selectedFile].name, 'A'); - } - print(strings[STR_FAILED]); - print(strings[STR_DUMPING], tmpstr, dest); - ConsoleShow(); - res = FSFileCopy(dest, tmpstr); - } - - switch ((res >> 8) & 0xFF) - { - case 0: - print(strings[STR_COMPLETED]); - break; - case 1: - print(strings[STR_ERROR_OPENING], tmpstr); - break; - case 2: - print(strings[STR_ERROR_CREATING], dest); - break; - case 3: - case 4: - print(strings[STR_ERROR_READING], tmpstr); - break; - case 5: - case 6: - print(strings[STR_ERROR_WRITING], dest); - break; - default: - print(strings[STR_FAILED]); - break; - } - - print(strings[STR_PRESS_BUTTON_ACTION], strings[STR_BUTTON_A], strings[STR_CONTINUE]); - ConsoleShow(); - WaitForButton(BUTTON_A); -} - -void restoreCoolFiles() -{ - int nandtype = NandSwitch(); - if (nandtype == UNK_NAND) return; - - selectedFile = -1; - MenuInit(&CoolFilesMenu); - MenuShow(); - while (true) - { - uint32_t pad_state = InputWait(); - if (pad_state & BUTTON_DOWN) MenuNextSelection(); - if (pad_state & BUTTON_UP) MenuPrevSelection(); - if (pad_state & BUTTON_A) { MenuSelect(); break; } - if (pad_state & BUTTON_B) break; - TryScreenShot(); - MenuShow(); - } - - if (selectedFile == -1) return; - ConsoleInit(); - ConsoleSetTitle(strings[STR_INJECT], strings[STR_FILES]); - - wchar_t dest[_MAX_LFN], tmpstr[_MAX_LFN]; - - swprintf(tmpstr, _MAX_LFN, L"rxTools/%ls", - CoolFiles[selectedFile].name); - - swprintf(dest, _MAX_LFN, L"%d:%ls/%ls", - nandtype, CoolFiles[selectedFile].path, - CoolFiles[selectedFile].name); - - print(strings[STR_INJECTING], tmpstr, dest); - ConsoleShow(); - - unsigned int res = FSFileCopy(dest, tmpstr); - if (res != 0 && (selectedFile == 1 || selectedFile == 2)){ - if (selectedFile == 1) - { - /* Fix for SecureInfo_B */ - swprintf(tmpstr, _MAX_LFN, L"rxTools/%.11ls%lc", - CoolFiles[selectedFile].name, L'B'); - - swprintf(dest, _MAX_LFN, L"%d:%ls/%.11ls%lc", - nandtype, CoolFiles[selectedFile].path, - CoolFiles[selectedFile].name, L'B'); - } - else if (selectedFile == 2) - { - swprintf(tmpstr, _MAX_LFN, L"rxTools/%.20s%lc", - CoolFiles[selectedFile].name, L'A'); - - swprintf(dest, _MAX_LFN, L"%d:%ls/%.20ls%lc", - nandtype, CoolFiles[selectedFile].path, - CoolFiles[selectedFile].name, L'A'); - } - print(strings[STR_FAILED]); - print(strings[STR_INJECTING], tmpstr, dest); - ConsoleShow(); - res = FSFileCopy(dest, tmpstr); - } - - switch ((res >> 8) & 0xFF) - { - case 0: - print(strings[STR_COMPLETED]); - break; - case 1: - print(strings[STR_ERROR_OPENING], tmpstr); - break; - case 2: - print(strings[STR_ERROR_CREATING], dest); - break; - case 3: - case 4: - print(strings[STR_ERROR_READING], tmpstr); - break; - case 5: - case 6: - print(strings[STR_ERROR_WRITING], dest); - break; - default: - print(strings[STR_FAILED]); - break; - } - - print(strings[STR_PRESS_BUTTON_ACTION], strings[STR_BUTTON_A], strings[STR_CONTINUE]); - ConsoleShow(); - WaitForButton(BUTTON_A); -} diff --git a/rxtools/source/features/padgen.c b/rxtools/source/features/padgen.c deleted file mode 100644 index 3eba3ba9..00000000 --- a/rxtools/source/features/padgen.c +++ /dev/null @@ -1,208 +0,0 @@ -/* - * Copyright (C) 2015 The PASTA Team - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -void PadGen(){ - ConsoleInit(); - ConsoleSetTitle(strings[STR_GENERATE], strings[STR_XORPAD]); - NcchPadgen(); - ConsoleShow(); - SdPadgen(); - ConsoleShow(); - - print(strings[STR_PRESS_BUTTON_ACTION], strings[STR_BUTTON_A], strings[STR_CONTINUE]); - ConsoleShow(); - WaitForButton(BUTTON_A); -} - -uint32_t NcchPadgen() -{ - uint32_t result; - File pf; - NcchInfo *info = (NcchInfo*)0x20316000; - - const TCHAR *filename = _T("/ncchinfo.bin"); - if (!FileOpen(&pf, filename, 0)) { - print(strings[STR_ERROR_OPENING], filename+1); - return 1; - } - FileRead(&pf, info, 16, 0); - - if (info->ncch_info_version != 0xF0000003) { - print(strings[STR_WRONG], filename+1, strings[STR_VERSION]); - return 0; - } - if (!info->n_entries || info->n_entries > MAXENTRIES) { - print(strings[STR_WRONG], filename+1, strings[STR_ENTRIES_COUNT]); - return 0; - } - FileRead(&pf, info->entries, info->n_entries * sizeof(NcchInfoEntry), 16); - FileClose(&pf); - - print(strings[STR_PROCESSING], filename+1); - ConsoleShow(); - for(uint32_t i = 0; i < info->n_entries; i++) { - PadInfo padInfo = {.setKeyY = 1, .size_mb = info->entries[i].size_mb}; - memcpy(padInfo.CTR, info->entries[i].CTR, 16); - memcpy(padInfo.keyY, info->entries[i].keyY, 16); - memcpy(padInfo.filename, info->entries[i].filename, 112); - - if (info->entries[i].uses7xCrypto == 0xA) // won't work on an Old 3DS - padInfo.keyslot = 0x18; - else if (info->entries[i].uses7xCrypto >> 8 == 0xDEC0DE) // magic value to manually specify keyslot - padInfo.keyslot = info->entries[i].uses7xCrypto & 0x3F; - else if (info->entries[i].uses7xCrypto) - padInfo.keyslot = 0x25; - else - padInfo.keyslot = 0x2C; - - result = CreatePad(&padInfo, i); - if (result) return 1; - } - - return 0; -} - -uint32_t SdPadgen() -{ - size_t bytesRead; - uint32_t result; - File fp; - SdInfo *info = (SdInfo*)0x20316000; - - uint8_t movable_seed[0x120] = {0}; - const TCHAR *filename; - const TCHAR *filenames[] = { - _T("movable.sed"), - _T("2:private/movable.sed"), - _T("1:private/movable.sed"), - 0 - }; - const TCHAR **pfilename; - for(pfilename = filenames; *pfilename != 0; pfilename++) - { - filename = *pfilename; - // Load console 0x34 keyY from movable.sed if present on SD card - if (FileOpen(&fp, filename, 0)) { - bytesRead = FileRead(&fp, &movable_seed, 0x120, 0); - FileClose(&fp); - if (bytesRead != 0x120) { - print(strings[STR_WRONG], filename, strings[STR_SIZE]); - return 1; - } - if (memcmp(movable_seed, "SEED", 4) != 0) { - print(strings[STR_WRONG], filename, strings[STR_CONTENT]); - return 1; - } - setup_aeskey(0x34, AES_BIG_INPUT|AES_NORMAL_INPUT, &movable_seed[0x110]); - use_aeskey(0x34); - break; - } - } - filename = _T("/SDinfo.bin"); - if (!FileOpen(&fp, filename, 0)) { - print(strings[STR_ERROR_OPENING], filename+1); - return 1; - } - bytesRead = FileRead(&fp, info, 4, 0); - - if (!info->n_entries || info->n_entries > MAXENTRIES) { - print(strings[STR_WRONG], filename+1, strings[STR_ENTRIES_COUNT]); - return 1; - } - - print(strings[STR_PROCESSING], filename); - ConsoleShow(); - - bytesRead = FileRead(&fp, info->entries, info->n_entries * sizeof(SdInfoEntry), 4); - FileClose(&fp); - - for(uint32_t i = 0; i < info->n_entries; i++) { - PadInfo padInfo = {.keyslot = 0x34, .setKeyY = 0, .size_mb = info->entries[i].size_mb}; - memcpy(padInfo.CTR, info->entries[i].CTR, 16); - memcpy(padInfo.filename, info->entries[i].filename, 180); - - result = CreatePad(&padInfo, i); - if (result) - return 1; - } - - return 0; -} - -static const uint8_t zero_buf[16] __attribute__((aligned(16))) = {0}; - -uint32_t CreatePad(PadInfo *info, int index) -{ - File pf; - #define BUFFER_ADDR ((volatile uint8_t*)0x21000000) - #define BLOCK_SIZE (4*1024*1024) - - wchar_t filename[sizeof(info->filename)]; - mbstowcs(filename, info->filename, sizeof(info->filename)); - if(filename[0] != 0 && filename[1] == 0 && filename[2] != 0 && filename[3] == 0) - { - wchar_t fname[sizeof(filename) / 2]; - for(int i = 0; i < sizeof(filename) / 2; ++i) - { - fname[i] = filename[i*2]; - if(fname[i] == 0) break; - } - if (!FileOpen(&pf, wcsncmp(fname, L"sdmc:/", 6) == 0 ? fname + 6 : fname, 1)) - return 1; - } - else if (!FileOpen(&pf, filename, 1)) - return 1; - - if(info->setKeyY != 0) - setup_aeskey(info->keyslot, AES_BIG_INPUT|AES_NORMAL_INPUT, info->keyY); - use_aeskey(info->keyslot); - - uint8_t ctr[16] __attribute__((aligned(32))); - memcpy(ctr, info->CTR, 16); - - uint32_t size_bytes = info->size_mb*1024*1024; - uint32_t size_100 = size_bytes/100; - uint32_t seekpos = 0; - print(strings[STR_GENERATING], strings[STR_PAD]); - for (uint32_t i = 0; i < size_bytes; i += BLOCK_SIZE) { - uint32_t j; - for (j = 0; (j < BLOCK_SIZE) && (i+j < size_bytes); j+= 16) { - set_ctr(AES_BIG_INPUT|AES_NORMAL_INPUT, ctr); - aes_decrypt((void*)zero_buf, (void*)BUFFER_ADDR+j, ctr, 1, AES_CTR_MODE); - add_ctr(ctr, 1); - } - - print(L"\r\033[K%i : %i%%", index, (i+j)/size_100); - ConsoleShow(); - FileWrite(&pf, (void*)BUFFER_ADDR, j, seekpos); - seekpos += j; - } - - FileClose(&pf); - return 0; -} diff --git a/rxtools/source/include/features/AdvancedFileManager.h b/rxtools/source/include/features/AdvancedFileManager.h deleted file mode 100644 index 91fd221b..00000000 --- a/rxtools/source/include/features/AdvancedFileManager.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2015 The PASTA Team - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef ADVANCEDFILEMANAGER_H -#define ADVANCEDFILEMANAGER_H - -#include -#include - -#pragma once - -typedef struct -{ - int pointer, beginning, openedFolder; - size_t count; - TCHAR **files; - TCHAR dir[1000]; - int enabled; -} panel_t; - -void AdvFileManagerShow(panel_t* Panel, int x); -void AdvFileManagerNextSelection(panel_t* Panel); -void AdvFileManagerPrevSelection(panel_t* Panel); -void AdvFileManagerSelect(panel_t* Panel); -void AdvFileManagerFileAction(TCHAR filePath[]); -void AdvFileManagerBack(panel_t* Panel); -void AdvFileManagerMain(); -#endif diff --git a/rxtools/source/include/features/CTRDecryptor.h b/rxtools/source/include/features/CTRDecryptor.h deleted file mode 100644 index 518ca96c..00000000 --- a/rxtools/source/include/features/CTRDecryptor.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) 2015 The PASTA Team - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef CTR_DECRYPTOR -#define CTR_DECRYPTOR - -#include -#include - -typedef struct{ - uint8_t* buffer; - uint8_t* keyY; - uint8_t* ctr; - size_t size; - uint32_t keyslot; -}PartitionInfo; //This basic struct can be useful anytime, even if i'll add nand decryption/exploring - -uint32_t DecryptPartition(PartitionInfo* info); -void CTRDecryptor(); - -#endif diff --git a/rxtools/source/include/features/NandDumper.h b/rxtools/source/include/features/NandDumper.h deleted file mode 100644 index e2620ff7..00000000 --- a/rxtools/source/include/features/NandDumper.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) 2015 The PASTA Team - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef NAND_DUMPER_H -#define NAND_DUMPER_H -#include - -enum nand_type{ - UNK_NAND = -1, - SYS_NAND = 1, - EMU_NAND = 2 -}; - -int NandSwitch(); -void NandDumper(); -void DumpNandPartitions(); -void GenerateNandXorpads(); -void DumpNANDSystemTitles(); -void RebuildNand(); - -#endif diff --git a/rxtools/source/include/features/TitleKeyDecrypt.h b/rxtools/source/include/features/decryption.h similarity index 73% rename from rxtools/source/include/features/TitleKeyDecrypt.h rename to rxtools/source/include/features/decryption.h index ab75539d..11604efc 100644 --- a/rxtools/source/include/features/TitleKeyDecrypt.h +++ b/rxtools/source/include/features/decryption.h @@ -15,9 +15,10 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -#ifndef TITLE_KEY_DECRYPT_H -#define TITLE_KEY_DECRYPT_H +#ifndef DECRYPTION_H +#define DECRYPTION_H +#include #include #include @@ -46,9 +47,20 @@ typedef struct { uint8_t contentIndex[172]; } TicketHdr; -void DecryptTitleKeys(); -void DecryptTitleKeyFile(void); +typedef struct{ + uint8_t* buffer; + uint8_t* keyY; + uint8_t* ctr; + size_t size; + uint32_t keyslot; +}PartitionInfo; //This basic struct can be useful anytime, even if i'll add nand decryption/exploring + + int getTitleKey(uint8_t *TitleKey, uint32_t low, uint32_t high, int drive); int getTitleKeyWithCetk(uint8_t dst[16], const TCHAR *path); +uint32_t DecryptPartition(PartitionInfo* info); +uint8_t *decryptFirmTitleNcch(uint8_t* title, size_t *size); +uint8_t *decryptFirmTitle(uint8_t *title, size_t size, size_t *firmSize, uint8_t key[16]); +int decryptFirmKtrArm9(void *p); -#endif +#endif \ No newline at end of file diff --git a/rxtools/source/include/features/downgradeapp.h b/rxtools/source/include/features/downgradeapp.h deleted file mode 100644 index ab85cda4..00000000 --- a/rxtools/source/include/features/downgradeapp.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2015 The PASTA Team - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef DOWNGRADEAPP_H -#define DOWNGRADEAPP_H - -#include -#include - -typedef struct { - unsigned int drive; - uint32_t tidLo; - uint32_t tidHi; - TCHAR tmd[64]; - TCHAR content[64]; -} AppInfo; - -//Utilities -// Fill drive, tidLo and tidHi before calling this. -int FindApp(AppInfo *info); -int CheckRegion(int drive); - -//Features -void downgradeMSET(); -void installFBI(); -void restoreHS(); - -#endif diff --git a/rxtools/source/include/features/fileexplorer.h b/rxtools/source/include/features/fileexplorer.h deleted file mode 100644 index e43f7ce3..00000000 --- a/rxtools/source/include/features/fileexplorer.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (C) 2015 The PASTA Team - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef FILEEXPLORER_H -#define FILEEXPLORER_H - -#include -#include - -void FileExplorerShow(); -void FileExplorerNextSelection(); -void FileExplorerPrevSelection(); -int FileExplorerSelect(TCHAR *p, size_t n); -void FileExplorerBack(); -int FileExplorerMain(TCHAR *p, size_t n); - -#endif diff --git a/rxtools/source/include/features/nandtools.h b/rxtools/source/include/features/nandtools.h deleted file mode 100644 index cad8d200..00000000 --- a/rxtools/source/include/features/nandtools.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (C) 2015 The PASTA Team - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef NANDTOOLS_H -#define NANDTOOLS_H - -void dumpCoolFiles(); -void restoreCoolFiles(); - -#endif diff --git a/rxtools/source/include/features/padgen.h b/rxtools/source/include/features/padgen.h deleted file mode 100644 index 46ceb7f1..00000000 --- a/rxtools/source/include/features/padgen.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (C) 2015 The PASTA Team - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef PADGEN_H -#define PADGEN_H - -#define MAXENTRIES 1024 - -typedef struct { - uint8_t CTR[16]; - uint32_t size_mb; - char filename[180]; -} __attribute__((packed)) SdInfoEntry; - -typedef struct { - uint32_t n_entries; - SdInfoEntry entries[MAXENTRIES]; -} __attribute__((packed, aligned(16))) SdInfo; - - -typedef struct { - uint8_t CTR[16]; - uint8_t keyY[16]; - uint32_t size_mb; - uint8_t reserved[8]; - uint32_t uses7xCrypto; - char filename[112]; -} __attribute__((packed)) NcchInfoEntry; - -typedef struct { - uint32_t padding; - uint32_t ncch_info_version; - uint32_t n_entries; - uint8_t reserved[4]; - NcchInfoEntry entries[MAXENTRIES]; -} __attribute__((packed, aligned(16))) NcchInfo; - - -typedef struct { - uint32_t keyslot; - uint32_t setKeyY; - uint8_t CTR[16]; - uint8_t keyY[16]; - uint32_t size_mb; - char filename[180]; -} __attribute__((packed, aligned(16))) PadInfo; - -uint32_t CreatePad(PadInfo *info, int index); -uint32_t NcchPadgen(); -uint32_t SdPadgen(); -void PadGen(); - -#endif diff --git a/rxtools/source/include/lib/cfg.h b/rxtools/source/include/lib/cfg.h index 23f37c8f..b80b6ef1 100644 --- a/rxtools/source/include/lib/cfg.h +++ b/rxtools/source/include/lib/cfg.h @@ -37,12 +37,11 @@ typedef struct { } Cfg; enum { - CFG_GUI, + CFG_DEFAULT, CFG_THEME, CFG_RANDOM, CFG_AGB, CFG_3D, - CFG_ABSYSN, CFG_LANG, CFG_NUM diff --git a/rxtools/source/include/lib/menu.h b/rxtools/source/include/lib/menu.h deleted file mode 100644 index ef88d325..00000000 --- a/rxtools/source/include/lib/menu.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (C) 2015 The PASTA Team - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#ifndef MENU_H -#define MENU_H - -#include -#include -#include - -typedef struct{ - wchar_t Str[CONSOLE_MAX_LINE_LENGTH+1]; - void(* Func)(); - wchar_t* gfx_splash; -}MenuEntry; - -typedef struct{ - wchar_t Name[CONSOLE_MAX_LINE_LENGTH+1]; - MenuEntry* Option; - int nEntryes; - int Current; //The current selected option - bool Showed; //Useful, to not refresh everything everytime -} Menu; - -void MenuInit(Menu* menu); -void MenuShow(); -void MenuNextSelection(); -void MenuPrevSelection(); -void MenuSelect(); -void MenuClose(); -void MenuRefresh(); - -extern bool bootGUI; -extern unsigned char Theme; -extern bool agb_bios; -extern bool theme_3d; -extern unsigned char language; -extern Menu* MyMenu; - -#endif diff --git a/rxtools/source/lib/cfg.c b/rxtools/source/lib/cfg.c index 266c1ce0..c17daf76 100644 --- a/rxtools/source/lib/cfg.c +++ b/rxtools/source/lib/cfg.c @@ -26,12 +26,11 @@ static char cfgLang[CFG_STR_MAX_LEN] = "en.json"; Cfg cfgs[] = { - [CFG_GUI] = { "GUI", CFG_TYPE_BOOLEAN, { .i = 0 } }, + [CFG_DEFAULT] = { "Default", CFG_TYPE_INT, { .i = 0 } }, [CFG_THEME] = { "Theme", CFG_TYPE_INT, { .i = 0 } }, [CFG_RANDOM] = { "Random theme", CFG_TYPE_BOOLEAN, { .i = 0 } }, [CFG_AGB] = { "AGB", CFG_TYPE_BOOLEAN, { .i = 0 } }, [CFG_3D] = { "3D", CFG_TYPE_BOOLEAN, { .i = 1 } }, - [CFG_ABSYSN] = { "Autoboot-sysNAND", CFG_TYPE_BOOLEAN, { .i = 0 } }, [CFG_LANG] = { "Language", CFG_TYPE_STRING, { .s = cfgLang } } }; diff --git a/rxtools/source/lib/media/nand.c b/rxtools/source/lib/media/nand.c index 557c471a..a3ad7165 100644 --- a/rxtools/source/lib/media/nand.c +++ b/rxtools/source/lib/media/nand.c @@ -16,7 +16,7 @@ */ #include -#include +#include #include #include #include diff --git a/rxtools/source/lib/menu.c b/rxtools/source/lib/menu.c deleted file mode 100644 index 7aec7a5d..00000000 --- a/rxtools/source/lib/menu.c +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (C) 2015 The PASTA Team - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * version 2 as published by the Free Software Foundation - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -Menu* MyMenu; -Menu *MenuChain[100]; -int openedMenus = 0; -int saved_index = 0; - -void MenuInit(Menu* menu){ - MyMenu = menu; - ConsoleInit(); - if (openedMenus == 0) MyMenu->Current = saved_index; //if we're entering the main menu, load the index - else MyMenu->Current = 0; - MyMenu->Showed = 0; - ConsoleSetTitle(MyMenu->Name); - for(int i = 0; i < MyMenu->nEntryes; i++){ - ConsoleAddText(MyMenu->Option[i].Str); - } -} - -void MenuShow(){ - wchar_t str[_MAX_LFN]; - - //OLD TEXT MENU: - /*int x = 0, y = 0; - ConsoleGetXY(&x, &y); - if (!MyMenu->Showed){ - sprintf(str, "/rxTools/Theme/%c/app.bin", Theme); - DrawBottomSplash(str); - ConsoleShow(); - MyMenu->Showed = 1; - } - for (int i = 0; i < MyMenu->nEntryes; i++){ - DrawString(BOT_SCREEN, i == MyMenu->Current ? L">" : L" ", x + CHAR_WIDTH*(ConsoleGetSpacing() - 1), (i)* CHAR_WIDTH + y + CHAR_WIDTH*(ConsoleGetSpacing() + 1), ConsoleGetSpecialColor(), ConsoleGetBackgroundColor()); - }*/ - - //NEW GUI: - swprintf(str, _MAX_LFN, L"/rxTools/Theme/%u/%ls", - cfgs[CFG_THEME].val.i, MyMenu->Option[MyMenu->Current].gfx_splash); - DrawBottomSplash(str); -} - -void MenuNextSelection(){ - if(MyMenu->Current + 1 < MyMenu->nEntryes){ - MyMenu->Current++; - }else{ - MyMenu->Current = 0; - } - -} - -void MenuPrevSelection(){ - if(MyMenu->Current > 0){ - MyMenu->Current--; - }else{ - MyMenu->Current = MyMenu->nEntryes - 1; - } -} - -void MenuSelect(){ - if(MyMenu->Option[MyMenu->Current].Func != NULL){ - if (openedMenus == 0)saved_index = MyMenu->Current; //if leaving the main menu, save the index - MenuChain[openedMenus++] = MyMenu; - MyMenu->Option[MyMenu->Current].Func(); - MenuInit(MenuChain[--openedMenus]); - MenuShow(); - } -} - -void MenuClose(){ - if (openedMenus > 0){ - OpenAnimation(); - } -} - -void MenuRefresh(){ - ConsoleInit(); - MyMenu->Showed = 0; - ConsoleSetTitle(MyMenu->Name); - for (int i = 0; i < MyMenu->nEntryes; i++){ - print(L"%ls %ls\n", i == MyMenu->Current ? strings[STR_CURSOR] : strings[STR_NO_CURSOR], MyMenu->Option[i].Str); - } - int x = 0, y = 0; - ConsoleGetXY(&x, &y); - if (!MyMenu->Showed){ - ConsoleShow(); - MyMenu->Showed = 1; - } -} diff --git a/rxtools/source/lib/ui/console.c b/rxtools/source/lib/ui/console.c index f023d954..3a3f420c 100644 --- a/rxtools/source/lib/ui/console.c +++ b/rxtools/source/lib/ui/console.c @@ -25,7 +25,6 @@ #include #include #include -#include wchar_t console[CONSOLE_MAX_LINES][CONSOLE_MAX_LINE_LENGTH + 1]; wchar_t consoletitle[CONSOLE_MAX_TITLE_LENGTH+1] = L""; diff --git a/rxtools/source/main.c b/rxtools/source/main.c index 0bc6fb9e..d16bf8ee 100644 --- a/rxtools/source/main.c +++ b/rxtools/source/main.c @@ -20,7 +20,6 @@ #include #include #include -#include "MainMenu.h" #include #include #include @@ -31,9 +30,17 @@ #include #include #include +#include +#include +#include #define FONT_NAME "font.bin" +static void ShutDown(int arg){ + i2cWriteRegister(I2C_DEV_MCU, 0x20, (arg) ? (uint8_t)(1<<0):(uint8_t)(1<<2)); + while(1); +} + static int warned = 0; static void setConsole() @@ -73,6 +80,15 @@ static void drawTop() DrawTopSplash(str, str, str); } +static void drawBottom() +{ + wchar_t str[_MAX_LFN]; + + swprintf(str, _MAX_LFN, L"/rxTools/Theme/%u/BOT%u.bin", + cfgs[CFG_THEME].val.i, cfgs[CFG_DEFAULT].val.i); + DrawBottomSplash(str); +} + static FRESULT initKeyX() { uint8_t buff[AES_BLOCK_SIZE]; @@ -129,28 +145,26 @@ static _Noreturn void mainLoop() uint32_t pad; while (true) { + drawBottom(); pad = InputWait(); - if (pad & (BUTTON_DOWN | BUTTON_RIGHT | BUTTON_R1)) - MenuNextSelection(); - if (pad & (BUTTON_UP | BUTTON_LEFT | BUTTON_L1)) - MenuPrevSelection(); + if (pad & BUTTON_A) rxMode(1); //EMUNAND + if (pad & BUTTON_X) rxMode(0); //SYSNAND + if (pad & BUTTON_Y) PastaMode(); //PASTAMODE + if (pad & BUTTON_B) ShutDown(1); //SHUTDOWN + if (pad & BUTTON_LEFT) + { + if(cfgs[CFG_DEFAULT].val.i == 0) cfgs[CFG_DEFAULT].val.i = 3; + else cfgs[CFG_DEFAULT].val.i--; + writeCfg(); - if (pad & BUTTON_A) { - OpenAnimation(); - MenuSelect(); } - - if (pad & BUTTON_SELECT) { - fadeOut(); - ShutDown(1); //shutdown - } - if (pad & BUTTON_START) { - fadeOut(); - ShutDown(0); //reboot + if(pad & BUTTON_RIGHT) + { + if(cfgs[CFG_DEFAULT].val.i == 3) cfgs[CFG_DEFAULT].val.i = 0; + else cfgs[CFG_DEFAULT].val.i++; + writeCfg(); } - - MenuShow(); } } @@ -184,16 +198,17 @@ __attribute__((section(".text.start"), noreturn)) void _start() preloadStringsA(); + if (!FSInit()) { DrawString(BOT_SCREEN, strings[STR_FAILED], BOT_SCREEN_WIDTH / 2, SCREEN_HEIGHT - FONT_HEIGHT, RED, BLACK); while (1); } - /* + set_loglevel(ll_info); log(ll_info, "Initializing rxTools..."); - */ + setConsole(); @@ -215,7 +230,7 @@ __attribute__((section(".text.start"), noreturn)) void _start() else warn(L"Failed to load " FONT_NAME ": %d\n", r); - if (getMpInfo() == MPINFO_KTR) + if (getMpInfo() == MPINFO_KTR) { r = initN3DSKeys(); if (r != FR_OK) { @@ -230,22 +245,25 @@ __attribute__((section(".text.start"), noreturn)) void _start() } } + install(); postinstall: readCfg(); + log(ll_info, "Done..."); + r = loadStrings(); if (r) warn(L"Failed to load strings: %d\n", r); drawTop(); - if (!cfgs[CFG_GUI].val.i && HID_STATE & BUTTON_L1) { - if(~HID_STATE & BUTTON_Y) rxMode(1); - else if(~HID_STATE & BUTTON_X) rxMode(0); - else if(~HID_STATE & BUTTON_B) PastaMode(); - else rxMode(cfgs[CFG_ABSYSN].val.i ? 0 : 1); - } + //Default boot check + if (cfgs[CFG_DEFAULT].val.i && HID_STATE & BUTTON_L1) + { + if(cfgs[CFG_DEFAULT].val.i == 3) PastaMode(); + else rxMode(cfgs[CFG_DEFAULT].val.i - 1); + } if (sysver < 7) { r = initKeyX(); @@ -265,7 +283,5 @@ __attribute__((section(".text.start"), noreturn)) void _start() } OpenAnimation(); - MenuInit(&MainMenu); - MenuShow(); mainLoop(); } diff --git a/theme/BASE.png b/theme/BASE.png deleted file mode 100644 index 2c2ece1b..00000000 Binary files a/theme/BASE.png and /dev/null differ diff --git a/theme/BOT0.png b/theme/BOT0.png new file mode 100644 index 00000000..899ba739 Binary files /dev/null and b/theme/BOT0.png differ diff --git a/theme/BOT1.png b/theme/BOT1.png new file mode 100644 index 00000000..fbfb7be8 Binary files /dev/null and b/theme/BOT1.png differ diff --git a/theme/BOT2.png b/theme/BOT2.png new file mode 100644 index 00000000..bc14c4d1 Binary files /dev/null and b/theme/BOT2.png differ diff --git a/theme/BOT3.png b/theme/BOT3.png new file mode 100644 index 00000000..1a05dacc Binary files /dev/null and b/theme/BOT3.png differ diff --git a/theme/FM.png b/theme/FM.png deleted file mode 100644 index 4b566f02..00000000 Binary files a/theme/FM.png and /dev/null differ diff --git a/theme/TOP.png b/theme/TOP.png index d7fdf85b..0d472b57 100644 Binary files a/theme/TOP.png and b/theme/TOP.png differ diff --git a/theme/adv0.png b/theme/adv0.png deleted file mode 100644 index 687b9dea..00000000 Binary files a/theme/adv0.png and /dev/null differ diff --git a/theme/adv1.png b/theme/adv1.png deleted file mode 100644 index 5d62dfb1..00000000 Binary files a/theme/adv1.png and /dev/null differ diff --git a/theme/adv2.png b/theme/adv2.png deleted file mode 100644 index 0127cba8..00000000 Binary files a/theme/adv2.png and /dev/null differ diff --git a/theme/adv3.png b/theme/adv3.png deleted file mode 100644 index d0f6fbc2..00000000 Binary files a/theme/adv3.png and /dev/null differ diff --git a/theme/adv4.png b/theme/adv4.png deleted file mode 100644 index 74efc53f..00000000 Binary files a/theme/adv4.png and /dev/null differ diff --git a/theme/app.png b/theme/app.png index ebd38836..4d9eb043 100644 Binary files a/theme/app.png and b/theme/app.png differ diff --git a/theme/boot.png b/theme/boot.png deleted file mode 100644 index 513393bd..00000000 Binary files a/theme/boot.png and /dev/null differ diff --git a/theme/boot0.png b/theme/boot0.png deleted file mode 100644 index 296a75fc..00000000 Binary files a/theme/boot0.png and /dev/null differ diff --git a/theme/bootE.png b/theme/bootE.png deleted file mode 100644 index 98c9a213..00000000 Binary files a/theme/bootE.png and /dev/null differ diff --git a/theme/bootS.png b/theme/bootS.png deleted file mode 100644 index 580e91ff..00000000 Binary files a/theme/bootS.png and /dev/null differ diff --git a/theme/cfg0.png b/theme/cfg0.png index 0c40ea84..aa66c9ee 100644 Binary files a/theme/cfg0.png and b/theme/cfg0.png differ diff --git a/theme/cfg0TOP.png b/theme/cfg0TOP.png index 072d567c..f30a7976 100644 Binary files a/theme/cfg0TOP.png and b/theme/cfg0TOP.png differ diff --git a/theme/cfg1E.png b/theme/cfg1E.png index 50d84f13..46038c07 100644 Binary files a/theme/cfg1E.png and b/theme/cfg1E.png differ diff --git a/theme/cfg1O.png b/theme/cfg1O.png index b77cc885..95fd6f2e 100644 Binary files a/theme/cfg1O.png and b/theme/cfg1O.png differ diff --git a/theme/credits.png b/theme/credits.png deleted file mode 100644 index 30b081a1..00000000 Binary files a/theme/credits.png and /dev/null differ diff --git a/theme/dec0.png b/theme/dec0.png deleted file mode 100644 index 0a29fdb4..00000000 Binary files a/theme/dec0.png and /dev/null differ diff --git a/theme/dec1.png b/theme/dec1.png deleted file mode 100644 index fd7ade47..00000000 Binary files a/theme/dec1.png and /dev/null differ diff --git a/theme/dec2.png b/theme/dec2.png deleted file mode 100644 index 7755a81e..00000000 Binary files a/theme/dec2.png and /dev/null differ diff --git a/theme/dec3.png b/theme/dec3.png deleted file mode 100644 index e01c5fbf..00000000 Binary files a/theme/dec3.png and /dev/null differ diff --git a/theme/dec4.png b/theme/dec4.png deleted file mode 100644 index 57f05043..00000000 Binary files a/theme/dec4.png and /dev/null differ diff --git a/theme/dec5.png b/theme/dec5.png deleted file mode 100644 index 109b20cd..00000000 Binary files a/theme/dec5.png and /dev/null differ diff --git a/theme/dmp0.png b/theme/dmp0.png deleted file mode 100644 index cf8a6a31..00000000 Binary files a/theme/dmp0.png and /dev/null differ diff --git a/theme/dmp1.png b/theme/dmp1.png deleted file mode 100644 index aff9f2a9..00000000 Binary files a/theme/dmp1.png and /dev/null differ diff --git a/theme/dmp2.png b/theme/dmp2.png deleted file mode 100644 index 870b4be4..00000000 Binary files a/theme/dmp2.png and /dev/null differ diff --git a/theme/dmp3.png b/theme/dmp3.png deleted file mode 100644 index ded1af2d..00000000 Binary files a/theme/dmp3.png and /dev/null differ diff --git a/theme/fil0.png b/theme/fil0.png deleted file mode 100644 index d4bcec53..00000000 Binary files a/theme/fil0.png and /dev/null differ diff --git a/theme/fil1.png b/theme/fil1.png deleted file mode 100644 index d38c3a33..00000000 Binary files a/theme/fil1.png and /dev/null differ diff --git a/theme/fil2.png b/theme/fil2.png deleted file mode 100644 index 57d3aaa9..00000000 Binary files a/theme/fil2.png and /dev/null differ diff --git a/theme/fil3.png b/theme/fil3.png deleted file mode 100644 index 6cf1d4f5..00000000 Binary files a/theme/fil3.png and /dev/null differ diff --git a/theme/fil4.png b/theme/fil4.png deleted file mode 100644 index d7398b8f..00000000 Binary files a/theme/fil4.png and /dev/null differ diff --git a/theme/fil5.png b/theme/fil5.png deleted file mode 100644 index 1ffd7deb..00000000 Binary files a/theme/fil5.png and /dev/null differ diff --git a/theme/inj0.png b/theme/inj0.png deleted file mode 100644 index f435dc0b..00000000 Binary files a/theme/inj0.png and /dev/null differ diff --git a/theme/inj1.png b/theme/inj1.png deleted file mode 100644 index f07c2e17..00000000 Binary files a/theme/inj1.png and /dev/null differ diff --git a/theme/menu0.png b/theme/menu0.png deleted file mode 100644 index dd81a340..00000000 Binary files a/theme/menu0.png and /dev/null differ diff --git a/theme/menu1.png b/theme/menu1.png deleted file mode 100644 index ff6965ff..00000000 Binary files a/theme/menu1.png and /dev/null differ diff --git a/theme/menu2.png b/theme/menu2.png deleted file mode 100644 index c35f236f..00000000 Binary files a/theme/menu2.png and /dev/null differ diff --git a/theme/menu3.png b/theme/menu3.png deleted file mode 100644 index 6544dc06..00000000 Binary files a/theme/menu3.png and /dev/null differ diff --git a/theme/menu4.png b/theme/menu4.png deleted file mode 100644 index 4bb78534..00000000 Binary files a/theme/menu4.png and /dev/null differ diff --git a/theme/menu5.png b/theme/menu5.png deleted file mode 100644 index 6135d420..00000000 Binary files a/theme/menu5.png and /dev/null differ diff --git a/theme/menu6.png b/theme/menu6.png deleted file mode 100644 index ecae4fc2..00000000 Binary files a/theme/menu6.png and /dev/null differ