]> Chaos Git - corbenik/corbenik.git/commitdiff
Fix 0x21 key handling (wow me)
authorroot <chaos.kagami@gmail.com>
Tue, 17 May 2016 06:45:10 +0000 (02:45 -0400)
committerroot <chaos.kagami@gmail.com>
Tue, 17 May 2016 06:45:10 +0000 (02:45 -0400)
doc/firmware.md
source/firm/firm.c
source/patch/svc.c

index 884edb0798a32e53dbedfadd9cd49d4939bc7509..89c08f13687450a4def82bc836e52727159604a4 100644 (file)
@@ -29,3 +29,10 @@ New 3DS AGB_FIRM (Firmware for GBA games):
   cetk: http://nus.cdn.c.shop.nintendowifi.net/ccs/download/0004013820000202/cetk
 
   firm: http://nus.cdn.c.shop.nintendowifi.net/ccs/download/0004013820000202/00000000
+
+Note that while latest is usually greatest, if you MUST use 11.0 FIRMs, please enable
+both the loader replacement and service fix. Nintendo broke quite a bit, and it was
+quite literally a anti-hack.
+
+Also, I may reimplement a token based svcBackdoor since it can now be used to detect
+CFW's presence.
index 0d930a50a696f10ca2f0f5764e70e3ae407c357b..1586d8641c331a854e16a366415fad1de401c210 100644 (file)
@@ -130,6 +130,8 @@ int decrypt_firm(firm_h *dest, char *path_firmkey, uint32_t *size) {
        return 0;
 }
 
