From 72f028efaef75b4d1fac5eb484d3042d91374bc0 Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Fri, 30 Nov 2018 04:10:23 -0800 Subject: [PATCH] fusee: Implement built-in support for togglable nogc patches --- Makefile | 1 + ...E0377EF526CE6AD2AC6F2CAD7180CE69E74311.ips | Bin 0 -> 27 bytes ...6F10FB367A00BBD8B7D8D1F25CCE0B458D7E89.ips | Bin 0 -> 27 bytes ...AC2DF1E2BCAB3BC19DC5CD63DB6FAEC0947097.ips | Bin 0 -> 27 bytes ...0276B3EAD664DA79826FA936F99803B6C28F3B.ips | Bin 0 -> 27 bytes ...076B11737132EBB1484CF906B6A8EB3B1BF459.ips | Bin 0 -> 27 bytes ...CE4A5A1DA2D5C393F74224F8BC09DE4AAA4217.ips | Bin 0 -> 27 bytes ...CEBB93E3E9695C7CFD390F00509B1204101C24.ips | Bin 0 -> 27 bytes ...413B0B64CE03BD9BBFEB26F2B3E01C5427C69E.ips | Bin 0 -> 27 bytes ...785A0CD7AA9DC1A63C57D10049423DE7B77E2C.ips | Bin 0 -> 27 bytes ...2B32B432340DD2C7590CDEFC03E51B844AE805.ips | Bin 0 -> 27 bytes fusee/fusee-secondary/src/ips.c | 65 +++++++++++++++++- fusee/fusee-secondary/src/ips.h | 2 + fusee/fusee-secondary/src/nxboot.c | 22 ++++++ fusee/fusee-secondary/src/stratosphere.h | 3 + 15 files changed, 92 insertions(+), 1 deletion(-) create mode 100644 common/defaults/kip_patches/default_nogc/02D5ABAAFD20C8B0633AA0DBAEE0377EF526CE6AD2AC6F2CAD7180CE69E74311.ips create mode 100644 common/defaults/kip_patches/default_nogc/06E90719595A010C6246FF70946F10FB367A00BBD8B7D8D1F25CCE0B458D7E89.ips create mode 100644 common/defaults/kip_patches/default_nogc/10B2D81605488599DF2242CB6BAC2DF1E2BCAB3BC19DC5CD63DB6FAEC0947097.ips create mode 100644 common/defaults/kip_patches/default_nogc/330553F6B5FB55C4C2D7B736240276B3EAD664DA79826FA936F99803B6C28F3B.ips create mode 100644 common/defaults/kip_patches/default_nogc/3A574D436186191D1788EB2C0F076B11737132EBB1484CF906B6A8EB3B1BF459.ips create mode 100644 common/defaults/kip_patches/default_nogc/549B0F8D6F72C4E9F3FD1F19EACE4A5A1DA2D5C393F74224F8BC09DE4AAA4217.ips create mode 100644 common/defaults/kip_patches/default_nogc/76F87402C9387C0F0A2FAB1B45CEBB93E3E9695C7CFD390F00509B1204101C24.ips create mode 100644 common/defaults/kip_patches/default_nogc/8096AF7C6A35AA8271F3916995413B0B64CE03BD9BBFEB26F2B3E01C5427C69E.ips create mode 100644 common/defaults/kip_patches/default_nogc/A6F27AD9AC7C73AD419B63B23E785A0CD7AA9DC1A63C57D10049423DE7B77E2C.ips create mode 100644 common/defaults/kip_patches/default_nogc/CE3ECBA2F2F062F575F8F360842B32B432340DD2C7590CDEFC03E51B844AE805.ips diff --git a/Makefile b/Makefile index 6bcecf67f..9d8364e89 100644 --- a/Makefile +++ b/Makefile @@ -45,6 +45,7 @@ dist: all cp fusee/fusee-secondary/fusee-secondary.bin atmosphere-$(AMSVER)/fusee-secondary.bin cp common/defaults/BCT.ini atmosphere-$(AMSVER)/BCT.ini cp common/defaults/loader.ini atmosphere-$(AMSVER)/atmosphere/loader.ini + cp -r common/defaults/kip_patches atmosphere-$(AMSVER)/atmosphere/kip_patches cp stratosphere/creport/creport.nsp atmosphere-$(AMSVER)/atmosphere/titles/0100000000000036/exefs.nsp cp stratosphere/fatal/fatal.nsp atmosphere-$(AMSVER)/atmosphere/titles/0100000000000034/exefs.nsp cp stratosphere/set_mitm/set_mitm.nsp atmosphere-$(AMSVER)/atmosphere/titles/0100000000000032/exefs.nsp diff --git a/common/defaults/kip_patches/default_nogc/02D5ABAAFD20C8B0633AA0DBAEE0377EF526CE6AD2AC6F2CAD7180CE69E74311.ips b/common/defaults/kip_patches/default_nogc/02D5ABAAFD20C8B0633AA0DBAEE0377EF526CE6AD2AC6F2CAD7180CE69E74311.ips new file mode 100644 index 0000000000000000000000000000000000000000..62f99241b1fc0d676880aabf6c3e4d8057b4b823 GIT binary patch literal 27 icmWG=3~~10GTqC-*ub@B1p~(eW_hgx%<&= literal 0 HcmV?d00001 diff --git a/common/defaults/kip_patches/default_nogc/06E90719595A010C6246FF70946F10FB367A00BBD8B7D8D1F25CCE0B458D7E89.ips b/common/defaults/kip_patches/default_nogc/06E90719595A010C6246FF70946F10FB367A00BBD8B7D8D1F25CCE0B458D7E89.ips new file mode 100644 index 0000000000000000000000000000000000000000..7f1adb6e1a2fc09f477f590c1a133caa40ebbca2 GIT binary patch literal 27 icmWG=3~~10GL2+lY~Whs!ocx>SzhY^bNn?|e>VVM{RfHw literal 0 HcmV?d00001 diff --git a/common/defaults/kip_patches/default_nogc/10B2D81605488599DF2242CB6BAC2DF1E2BCAB3BC19DC5CD63DB6FAEC0947097.ips b/common/defaults/kip_patches/default_nogc/10B2D81605488599DF2242CB6BAC2DF1E2BCAB3BC19DC5CD63DB6FAEC0947097.ips new file mode 100644 index 0000000000000000000000000000000000000000..d8f050ed0da131200dc0e941dfda20dcd2c68dca GIT binary patch literal 27 icmWG=3~~10`7xD&v4OXufPv!yv%J;;=J;!_{%!ztWC(@; literal 0 HcmV?d00001 diff --git a/common/defaults/kip_patches/default_nogc/330553F6B5FB55C4C2D7B736240276B3EAD664DA79826FA936F99803B6C28F3B.ips b/common/defaults/kip_patches/default_nogc/330553F6B5FB55C4C2D7B736240276B3EAD664DA79826FA936F99803B6C28F3B.ips new file mode 100644 index 0000000000000000000000000000000000000000..26f1345d9fb6734b27a04e41387eaf77758f5dd4 GIT binary patch literal 27 icmWG=3~}}l{qU86u|c>+fq~-zv%J;;=J;!_{%!zxwg{;J literal 0 HcmV?d00001 diff --git a/common/defaults/kip_patches/default_nogc/3A574D436186191D1788EB2C0F076B11737132EBB1484CF906B6A8EB3B1BF459.ips b/common/defaults/kip_patches/default_nogc/3A574D436186191D1788EB2C0F076B11737132EBB1484CF906B6A8EB3B1BF459.ips new file mode 100644 index 0000000000000000000000000000000000000000..da978a82a58cd22218ac20bcbad99a2b0a66bf5a GIT binary patch literal 27 icmWG=3~}}lwfxG!*dTOPfq~-zv%J;;=J;!_{%!zm>Igaj literal 0 HcmV?d00001 diff --git a/common/defaults/kip_patches/default_nogc/549B0F8D6F72C4E9F3FD1F19EACE4A5A1DA2D5C393F74224F8BC09DE4AAA4217.ips b/common/defaults/kip_patches/default_nogc/549B0F8D6F72C4E9F3FD1F19EACE4A5A1DA2D5C393F74224F8BC09DE4AAA4217.ips new file mode 100644 index 0000000000000000000000000000000000000000..7f1adb6e1a2fc09f477f590c1a133caa40ebbca2 GIT binary patch literal 27 icmWG=3~~10GL2+lY~Whs!ocx>SzhY^bNn?|e>VVM{RfHw literal 0 HcmV?d00001 diff --git a/common/defaults/kip_patches/default_nogc/76F87402C9387C0F0A2FAB1B45CEBB93E3E9695C7CFD390F00509B1204101C24.ips b/common/defaults/kip_patches/default_nogc/76F87402C9387C0F0A2FAB1B45CEBB93E3E9695C7CFD390F00509B1204101C24.ips new file mode 100644 index 0000000000000000000000000000000000000000..d8f050ed0da131200dc0e941dfda20dcd2c68dca GIT binary patch literal 27 icmWG=3~~10`7xD&v4OXufPv!yv%J;;=J;!_{%!ztWC(@; literal 0 HcmV?d00001 diff --git a/common/defaults/kip_patches/default_nogc/8096AF7C6A35AA8271F3916995413B0B64CE03BD9BBFEB26F2B3E01C5427C69E.ips b/common/defaults/kip_patches/default_nogc/8096AF7C6A35AA8271F3916995413B0B64CE03BD9BBFEB26F2B3E01C5427C69E.ips new file mode 100644 index 0000000000000000000000000000000000000000..62f99241b1fc0d676880aabf6c3e4d8057b4b823 GIT binary patch literal 27 icmWG=3~~10GTqC-*ub@B1p~(eW_hgx%<&= literal 0 HcmV?d00001 diff --git a/common/defaults/kip_patches/default_nogc/A6F27AD9AC7C73AD419B63B23E785A0CD7AA9DC1A63C57D10049423DE7B77E2C.ips b/common/defaults/kip_patches/default_nogc/A6F27AD9AC7C73AD419B63B23E785A0CD7AA9DC1A63C57D10049423DE7B77E2C.ips new file mode 100644 index 0000000000000000000000000000000000000000..dd546f608b612e41343718cd381f60d203935bb8 GIT binary patch literal 27 icmWG=3~~10`Erzjv4OW_0RzVaW_hgx%<= sizeof(path)) { + return false; + } + + FILE *f = fopen(path, "rb"); + if (f != NULL) { + fclose(f); + return true; + } + return false; +} + +static bool has_needed_default_kip_patches(uint64_t title_id, const void *hash, size_t hash_size) { + if (title_id == 0x0100000000000000ULL && g_enable_nogc_patches) { + return has_patch("atmosphere/kip_patches", NOGC_PATCH_DIR, hash, hash_size); + } + + return true; +} + /* Applies an IPS/IPS32 patch to memory, disregarding writes to the first prot_size bytes. */ static void apply_ips_patch(uint8_t *mem, size_t mem_size, size_t prot_size, bool is_ips32, FILE *f_ips) { uint8_t buffer[4]; @@ -156,6 +203,11 @@ static bool has_ips_patches(const char *dir, const void *hash, size_t hash_size) if (strcmp(pdir_ent->d_name, ".") == 0 || strcmp(pdir_ent->d_name, "..") == 0) { continue; } + + if (should_ignore_default_patch(pdir_ent->d_name)) { + continue; + } + snprintf(path, sizeof(path) - 1, "%s/%s", dir, pdir_ent->d_name); DIR *patch_dir = opendir(path); struct dirent *ent; @@ -165,6 +217,7 @@ static bool has_ips_patches(const char *dir, const void *hash, size_t hash_size) if (strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0) { continue; } + size_t name_len = strlen(ent->d_name); if ((4 < name_len && name_len <= 0x44) && ((name_len & 1) == 0) && strcmp(ent->d_name + name_len - 4, ".ips") == 0 && name_matches_hash(ent->d_name, name_len, hash, hash_size)) { snprintf(path, sizeof(path) - 1, "%s/%s/%s", dir, pdir_ent->d_name, ent->d_name); @@ -200,6 +253,11 @@ static void apply_ips_patches(const char *dir, void *mem, size_t mem_size, size_ if (strcmp(pdir_ent->d_name, ".") == 0 || strcmp(pdir_ent->d_name, "..") == 0) { continue; } + + if (should_ignore_default_patch(pdir_ent->d_name)) { + continue; + } + snprintf(path, sizeof(path) - 1, "%s/%s", dir, pdir_ent->d_name); DIR *patch_dir = opendir(path); struct dirent *ent; @@ -209,6 +267,7 @@ static void apply_ips_patches(const char *dir, void *mem, size_t mem_size, size_ if (strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0) { continue; } + size_t name_len = strlen(ent->d_name); if ((4 < name_len && name_len <= 0x44) && ((name_len & 1) == 0) && strcmp(ent->d_name + name_len - 4, ".ips") == 0 && name_matches_hash(ent->d_name, name_len, hash, hash_size)) { snprintf(path, sizeof(path) - 1, "%s/%s/%s", dir, pdir_ent->d_name, ent->d_name); @@ -316,7 +375,11 @@ static kip1_header_t *kip1_uncompress(kip1_header_t *kip, size_t *size) { kip1_header_t *apply_kip_ips_patches(kip1_header_t *kip, size_t kip_size) { uint8_t hash[0x20]; se_calculate_sha256(hash, kip, kip_size); - + + if (!has_needed_default_kip_patches(kip->title_id, hash, sizeof(hash))) { + fatal_error("[NXBOOT]: Missing default patch for KIP %08x%08x...\n", (uint32_t)(kip->title_id >> 32), (uint32_t)kip->title_id); + } + if (!has_ips_patches("atmosphere/kip_patches", hash, sizeof(hash))) { return NULL; } diff --git a/fusee/fusee-secondary/src/ips.h b/fusee/fusee-secondary/src/ips.h index 6db00a1f1..f39e8b89c 100644 --- a/fusee/fusee-secondary/src/ips.h +++ b/fusee/fusee-secondary/src/ips.h @@ -24,4 +24,6 @@ void apply_kernel_ips_patches(void *kernel, size_t kernel_size); kip1_header_t *apply_kip_ips_patches(kip1_header_t *kip, size_t kip_size); +void kip_patches_set_enable_nogc(void); + #endif diff --git a/fusee/fusee-secondary/src/nxboot.c b/fusee/fusee-secondary/src/nxboot.c index eca9181c9..87703c90b 100644 --- a/fusee/fusee-secondary/src/nxboot.c +++ b/fusee/fusee-secondary/src/nxboot.c @@ -29,6 +29,8 @@ #include "se.h" #include "pmc.h" #include "i2c.h" +#include "ips.h" +#include "stratosphere.h" #include "max77620.h" #include "cluster.h" #include "flow.h" @@ -82,6 +84,23 @@ static int exosphere_ini_handler(void *user, const char *section, const char *na return 1; } +static int stratosphere_ini_handler(void *user, const char *section, const char *name, const char *value) { + int tmp = 0; + if (strcmp(section, "stratosphere") == 0) { + if (strcmp(name, STRATOSPHERE_NOGC_KEY) == 0) { + sscanf(value, "%d", &tmp); + if (tmp) { + kip_patches_set_enable_nogc(); + } + } else { + return 0; + } + } else { + return 0; + } + return 1; +} + static uint32_t nxboot_get_target_firmware(const void *package1loader) { const package1loader_header_t *package1loader_header = (const package1loader_header_t *)package1loader; switch (package1loader_header->version) { @@ -427,6 +446,9 @@ uint32_t nxboot_main(void) { print(SCREEN_LOG_LEVEL_MANDATORY, "[NXBOOT]: Rebuilding package2...\n"); /* Patch package2, adding Thermosphère + custom KIPs. */ + if (ini_parse_string(get_loader_ctx()->bct0, stratosphere_ini_handler, NULL) < 0) { + fatal_error("[NXBOOT]: Failed to parse BCT.ini!\n"); + } package2_rebuild_and_copy(package2, MAILBOX_EXOSPHERE_CONFIGURATION->target_firmware); print(SCREEN_LOG_LEVEL_INFO, u8"[NXBOOT]: Reading Exosphère...\n"); diff --git a/fusee/fusee-secondary/src/stratosphere.h b/fusee/fusee-secondary/src/stratosphere.h index 2ae43f1be..58caae31f 100644 --- a/fusee/fusee-secondary/src/stratosphere.h +++ b/fusee/fusee-secondary/src/stratosphere.h @@ -31,4 +31,7 @@ void stratosphere_free_ini1(void); ini1_header_t *stratosphere_merge_inis(ini1_header_t **inis, unsigned int num_inis); + +#define STRATOSPHERE_NOGC_KEY "nogc" + #endif