From: root Date: Tue, 17 May 2016 06:45:10 +0000 (-0400) Subject: Fix 0x21 key handling (wow me) X-Git-Tag: stable-1~70 X-Git-Url: https://chaos.moe/g/?a=commitdiff_plain;h=5ea13d2a698469507933e5832c8790972d84fa90;p=corbenik%2Fcorbenik.git Fix 0x21 key handling (wow me) --- diff --git a/doc/firmware.md b/doc/firmware.md index 884edb0..89c08f1 100644 --- a/doc/firmware.md +++ b/doc/firmware.md @@ -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. diff --git a/source/firm/firm.c b/source/firm/firm.c index 0d930a5..1586d86 100644 --- a/source/firm/firm.c +++ b/source/firm/firm.c @@ -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]; diff --git a/source/patch/svc.c b/source/patch/svc.c index 8646c00..cc77d17 100644 --- a/source/patch/svc.c +++ b/source/patch/svc.c @@ -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;