From e6644874cfabaad7b84cb14fbbef34257d73cd39 Mon Sep 17 00:00:00 2001 From: root Date: Tue, 17 May 2016 01:52:06 -0400 Subject: [PATCH] Svc patcher? Yeah, svc patcher. --- source/config.h | 19 ++++++++------- source/menu.c | 11 +++++---- source/patch/svc.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++ source/patcher.c | 8 +++++++ 4 files changed, 83 insertions(+), 14 deletions(-) create mode 100644 source/patch/svc.c diff --git a/source/config.h b/source/config.h index f4a6abe..bb2a949 100644 --- a/source/config.h +++ b/source/config.h @@ -20,18 +20,19 @@ extern struct config_file config; #define OPTION_SIGPATCH 0 // Use builtin signature patch. #define OPTION_FIRMPROT 1 // Protect firmware from writes. #define OPTION_LOADER 2 // Use builtin loader module replacer. -#define OPTION_ARM9THREAD 3 // Use builtin ARM9 thread injector. +#define OPTION_SERVICES 3 // Inject services (including backdoor for 11) +#define OPTION_ARM9THREAD 4 // Use builtin ARM9 thread injector. -#define OPTION_AUTOBOOT 4 // Skip menu unless L is held. -#define OPTION_SILENCE 5 // Don't print debug information. -#define OPTION_TRACE 6 // Pause for A key on each step. +#define OPTION_AUTOBOOT 5 // Skip menu unless L is held. +#define OPTION_SILENCE 6 // Don't print debug information. +#define OPTION_TRACE 7 // Pause for A key on each step. -#define OPTION_TRANSP_BG 7 // Background color is not drawn under text. -#define OPTION_NO_CLEAR_BG 8 // Framebuffer is preserved from whatever ran before us. -#define OPTION_READ_ME 9 // Remove Help/Readme from menu. +#define OPTION_TRANSP_BG 8 // Background color is not drawn under text. +#define OPTION_NO_CLEAR_BG 9 // Framebuffer is preserved from whatever ran before us. +#define OPTION_READ_ME 10 // Remove Help/Readme from menu. -#define IGNORE_PATCH_DEPS 10 // Ignore patch UUID dependencies. Not recommended. -#define IGNORE_BROKEN_SHIT 11 // Allow enabling patches which are marked as 'incompatible'. Chances are there's a reason. +#define IGNORE_PATCH_DEPS 11 // Ignore patch UUID dependencies. Not recommended. +#define IGNORE_BROKEN_SHIT 12 // Allow enabling patches which are marked as 'incompatible'. Chances are there's a reason. //#define HEADER_COLOR 12 // Color of header text. //#define BG_COLOR 13 // Color of background. diff --git a/source/menu.c b/source/menu.c index 53429f4..4336e2e 100644 --- a/source/menu.c +++ b/source/menu.c @@ -60,12 +60,13 @@ int menu_options() { const char *list[] = { "Signature Patch", "FIRM Write Protection", - "Inject Loader", + "Inject Loader (NYI)", + "Inject Services", "Enable ARM9 Thread", - "Autoboot (NYI)", - "Silence debug output (NYI)", - "Pause for input as trace", + "Autoboot", + "Silence debug w/ autoboot", + "Pause for input on steps", "Don't draw background color (NYI)", "Preserve current framebuffer (NYI)", @@ -74,7 +75,7 @@ int menu_options() { "Ignore dependencies (NYI)", "Allow enabling broken (NYI)", }; - const int menu_max = 11; + const int menu_max = 12; header(); diff --git a/source/patch/svc.c b/source/patch/svc.c new file mode 100644 index 0000000..8646c00 --- /dev/null +++ b/source/patch/svc.c @@ -0,0 +1,59 @@ +#include +#include "../std/unused.h" +#include "../std/memory.h" +#include "../firm/firm.h" +#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; + +int patch_services() { + if (svc_offs_init == 0) { + arm11Section1 = (uint8_t*)firm_loc + firm_loc->section[1].offset; + + uint8_t pattern[] = {0x00, 0xB0, 0x9C, 0xE5}; //cpsid aif + + exceptionsPage = (uint32_t *)memfind(arm11Section1, firm_loc->section[1].size, pattern, 4) - 0xB; + + 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) + + // Skip to free space + for(svc_tab_open = exceptionsPage; *svc_tab_open != 0xFFFFFFFF; svc_tab_open++); + svc_offs_init = 1; + } + + fprintf(stderr, "Svc Stubs:\n"); + for (int i=0; i < 0xFF; i++) { + if(!svcTable[i]) { + fprintf(stderr, "%d ", i); + } + } + fprintf(stderr, "\n"); + + // Make sure svcBackdoor is there. + if(!svcTable[0x7B]) { + fprintf(stderr, "svc: 0x7B (backdoor) missing.\n"); + + // See extra/backdoor.s for the code to this. + const unsigned char svcbackdoor[40] = { + 0xFF, 0x10, 0xCD, 0xE3, 0x0F, 0x1C, 0x81, 0xE3, 0x28, 0x10, 0x81, 0xE2, 0x00, 0x20, 0x91, 0xE5, + 0x00, 0x60, 0x22, 0xE9, 0x02, 0xD0, 0xA0, 0xE1, 0x30, 0xFF, 0x2F, 0xE1, 0x03, 0x00, 0xBD, 0xE8, + 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); + + svc_tab_open += sizeof(svcbackdoor); + + fprintf(stderr, "svc: Injected 0x7B.\n"); + } else { + fprintf(stderr, "svc: No change needed.\n"); + } + + return 0; +} diff --git a/source/patcher.c b/source/patcher.c index 0527051..5cccb03 100644 --- a/source/patcher.c +++ b/source/patcher.c @@ -12,6 +12,7 @@ int execp(char* path); extern int patch_signatures(); extern int patch_firmprot(); +extern int patch_services(); // A portion of this file is inherited from Luma3DS. /*u32 getLoader(u8 *pos, u32 *loaderSize) { @@ -79,6 +80,13 @@ int patch_firm_all() { // This requires OPTION_SIGPATCH. } + // Replace loader? + if (config.options[OPTION_SERVICES]) { + if(patch_services()) { + abort("Fatal. Service patch has failed."); + } + } + // Use ARM9 hook thread? if (config.options[OPTION_ARM9THREAD]) { // Yes. -- 2.39.5