]> Chaos Git - corbenik/corbenik.git/commitdiff
Fix loader config, minor adjustments, etc
authorchaoskagami <chaos.kagami@gmail.com>
Tue, 17 May 2016 21:27:03 +0000 (17:27 -0400)
committerchaoskagami <chaos.kagami@gmail.com>
Tue, 17 May 2016 21:27:03 +0000 (17:27 -0400)
external/loader/source/patcher.c
source/firm/firm.c
source/menu.c
source/patch/module.c
source/patch/svc.c
source/patcher.c

index bd21e9357d033e2f2285790698ba882bf43daf02..e8db47c6b90b61337699eba805d65322f8f92691 100644 (file)
@@ -117,30 +117,25 @@ static u32 secureInfoExists(void)
     return secureInfoExists;
 }
 
-struct config_file config;
-int failed_load_config = 1;
+static struct config_file config;
+static int failed_load_config = 1;
 
-void clear_config() {
-       // Basically; memset.
-       for(int i=0;i<sizeof(struct config_file);i++)
-               ((char*)&config)[i]=0;
-}
-
-void load_config() {
-       IFile file;
-    u64 total;
+static void load_config() {
+       static IFile file;
+    static u64 total;
 
        // Open file.
-    if (!fileOpen(&file, ARCHIVE_SDMC, PATH_CONFIG, FS_OPEN_READ)) {
+    if (!R_SUCCEEDED(fileOpen(&file, ARCHIVE_SDMC, PATH_CONFIG, FS_OPEN_READ))) {
                // Failed to open.
-               failed_load_config = 1;
-        goto ret_fail;
+        return;
     }
 
        // Read file.
-    if(!IFile_Read(&file, &total, &config, sizeof(struct config_file))) {
+    if (!R_SUCCEEDED(IFile_Read(&file, &total, &config, sizeof(struct config_file)))) {
+               IFile_Close(&file); // Read to memory.
+
                // Failed to read.
-               goto ret_fail;
+               return;
        }
 
        IFile_Close(&file); // Read to memory.
@@ -148,21 +143,16 @@ void load_config() {
        if (config.magic[0] != 'O' || config.magic[1] != 'V' || config.magic[2] != 'A' || config.magic[3] != 'N') {
                // Incorrect magic.
                // Failed to read.
-               goto ret_fail;
+               return;
        }
 
        if (config.config_ver != config_version) {
                // Invalid version.
-               goto ret_fail;
+               return;
     }
 
        failed_load_config = 0;
 
-       return;
-
-ret_fail:
-       clear_config();
-
        return;
 }
 
@@ -346,7 +336,7 @@ static void patchCfgGetRegion(u8 *code, u32 size, u8 regionId, u32 CFGUHandleOff
     }
 }
 
-void region_patch(u64 progId, u8 *code, u32 size) {
+static void region_patch(u64 progId, u8 *code, u32 size) {
        static const u8 regionFreePattern[] = {0x00, 0x00, 0x55, 0xE3, 0x01, 0x10, 0xA0, 0xE3};
        static const u8 regionFreePatch[]   = {0x01, 0x00, 0xA0, 0xE3, 0x1E, 0xFF, 0x2F, 0xE1};
 
@@ -359,7 +349,7 @@ void region_patch(u64 progId, u8 *code, u32 size) {
     );
 }
 
-void disable_nim_updates(u64 progId, u8 *code, u32 size) {
+static void disable_nim_updates(u64 progId, u8 *code, u32 size) {
        static const u8 blockAutoUpdatesPattern[] = {0x25, 0x79, 0x0B, 0x99};
        static const u8 blockAutoUpdatesPatch[]   = {0xE3, 0xA0};
 
@@ -372,7 +362,7 @@ void disable_nim_updates(u64 progId, u8 *code, u32 size) {
        );
 }
 
-void disable_eshop_updates(u64 progId, u8 *code, u32 size) {
+static void disable_eshop_updates(u64 progId, u8 *code, u32 size) {
        static const u8 skipEshopUpdateCheckPattern[] = {0x30, 0xB5, 0xF1, 0xB0};
        static const u8 skipEshopUpdateCheckPatch[]   = {0x00, 0x20, 0x08, 0x60, 0x70, 0x47};
 
@@ -385,7 +375,7 @@ void disable_eshop_updates(u64 progId, u8 *code, u32 size) {
        );
 }
 
-void fake_friends_version(u64 progId, u8 *code, u32 size) {
+static void fake_friends_version(u64 progId, u8 *code, u32 size) {
        static const u8 fpdVerPattern[] = {0xE0, 0x1E, 0xFF, 0x2F, 0xE1, 0x01, 0x01, 0x01};
        static const u8 fpdVerPatch = 0x06; // Latest version.
 
@@ -398,7 +388,7 @@ void fake_friends_version(u64 progId, u8 *code, u32 size) {
        );
 }
 
-void settings_string(u64 progId, u8 *code, u32 size) {
+static void settings_string(u64 progId, u8 *code, u32 size) {
        static const u16 verPattern[] = u"Ver.";
        static const u16 verPatch[] = u".hax";
 
@@ -411,7 +401,7 @@ void settings_string(u64 progId, u8 *code, u32 size) {
        );
 }
 
-void disable_cart_updates(u64 progId, u8 *code, u32 size) {
+static void disable_cart_updates(u64 progId, u8 *code, u32 size) {
        static const u8 stopCartUpdatesPattern[] = {0x0C, 0x18, 0xE1, 0xD8};
        static const u8 stopCartUpdatesPatch[]   = {0x0B, 0x18, 0x21, 0xC8};
 
@@ -424,7 +414,7 @@ void disable_cart_updates(u64 progId, u8 *code, u32 size) {
        );
 }
 
-void adjust_cpu_settings(u64 progId, u8 *code, u32 size) {
+static void adjust_cpu_settings(u64 progId, u8 *code, u32 size) {
        if (!failed_load_config) {
                u32 cpuSetting = 0;
                // L2
@@ -446,7 +436,7 @@ void adjust_cpu_settings(u64 progId, u8 *code, u32 size) {
        }
 }
 
-void secureinfo_sigpatch(u64 progId, u8 *code, u32 size) {
+static void secureinfo_sigpatch(u64 progId, u8 *code, u32 size) {
        static const u8 secureinfoSigCheckPattern[] = {0x06, 0x46, 0x10, 0x48, 0xFC};
        static const u8 secureinfoSigCheckPatch[]   = {0x00, 0x26};
 
@@ -459,11 +449,65 @@ void secureinfo_sigpatch(u64 progId, u8 *code, u32 size) {
        );
 }
 
-void patchCode(u64 progId, u8 *code, u32 size)
-{
-       // FIXME - Config loading breaks loader. WTF is this?
-       // Maybe the memcpy?
-       // load_config();
+static void ro_sigpatch(u64 progId, u8 *code, u32 size) {
+       static const u8 sigCheckPattern[]      = {0x30, 0x40, 0x2D, 0xE9, 0x02, 0x50, 0xA0, 0xE1};
+       static const u8 sha256ChecksPattern1[] = {0x30, 0x40, 0x2D, 0xE9, 0x24, 0xD0, 0x4D, 0xE2};
+       static const u8 sha256ChecksPattern2[] = {0xF8, 0x4F, 0x2D, 0xE9, 0x01, 0x70, 0xA0, 0xE1};
+
+       // mov r0, #0; bx lr - equivalent to 'return 0;'
+       static const u8 stub[]                 = {0x00, 0x00, 0xA0, 0xE3, 0x1E, 0xFF, 0x2F, 0xE1};
+
+       //Disable CRR0 signature (RSA2048 with SHA256) check
+       patchMemory(code, size,
+               sigCheckPattern,
+               sizeof(sigCheckPattern), 0,
+               stub,
+               sizeof(stub), 1
+       );
+
+       //Disable CRO0/CRR0 SHA256 hash checks (section hashes, and hash table)
+       patchMemory(code, size,
+               sha256ChecksPattern1,
+               sizeof(sha256ChecksPattern1), 0,
+               stub,
+               sizeof(stub), 1
+       );
+
+       patchMemory(code, size,
+               sha256ChecksPattern2,
+               sizeof(sha256ChecksPattern2), 0,
+               stub,
+               sizeof(stub), 1
+       );
+}
+
+void language_emu(u64 progId, u8 *code, u32 size) {
+       if(!failed_load_config && config.options[OPTION_LOADER_LANGEMU]) {
+               u32 tidHigh = (progId & 0xFFFFFFF000000000LL) >> 0x24;
+
+               if(tidHigh == 0x0004000) { // Normal Game
+                       //Language emulation
+                       u8 regionId = 0xFF,
+                       languageId = 0xFF;
+
+                       if(R_SUCCEEDED(loadTitleLocaleConfig(progId, &regionId, &languageId))) {
+                               u32 CFGUHandleOffset;
+
+                               u8 *CFGU_GetConfigInfoBlk2_endPos = getCfgOffsets(code, size, &CFGUHandleOffset);
+
+                               if(CFGU_GetConfigInfoBlk2_endPos != NULL) {
+                                       if(languageId != 0xFF)
+                                               patchCfgGetLanguage(code, size, languageId, CFGU_GetConfigInfoBlk2_endPos);
+                                       if(regionId != 0xFF)
+                                               patchCfgGetRegion(code, size, regionId, CFGUHandleOffset);
+                               }
+                       }
+               }
+       }
+}
+
+void patchCode(u64 progId, u8 *code, u32 size) {
+       load_config();
 
     switch(progId)
     {
@@ -504,7 +548,7 @@ void patchCode(u64 progId, u8 *code, u32 size)
         case 0x0004013000008002LL: // NS
         {
                        disable_cart_updates(progId, code, size);
-                       adjust_cpu_settings(progId, code, size);
+                       adjust_cpu_settings(progId, code, size); // DEFAULT cpu settings that are inherited system-wide. Per-app is handled in default.
             break;
         }
 
@@ -513,35 +557,15 @@ void patchCode(u64 progId, u8 *code, u32 size)
                        secureinfo_sigpatch(progId, code, size);
             break;
         }
-/*        default:
+               case 0x0004013000003702LL: // RO
                {
-            if(!failed_load_config && config.options[OPTION_LOADER_LANGEMU])
-            {
-                u32 tidHigh = (progId & 0xFFFFFFF000000000LL) >> 0x24;
-
-                if(tidHigh == 0x0004000)
-                {
-                    //Language emulation
-                    u8 regionId = 0xFF,
-                       languageId = 0xFF;
-
-                    if(R_SUCCEEDED(loadTitleLocaleConfig(progId, &regionId, &languageId)))
-                    {
-                        u32 CFGUHandleOffset;
-
-                        u8 *CFGU_GetConfigInfoBlk2_endPos = getCfgOffsets(code, size, &CFGUHandleOffset);
-
-                        if(CFGU_GetConfigInfoBlk2_endPos != NULL)
-                        {
-                            if(languageId != 0xFF)
-                                patchCfgGetLanguage(code, size, languageId, CFGU_GetConfigInfoBlk2_endPos);
-                            if(regionId != 0xFF)
-                                patchCfgGetRegion(code, size, regionId, CFGUHandleOffset);
-                        }
-                    }
-                }
-            }
+                       ro_sigpatch(progId, code, size);
+                       break;
+               }
+        default:
+               {
+                       language_emu(progId, code, size);
             break;
-        } */
+        }
     }
 }
index 1586d8641c331a854e16a366415fad1de401c210..dfb1cf1d0cc6d4087ed7729b3fba502d9ffdb59d 100644 (file)
@@ -46,7 +46,7 @@ int decrypt_firm_title(firm_h *dest, ncch_h *ncch, uint32_t *size, void *key) {
     uint8_t exefs_key[16] = {0};
     uint8_t exefs_iv[16] = {0};
 
-    fprintf(BOTTOM_SCREEN, "Decrypting the NCCH\n");
+    fprintf(BOTTOM_SCREEN, "  Decrypting the NCCH\n");
     aes_setkey(0x16, key, AES_KEYNORMAL, AES_INPUT_BE | AES_INPUT_NORMAL);
     aes_use_keyslot(0x16);
     aes(ncch, ncch, *size / AES_BLOCK_SIZE, firm_iv, AES_CBC_DECRYPT_MODE, AES_INPUT_BE | AES_INPUT_NORMAL);
@@ -61,7 +61,7 @@ int decrypt_firm_title(firm_h *dest, ncch_h *ncch, uint32_t *size, void *key) {
     exefs_h *exefs = (exefs_h *)((void *)ncch + ncch->exeFSOffset * MEDIA_UNITS);
     uint32_t exefs_size = ncch->exeFSSize * MEDIA_UNITS;
 
-    fprintf(BOTTOM_SCREEN, "Decrypting the exefs\n");
+    fprintf(BOTTOM_SCREEN, "  Decrypting the exefs\n");
     aes_setkey(0x2C, exefs_key, AES_KEYY, AES_INPUT_BE | AES_INPUT_NORMAL);
     aes_use_keyslot(0x2C);
     aes(exefs, exefs, exefs_size / AES_BLOCK_SIZE, exefs_iv, AES_CTR_MODE, AES_INPUT_BE | AES_INPUT_NORMAL);
@@ -82,7 +82,7 @@ int decrypt_firm_title(firm_h *dest, ncch_h *ncch, uint32_t *size, void *key) {
 int decrypt_arm9bin(arm9bin_h *header, uint64_t firm_title, uint8_t version) {
     uint8_t slot = 0x15;
 
-    fprintf(BOTTOM_SCREEN, "Decrypting ARM9 FIRM binary\n");
+    fprintf(BOTTOM_SCREEN, "  Decrypting ARM9 FIRM binary\n");
 
     if (firm_title == NATIVE_FIRM_TITLEID && version > 0x0F) {
         uint8_t decrypted_keyx[AES_BLOCK_SIZE];
@@ -116,13 +116,13 @@ int decrypt_firm(firm_h *dest, char *path_firmkey, uint32_t *size) {
 
     // Firmware is likely encrypted. Decrypt.
     if (!read_file(firm_key, path_firmkey, AES_BLOCK_SIZE)) {
-        fprintf(BOTTOM_SCREEN, "Failed to load FIRM key\n");
+        fprintf(BOTTOM_SCREEN, "  Failed to load FIRM key\n");
         return 1;
     } else {
-        fprintf(BOTTOM_SCREEN, "Loaded FIRM key\n");
+        fprintf(BOTTOM_SCREEN, "  Loaded FIRM key\n");
     }
 
-    fprintf(BOTTOM_SCREEN, "Decrypting FIRM\n");
+    fprintf(BOTTOM_SCREEN, "  Decrypting FIRM\n");
     if (decrypt_firm_title(dest, (void *)dest, size, firm_key) != 0) {
         fprintf(BOTTOM_SCREEN, "Failed to decrypt the firmware\n");
         return 1;
@@ -322,7 +322,7 @@ int find_proc9(firm_h* firm, firm_section_h* process9, exefs_h** p9exefs) {
 }
 
 int load_firms() {
-    fprintf(TOP_SCREEN, "[Loading FIRM]\n");
+    fprintf(BOTTOM_SCREEN, "Loading FIRM...\n");
 
     fprintf(BOTTOM_SCREEN, "Loading NATIVE_FIRM\n");
     if (load_firm(firm_loc, PATH_NATIVE_F, PATH_NATIVE_FIRMKEY, &firm_size, NATIVE_FIRM_TITLEID) != 0)
@@ -345,7 +345,7 @@ int load_firms() {
 }
 
 void boot_cfw() {
-    fprintf(TOP_SCREEN, "Applying patches...\n");
+    fprintf(BOTTOM_SCREEN, "Applying patches...\n");
     if (patch_firm_all() != 0)
         return;
 
index d891c2414620e2a6b2e39add6bcd9d4b2d008ee8..f89374383a8ba8e37fd6de3ea715c421188a6de8 100644 (file)
@@ -47,6 +47,10 @@ uint32_t wait_key() {
             get = BUTTON_UP;
         else if (HID_PAD & BUTTON_DOWN)
             get = BUTTON_DOWN;
+        else if (HID_PAD & BUTTON_RIGHT)
+            get = BUTTON_RIGHT;
+        else if (HID_PAD & BUTTON_LEFT)
+            get = BUTTON_LEFT;
         else if (HID_PAD & BUTTON_A)
             get = BUTTON_A;
         else if (HID_PAD & BUTTON_B)
@@ -56,8 +60,8 @@ uint32_t wait_key() {
     return get;
 }
 
-void header() {
-    fprintf(stdout, "\x1b[33;40m[.corbenik//%s]\x1b[0m\n", VERSION);
+void header(char* append) {
+    fprintf(stdout, "\x1b[33;40m[.corbenik//%s] %s\x1b[0m\n", VERSION, append);
 }
 
 int menu_patches() { return MENU_MAIN; }
@@ -65,7 +69,7 @@ int menu_patches() { return MENU_MAIN; }
 int menu_options() {
     set_cursor(TOP_SCREEN, 0, 0);
 
-    header();
+    header("A:Enter B:Back DPAD:Nav");
 
        int i = 0;
     while(options[i].index != -1) { // -1 Sentinel.
@@ -75,7 +79,7 @@ int menu_options() {
             fprintf(TOP_SCREEN, "   ");
 
         if (need_redraw)
-                       fprintf(TOP_SCREEN, "[%c] %s\n", (config.options[options[i].index] ? 'X' : ' '), options[i].name);
+                       fprintf(TOP_SCREEN, "[%c]  %s\n", (config.options[options[i].index] ? 'X' : ' '), options[i].name);
                else {
                        // Yes, this is weird. printf does a large number of extra things we don't
                        // want computed at the moment; this is faster.
@@ -122,7 +126,7 @@ int menu_info() {
 
     set_cursor(TOP_SCREEN, 0, 0);
 
-    header();
+    header("Any:Back");
        struct firm_signature *native = get_firm_info(firm_loc);
        struct firm_signature *agb = get_firm_info(agb_firm_loc);
        struct firm_signature *twl = get_firm_info(twl_firm_loc);
@@ -132,9 +136,7 @@ int menu_info() {
                         "AGB_FIRM / GBA Firmware:\n"
                         "  Version: %s (%x)\n"
                         "TWL_FIRM / DSi Firmware:\n"
-                        "  Version: %s (%x)\n"
-                        "\n"
-                                               "[Press any key]\n",
+                        "  Version: %s (%x)\n",
                                                native->version_string, native->version,
                                                agb->version_string, agb->version,
                                                twl->version_string, twl->version);
@@ -154,7 +156,7 @@ int menu_help() {
 
     set_cursor(TOP_SCREEN, 0, 0);
 
-    header();
+    header("Any:Back");
 
     fprintf(stdout,     "\nCorbenik is a 3DS firmware patching tool;\n"
                         "  commonly known as a CFW. It seeks to address\n"
@@ -215,7 +217,7 @@ int menu_main() {
     };
     int menu_max = 7;
 
-    header();
+    header("A:Enter DPAD:Nav");
 
     for(int i=0; i < menu_max; i++) {
         if (!(i+2 == MENU_HELP && config.options[OPTION_READ_ME])) {
index fecadf12516477136f905cba18df9629525fbb1d..adb347144870c23d470258a99b0fc9f3323f0671 100644 (file)
@@ -40,6 +40,7 @@ int patch_modules() {
                if (memcmp(sysmodule->programID, module->programID, 8) == 0) {
                        // Expand firmware module size if needed to accomodate replacement.
                        if (module->contentSize > sysmodule->contentSize) {
+                               fprintf(stderr, "Module: Grow %d units\n", module->contentSize - sysmodule->contentSize);
                                // Location to shuffle to.
                                uint32_t need_units = (module->contentSize - sysmodule->contentSize);
                                uint8_t* move_to = ((uint8_t*)sysmodule + (module->contentSize + need_units) * 0x200);
@@ -53,6 +54,7 @@ int patch_modules() {
 
                        // Move the remaining modules closer
                        if (module->contentSize < sysmodule->contentSize) {
+                               fprintf(stderr, "Module: Shrink %d units\n", sysmodule->contentSize - module->contentSize);
                                int remaining_size =
                                        sysmodule_section->size -
                     (((uint32_t)sysmodule + sysmodule->contentSize * 0x200) -
@@ -62,6 +64,7 @@ int patch_modules() {
                                // Move end of section to be adjacent
                        }
 
+                       fprintf(stderr, "Module: Injecting %llu\n", module->programID);
                        // Copy the module into the firm
                        memcpy(sysmodule, module, module->contentSize * 0x200);
                        break;
index cc77d17dbc549ce0059563671b3b7a5c36191d39..21c880daf0110086fb85c02cd6183689a0a6c444 100644 (file)
@@ -25,7 +25,7 @@ int patch_services() {
     uint32_t *exceptionsPage;
     uint32_t *svcTable = getSvcAndExceptions(arm11Section1, firm_loc->section[1].size, &exceptionsPage);
 
-       fprintf(stderr, "Svc: table:%x\n", (uint32_t)svcTable);
+       fprintf(stderr, "Svc: table at %x\n", (uint32_t)svcTable);
 
     if(!svcTable[0x7B]) {
         // Firmware is missing svcBackdoor. Fix it.
@@ -42,14 +42,14 @@ int patch_services() {
                        for(freeSpace = exceptionsPage; *freeSpace != 0xFFFFFFFF; freeSpace++);
                }
 
-               fprintf(stderr, "Svc: to:%x\n", (uint32_t)freeSpace);
+               fprintf(stderr, "Svc: Copy code to %x\n", (uint32_t)freeSpace);
 
         memcpy(freeSpace, svcbackdoor, sizeof(svcbackdoor));
         svcTable[0x7B] = 0xFFFF0000 + ((uint8_t *)freeSpace - (uint8_t *)exceptionsPage);
 
                freeSpace += sizeof(svcbackdoor); // We keep track of this because there's more than 7B free.
 
-               fprintf(stderr, "Svc: ent:%x\n", svcTable[0x7B]);
+               fprintf(stderr, "Svc: entry set as %x\n", svcTable[0x7B]);
     } else {
         fprintf(stderr, "Svc: no change\n");
        }
index f8782cad11d49eef0cb3d59784fc4cef627371d4..0d6bae1a4cc508f4b58e7178eb012bfad6795a75 100644 (file)
@@ -37,9 +37,10 @@ extern int doing_autoboot;
 
 void wait() {
        if (config.options[OPTION_TRACE] && !doing_autoboot) {
-               fprintf(stderr, "[press key]\n");
+               fprintf(stderr, "                                 [WAIT]");
                wait_key();
        }
+       fprintf(stderr, "\r                                       \r");
 }
 
 int patch_firm_all() {