+extern int patch_services();
+
 int load_firm(firm_h *dest, char *path, char *path_firmkey, uint32_t *size, uint64_t firm_title) {
     int status = 0;
     int firmware_changed = 0;
@@ -247,10 +249,17 @@ void __attribute__((naked)) disable_lcds() {
 extern void wait();
 
 void boot_firm() {
+       struct firm_signature* fsig = get_firm_info(firm_loc);
+
     // Set up the keys needed to boot a few firmwares, due to them being unset, depending on which firmware you're booting from.
     // TODO: Don't use the hardcoded offset.
-    if (update_96_keys) {
-        void *keydata = (void *)((uintptr_t)firm_loc + firm_loc->section[2].offset + 0x89814);
+    if (update_96_keys && fsig->console == console_n3ds && fsig->version > 0x0F) {
+               void *keydata = NULL;
+               if (fsig->version == 0x1B || fsig->version == 0x1F) {
+                       keydata = (void *)((uintptr_t)firm_loc + firm_loc->section[2].offset + 0x89814);
+               } else if (fsig->version == 0x21) {
+                       keydata = (void *)((uintptr_t)firm_loc + firm_loc->section[2].offset + 0x89A14);
+               }
 
         aes_use_keyslot(0x11);
         uint8_t keyx[AES_BLOCK_SIZE];
index 8646c003871f9a59ba8294fb8d8a04917d29f303..cc77d17dbc549ce0059563671b3b7a5c36191d39 100644 (file)
@@ -5,38 +5,31 @@
 #include "../config.h"
 #include "../common.h"
 
-uint8_t* arm11Section1 = NULL;
-uint32_t *svc_tab_open = NULL, *exceptionsPage = NULL, *svcTable = NULL;
-int svc_offs_init = 0;
+uint32_t *getSvcAndExceptions(uint8_t *pos, uint32_t size, uint32_t **exceptionsPage) {
+    uint8_t pattern[] = {0x00, 0xB0, 0x9C, 0xE5}; //cpsid aif
 
-int patch_services() {
-       if (svc_offs_init == 0) {
-       arm11Section1 = (uint8_t*)firm_loc + firm_loc->section[1].offset;
+    *exceptionsPage = (uint32_t *)memfind(pos, size, pattern, 4) - 0xB;
 
-       uint8_t pattern[] = {0x00, 0xB0, 0x9C, 0xE5}; //cpsid aif
+    uint32_t svcOffset = (-(((*exceptionsPage)[2] & 0xFFFFFF) << 2) & (0xFFFFFF << 2)) - 8; //Branch offset + 8 for prefetch
+    uint32_t *svcTable = (uint32_t *)(pos + *(uint32_t *)(pos + 0xFFFF0008 - svcOffset - 0xFFF00000 + 8) - 0xFFF00000); //SVC handler address
+    while(*svcTable) svcTable++; //Look for SVC0 (NULL)
 
-       exceptionsPage = (uint32_t *)memfind(arm11Section1, firm_loc->section[1].size, pattern, 4) - 0xB;
+    return svcTable;
+}
 
-       uint32_t svcOffset = (-(((exceptionsPage)[2] & 0xFFFFFF) << 2) & (0xFFFFFF << 2)) - 8; //Branch offset + 8 for prefetch
-       svcTable = (uint32_t *)(arm11Section1 + *(uint32_t *)(arm11Section1 + 0xFFFF0008 - svcOffset - 0xFFF00000 + 8) - 0xFFF00000); //SVC handler address
-       while(*svcTable) svcTable++; //Look for SVC0 (NULL)
+uint32_t *freeSpace = NULL;
 
-               // Skip to free space
-               for(svc_tab_open = exceptionsPage; *svc_tab_open != 0xFFFFFFFF; svc_tab_open++);
-               svc_offs_init = 1;
-       }
+int patch_services() {
+    // Make sure svcBackdoor is there.
+    uint8_t* arm11Section1 = (uint8_t*)firm_loc + firm_loc->section[1].offset;
+    uint32_t *exceptionsPage;
+    uint32_t *svcTable = getSvcAndExceptions(arm11Section1, firm_loc->section[1].size, &exceptionsPage);
 
-       fprintf(stderr, "Svc Stubs:\n");
-       for (int i=0; i < 0xFF; i++) {
-               if(!svcTable[i]) {
-                       fprintf(stderr, "%d ", i);
-               }
-       }
-       fprintf(stderr, "\n");
+       fprintf(stderr, "Svc: table:%x\n", (uint32_t)svcTable);
 
-    // Make sure svcBackdoor is there.
     if(!svcTable[0x7B]) {
-               fprintf(stderr, "svc: 0x7B (backdoor) missing.\n");
+        // Firmware is missing svcBackdoor. Fix it.
+        fprintf(stderr, "Svc: inject 0x7B (backdoor)\n");
 
         // See extra/backdoor.s for the code to this.
         const unsigned char svcbackdoor[40] = {
@@ -45,14 +38,20 @@ int patch_services() {
             0x00, 0xD0, 0xA0, 0xE1, 0x11, 0xFF, 0x2F, 0xE1
         };
 
-        memcpy(svc_tab_open, svcbackdoor, sizeof(svcbackdoor));
-        svcTable[0x7B] = 0xFFFF0000 + ((uint8_t *)svc_tab_open - (uint8_t *)exceptionsPage);
+               if (!freeSpace) {
+                       for(freeSpace = exceptionsPage; *freeSpace != 0xFFFFFFFF; freeSpace++);
+               }
+
+               fprintf(stderr, "Svc: to:%x\n", (uint32_t)freeSpace);
+
+        memcpy(freeSpace, svcbackdoor, sizeof(svcbackdoor));
+        svcTable[0x7B] = 0xFFFF0000 + ((uint8_t *)freeSpace - (uint8_t *)exceptionsPage);
 
-               svc_tab_open += sizeof(svcbackdoor);
+               freeSpace += sizeof(svcbackdoor); // We keep track of this because there's more than 7B free.
 
-               fprintf(stderr, "svc: Injected 0x7B.\n");
+               fprintf(stderr, "Svc: ent:%x\n", svcTable[0x7B]);
     } else {
-               fprintf(stderr, "svc: No change needed.\n");
+        fprintf(stderr, "Svc: no change\n");
        }
 
        return 0;