From df982a639096888f8ba3675e11ebd05520ac654a Mon Sep 17 00:00:00 2001 From: chaoskagami Date: Thu, 19 May 2016 18:22:33 -0400 Subject: [PATCH] More changes and code restructure. Just the usual, etc. --- doc/todo.md | 1 + external/loader/source/patcher.c | 2 +- external/service/Makefile | 2 +- external/service/stub.s | 6 +++ source/linker.c | 65 +++++++++--------------------- source/patch/base.c | 2 + source/patch/prot.c | 2 + source/patch/sig.c | 2 + source/patch/svc.c | 5 +++ vco/signatures/src/link_table.s | 1 - vco/template/linker.ld | 22 ---------- vco/template/src/link_table.s | 69 -------------------------------- vco/template/src/start.s | 37 ++++++++++++++++- 13 files changed, 73 insertions(+), 143 deletions(-) create mode 100644 doc/todo.md create mode 100644 external/service/stub.s delete mode 120000 vco/signatures/src/link_table.s delete mode 100644 vco/template/src/link_table.s diff --git a/doc/todo.md b/doc/todo.md new file mode 100644 index 0000000..751b634 --- /dev/null +++ b/doc/todo.md @@ -0,0 +1 @@ + * Attempt to create a replacement handler for Service 0x3D, AKA OutputDebugString(void const, int) to log to a file on SD. diff --git a/external/loader/source/patcher.c b/external/loader/source/patcher.c index 272ea5e..d679401 100644 --- a/external/loader/source/patcher.c +++ b/external/loader/source/patcher.c @@ -559,7 +559,7 @@ void patch_text(u64 progId, u8 *text, u32 size, u32 orig_size) { case 0x0004013000008002LL: // NS { disable_cart_updates(progId, text, orig_size); - adjust_cpu_settings(progId, text, orig_size); // DEFAULT cpu settings that are inherited system-wide. Per-app is handled in default. + adjust_cpu_settings(progId, text, orig_size); break; } diff --git a/external/service/Makefile b/external/service/Makefile index b390e72..3e2acda 100644 --- a/external/service/Makefile +++ b/external/service/Makefile @@ -1,6 +1,6 @@ PATH := $(PATH):$(DEVKITARM)/bin -all: 7b.bin +all: 7b.bin stub.bin %.o: %.s arm-none-eabi-as -o $@ $< diff --git a/external/service/stub.s b/external/service/stub.s new file mode 100644 index 0000000..7706777 --- /dev/null +++ b/external/service/stub.s @@ -0,0 +1,6 @@ +// This is not intended to be built, but is what a stub service's code is +.section .text +.global _start +_start: + ldr r0, =0xf8c007f4 + bx lr diff --git a/source/linker.c b/source/linker.c index 4ec769e..af13c19 100644 --- a/source/linker.c +++ b/source/linker.c @@ -2,50 +2,30 @@ #include "firm/fcram.h" #include "firm/firm.h" -extern void flush_cache(); - -extern firm_h *firm_loc; -extern exefs_h *firm_p9_exefs; - -extern firm_h *twl_firm_loc; -extern exefs_h *twl_firm_p9_exefs; +// Yes, this is EXACTLY what it looks like. We dynamically link and +// load patches as binaries; they use functions from corbenik to do +// the work, and therefore must have a function table in them. -extern firm_h *agb_firm_loc; -extern exefs_h *agb_firm_p9_exefs; +// See vco/template for how this magic works. -firm_h* __attribute__((optimize("O0"))) get_firm() { - return firm_loc; -} +// This ensures relatively small patches while also having incredible +// flexibility unlike a 'patch format'. -exefs_h* __attribute__((optimize("O0"))) get_firm_proc9_exefs() { +extern exefs_h* firm_p9_exefs; +exefs_h* get_firm_proc9_exefs() { return firm_p9_exefs; } -firm_h* __attribute__((optimize("O0"))) get_agb() { - return agb_firm_loc; +extern exefs_h* twl_firm_p9_exefs; +exefs_h* get_twl_proc9_exefs() { + return twl_firm_p9_exefs; } -exefs_h* __attribute__((optimize("O0"))) get_agb_proc9_exefs() { +extern exefs_h* agb_firm_p9_exefs; +exefs_h* get_agb_proc9_exefs() { return agb_firm_p9_exefs; } -firm_h* __attribute__((optimize("O0"))) get_twl() { - return twl_firm_loc; -} - -exefs_h* __attribute__((optimize("O0"))) get_twl_proc9_exefs() { - return twl_firm_p9_exefs; -} - -// Yes, this is EXACTLY what it looks like. We dynamically link and -// load patches as binaries; they use functions from corbenik to do -// the work, and therefore must have a function table in them. - -// See vco/template for how this magic works. - -// This ensures relatively small patches while also having incredible -// flexibility unlike a 'patch format'. - int execp(char* path) { int basename = 0; for(basename=strlen(path); basename > 0; basename--) @@ -53,7 +33,7 @@ int execp(char* path) { break; basename++; - fprintf(stderr, "Executing patchbin: %s\n", &path[basename]); + fprintf(stderr, "Exec: %s\n", &path[basename]); struct system_patch patch; @@ -70,14 +50,8 @@ int execp(char* path) { fclose(f); fprintf(stderr, "[s]"); - // Now then...find the magical number. - uint8_t magic[] = { 0xc0, 0x9b, 0xe5, 0x1c }; - uint32_t* link_table = (uint32_t*)memfind((uint8_t*)FCRAM_PATCHBIN_EXEC_LOC, patch.patch_size, magic, 4); - if (link_table == NULL) { - fprintf(stderr, "\n Table missing. Abort.\n"); - return 1; - } + uint32_t* link_table = (uint32_t*)(FCRAM_PATCHBIN_EXEC_LOC+4); fprintf(stderr, "[r]"); @@ -101,14 +75,11 @@ int execp(char* path) { link_table[26] = (uint32_t)fprintf; // Get functions - link_table[28] = (uint32_t)get_firm; - link_table[30] = (uint32_t)get_firm_proc9_exefs; + link_table[28] = (uint32_t)get_firm_proc9_exefs; - link_table[32] = (uint32_t)get_agb; - link_table[34] = (uint32_t)get_agb_proc9_exefs; + link_table[30] = (uint32_t)get_agb_proc9_exefs; - link_table[36] = (uint32_t)get_twl; - link_table[38] = (uint32_t)get_twl_proc9_exefs; + link_table[32] = (uint32_t)get_twl_proc9_exefs; fprintf(stderr, "[b]\n"); diff --git a/source/patch/base.c b/source/patch/base.c index fd12e79..68a35fd 100644 --- a/source/patch/base.c +++ b/source/patch/base.c @@ -5,6 +5,8 @@ #include "../config.h" #include "../common.h" +// Do you like examples? + int patch_test() { fprintf(stderr, "Testing, testing, 1, 2, 3, 4..\n"); diff --git a/source/patch/prot.c b/source/patch/prot.c index 76e92cc..f5acd74 100644 --- a/source/patch/prot.c +++ b/source/patch/prot.c @@ -5,6 +5,8 @@ #include "../config.h" #include "../common.h" +// This patch applies the FIRM protection code needed for safe a9lh usage. + int patch_firmprot() { uint8_t *firm_mem = (uint8_t*)firm_p9_exefs + sizeof(exefs_h) + firm_p9_exefs->fileHeaders[0].offset; uint32_t size = firm_p9_exefs->fileHeaders[0].size; diff --git a/source/patch/sig.c b/source/patch/sig.c index 3d0adbd..85ef948 100644 --- a/source/patch/sig.c +++ b/source/patch/sig.c @@ -5,6 +5,8 @@ #include "../config.h" #include "../common.h" +// This patch is responsible for fixing signature checks for the firmware. + int patch_signatures() { //Look for signature checks diff --git a/source/patch/svc.c b/source/patch/svc.c index 661a4be..ed2060d 100644 --- a/source/patch/svc.c +++ b/source/patch/svc.c @@ -5,6 +5,11 @@ #include "../config.h" #include "../common.h" +// This patch handles replacement of services. This includes backdoor, but not just backdoor. +// Any service can be replaced provided there's enough space within the exception page. + +// Please note that the actual code for services is in `external/service`. + uint32_t *getSvcAndExceptions(uint8_t *pos, uint32_t size, uint32_t **exceptionsPage) { uint8_t pattern[] = {0x00, 0xB0, 0x9C, 0xE5}; //cpsid aif diff --git a/vco/signatures/src/link_table.s b/vco/signatures/src/link_table.s deleted file mode 120000 index 501d0b2..0000000 --- a/vco/signatures/src/link_table.s +++ /dev/null @@ -1 +0,0 @@ -../../template/src/link_table.s \ No newline at end of file diff --git a/vco/template/linker.ld b/vco/template/linker.ld index 7d6129b..0a7a3ad 100644 --- a/vco/template/linker.ld +++ b/vco/template/linker.ld @@ -1,19 +1,3 @@ -/* This memory map is mainly to assist in doing stuff in code. -MEMORY -{ - INSTRUCTION_TCM (rw) : ORIGIN = 0x00000000, LENGTH = 0x08000000 - ARM_INTERNAL (rw) : ORIGIN = 0x08000000, LENGTH = 0x00100000 - NEW_INTERNAL (rw) : ORIGIN = 0x08100000, LENGTH = 0x00080000 - IO_MEMORY (rw) : ORIGIN = 0x10000000, LENGTH = 0x08000000 - VRAM (rw) : ORIGIN = 0x18000000, LENGTH = 0x00600000 - DSP_MEMORY (rw) : ORIGIN = 0x1FF00000, LENGTH = 0x00080000 - AXI_WRAM (rw) : ORIGIN = 0x1FF80000, LENGTH = 0x00080000 - FCRAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x08000000 - NEW_FCRAM (rwx) : ORIGIN = 0x28000000, LENGTH = 0x08000000 - DATA_TCM (rw) : ORIGIN = 0xFFF00000, LENGTH = 0x00004000 - BOOTROM (rw) : ORIGIN = 0xFFFF0000, LENGTH = 0x00010000 -} */ - ENTRY(_start) SECTIONS { @@ -25,12 +9,6 @@ SECTIONS } START_SECTION_END = .; - TABLE_SECTION = .; - .text.table : { - *(.text.table) - } - TABLE_SECTION_END = .; - TEXT_SECTION = .; .text : { *(.text) diff --git a/vco/template/src/link_table.s b/vco/template/src/link_table.s deleted file mode 100644 index 0c459b5..0000000 --- a/vco/template/src/link_table.s +++ /dev/null @@ -1,69 +0,0 @@ -.section .text.table -.align 4 - -.macro stub name - .global \name - \name : - ldr pc, [pc, #-4] // Load the data after this to the PC. return will be before this call. - bx lr // Fall through in case of error. -.endm - -// (int) [0] -.global MAGIC_START -MAGIC_START: - .byte 0xc0 - .byte 0x9b - .byte 0xe5 - .byte 0x1c - -// Exported functions. - -// memory.c -// (int) [3] -stub strlen -// (int) [5] -stub isprint -// (int) [7] -stub memcpy -// (int) [9] -stub memmove -// (int) [11] -stub memset -// (int) [13] -stub memcmp -// (int) [15] -stub strncpy -// (int) [17] -stub strncmp -// (int) [19] -stub atoi -// (int) [21] -stub memfind - -// draw.c -// (int) [23] -stub putc -// (int) [25] -stub puts -// (int) [27] -stub fprintf - -// Wrappers to get shit. - -// Gets NATIVE_FIRM memory offset as (firm_h*) -stub get_firm - -// Get NATIVE_FIRM process9 -stub get_firm_proc9_exefs - -// Gets AGB_FIRM. -stub get_agb - -// Get AGB_FIRM process9 exefs -stub get_agb_proc9_exefs - -// Gets TWL_FIRM. -stub get_twl - -// Get TWL_FIRM process9 exefs -stub get_twl_proc9_exefs diff --git a/vco/template/src/start.s b/vco/template/src/start.s index 441e530..5898ae6 100644 --- a/vco/template/src/start.s +++ b/vco/template/src/start.s @@ -3,5 +3,38 @@ .global _start _start: b main -_die: - b _die // I have no clue how one would end up here. + +.macro stub name + .global \name + \name : + ldr pc, [pc, #-4] // Load the data after this to the PC. return will be before this call. + bx lr // Fall through in case of error. +.endm + +// memory.c +stub strlen +stub isprint +stub memcpy +stub memmove +stub memset +stub memcmp +stub strncpy +stub strncmp +stub atoi +stub memfind + +// draw.c +stub putc +stub puts +stub fprintf + +// Wrappers to get shit. + +// Get NATIVE_FIRM process9 +stub get_firm_proc9_exefs + +// Get AGB_FIRM process9 exefs +stub get_agb_proc9_exefs + +// Get TWL_FIRM process9 exefs +stub get_twl_proc9_exefs -- 2.39.5