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 000000000..62f99241b Binary files /dev/null and b/common/defaults/kip_patches/default_nogc/02D5ABAAFD20C8B0633AA0DBAEE0377EF526CE6AD2AC6F2CAD7180CE69E74311.ips differ 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 000000000..7f1adb6e1 Binary files /dev/null and b/common/defaults/kip_patches/default_nogc/06E90719595A010C6246FF70946F10FB367A00BBD8B7D8D1F25CCE0B458D7E89.ips differ 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 000000000..d8f050ed0 Binary files /dev/null and b/common/defaults/kip_patches/default_nogc/10B2D81605488599DF2242CB6BAC2DF1E2BCAB3BC19DC5CD63DB6FAEC0947097.ips differ 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 000000000..26f1345d9 Binary files /dev/null and b/common/defaults/kip_patches/default_nogc/330553F6B5FB55C4C2D7B736240276B3EAD664DA79826FA936F99803B6C28F3B.ips differ 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 000000000..da978a82a Binary files /dev/null and b/common/defaults/kip_patches/default_nogc/3A574D436186191D1788EB2C0F076B11737132EBB1484CF906B6A8EB3B1BF459.ips differ 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 000000000..7f1adb6e1 Binary files /dev/null and b/common/defaults/kip_patches/default_nogc/549B0F8D6F72C4E9F3FD1F19EACE4A5A1DA2D5C393F74224F8BC09DE4AAA4217.ips differ 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 000000000..d8f050ed0 Binary files /dev/null and b/common/defaults/kip_patches/default_nogc/76F87402C9387C0F0A2FAB1B45CEBB93E3E9695C7CFD390F00509B1204101C24.ips differ 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 000000000..62f99241b Binary files /dev/null and b/common/defaults/kip_patches/default_nogc/8096AF7C6A35AA8271F3916995413B0B64CE03BD9BBFEB26F2B3E01C5427C69E.ips differ 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 000000000..dd546f608 Binary files /dev/null and b/common/defaults/kip_patches/default_nogc/A6F27AD9AC7C73AD419B63B23E785A0CD7AA9DC1A63C57D10049423DE7B77E2C.ips differ diff --git a/common/defaults/kip_patches/default_nogc/CE3ECBA2F2F062F575F8F360842B32B432340DD2C7590CDEFC03E51B844AE805.ips b/common/defaults/kip_patches/default_nogc/CE3ECBA2F2F062F575F8F360842B32B432340DD2C7590CDEFC03E51B844AE805.ips new file mode 100644 index 000000000..dd546f608 Binary files /dev/null and b/common/defaults/kip_patches/default_nogc/CE3ECBA2F2F062F575F8F360842B32B432340DD2C7590CDEFC03E51B844AE805.ips differ diff --git a/fusee/fusee-secondary/src/ips.c b/fusee/fusee-secondary/src/ips.c index 41c2840a6..036789789 100644 --- a/fusee/fusee-secondary/src/ips.c +++ b/fusee/fusee-secondary/src/ips.c @@ -33,6 +33,53 @@ #define IPS32_MAGIC "IPS32" #define IPS32_TAIL "EEOF" +#define NOGC_PATCH_DIR "default_nogc" +static bool g_enable_nogc_patches = false; + +void kip_patches_set_enable_nogc(void) { + g_enable_nogc_patches = true; +} + +static bool should_ignore_default_patch(const char *patch_dir) { + /* This function will ensure that select default patches only get loaded if enabled. */ + if (!g_enable_nogc_patches && strcmp(patch_dir, NOGC_PATCH_DIR) == 0) { + return true; + } + + return false; +} + +static bool has_patch(const char *dir, const char *subdir, const void *hash, size_t hash_size) { + char path[0x301] = {0}; + int cur_len = 0; + cur_len += snprintf(path + cur_len, sizeof(path) - cur_len, "%s/", dir); + if (subdir != NULL) { + cur_len += snprintf(path + cur_len, sizeof(path) - cur_len, "%s/", subdir); + } + for (size_t i = 0; i < hash_size; i++) { + cur_len += snprintf(path + cur_len, sizeof(path) - cur_len, "%02X", ((const uint8_t *)hash)[i]); + } + cur_len += snprintf(path + cur_len, sizeof(path) - cur_len, ".ips"); + if (cur_len >= 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