mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2024-11-26 13:52:21 +00:00
fusee: Implement built-in support for togglable nogc patches
This commit is contained in:
parent
72a2c10896
commit
72f028efae
15 changed files with 92 additions and 1 deletions
1
Makefile
1
Makefile
|
@ -45,6 +45,7 @@ dist: all
|
||||||
cp fusee/fusee-secondary/fusee-secondary.bin atmosphere-$(AMSVER)/fusee-secondary.bin
|
cp fusee/fusee-secondary/fusee-secondary.bin atmosphere-$(AMSVER)/fusee-secondary.bin
|
||||||
cp common/defaults/BCT.ini atmosphere-$(AMSVER)/BCT.ini
|
cp common/defaults/BCT.ini atmosphere-$(AMSVER)/BCT.ini
|
||||||
cp common/defaults/loader.ini atmosphere-$(AMSVER)/atmosphere/loader.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/creport/creport.nsp atmosphere-$(AMSVER)/atmosphere/titles/0100000000000036/exefs.nsp
|
||||||
cp stratosphere/fatal/fatal.nsp atmosphere-$(AMSVER)/atmosphere/titles/0100000000000034/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
|
cp stratosphere/set_mitm/set_mitm.nsp atmosphere-$(AMSVER)/atmosphere/titles/0100000000000032/exefs.nsp
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -33,6 +33,53 @@
|
||||||
#define IPS32_MAGIC "IPS32"
|
#define IPS32_MAGIC "IPS32"
|
||||||
#define IPS32_TAIL "EEOF"
|
#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. */
|
/* 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) {
|
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];
|
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) {
|
if (strcmp(pdir_ent->d_name, ".") == 0 || strcmp(pdir_ent->d_name, "..") == 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (should_ignore_default_patch(pdir_ent->d_name)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
snprintf(path, sizeof(path) - 1, "%s/%s", dir, pdir_ent->d_name);
|
snprintf(path, sizeof(path) - 1, "%s/%s", dir, pdir_ent->d_name);
|
||||||
DIR *patch_dir = opendir(path);
|
DIR *patch_dir = opendir(path);
|
||||||
struct dirent *ent;
|
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) {
|
if (strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t name_len = strlen(ent->d_name);
|
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)) {
|
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);
|
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) {
|
if (strcmp(pdir_ent->d_name, ".") == 0 || strcmp(pdir_ent->d_name, "..") == 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (should_ignore_default_patch(pdir_ent->d_name)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
snprintf(path, sizeof(path) - 1, "%s/%s", dir, pdir_ent->d_name);
|
snprintf(path, sizeof(path) - 1, "%s/%s", dir, pdir_ent->d_name);
|
||||||
DIR *patch_dir = opendir(path);
|
DIR *patch_dir = opendir(path);
|
||||||
struct dirent *ent;
|
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) {
|
if (strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t name_len = strlen(ent->d_name);
|
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)) {
|
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);
|
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) {
|
kip1_header_t *apply_kip_ips_patches(kip1_header_t *kip, size_t kip_size) {
|
||||||
uint8_t hash[0x20];
|
uint8_t hash[0x20];
|
||||||
se_calculate_sha256(hash, kip, kip_size);
|
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))) {
|
if (!has_ips_patches("atmosphere/kip_patches", hash, sizeof(hash))) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,4 +24,6 @@
|
||||||
void apply_kernel_ips_patches(void *kernel, size_t kernel_size);
|
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);
|
kip1_header_t *apply_kip_ips_patches(kip1_header_t *kip, size_t kip_size);
|
||||||
|
|
||||||
|
void kip_patches_set_enable_nogc(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -29,6 +29,8 @@
|
||||||
#include "se.h"
|
#include "se.h"
|
||||||
#include "pmc.h"
|
#include "pmc.h"
|
||||||
#include "i2c.h"
|
#include "i2c.h"
|
||||||
|
#include "ips.h"
|
||||||
|
#include "stratosphere.h"
|
||||||
#include "max77620.h"
|
#include "max77620.h"
|
||||||
#include "cluster.h"
|
#include "cluster.h"
|
||||||
#include "flow.h"
|
#include "flow.h"
|
||||||
|
@ -82,6 +84,23 @@ static int exosphere_ini_handler(void *user, const char *section, const char *na
|
||||||
return 1;
|
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) {
|
static uint32_t nxboot_get_target_firmware(const void *package1loader) {
|
||||||
const package1loader_header_t *package1loader_header = (const package1loader_header_t *)package1loader;
|
const package1loader_header_t *package1loader_header = (const package1loader_header_t *)package1loader;
|
||||||
switch (package1loader_header->version) {
|
switch (package1loader_header->version) {
|
||||||
|
@ -427,6 +446,9 @@ uint32_t nxboot_main(void) {
|
||||||
print(SCREEN_LOG_LEVEL_MANDATORY, "[NXBOOT]: Rebuilding package2...\n");
|
print(SCREEN_LOG_LEVEL_MANDATORY, "[NXBOOT]: Rebuilding package2...\n");
|
||||||
|
|
||||||
/* Patch package2, adding Thermosphère + custom KIPs. */
|
/* 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);
|
package2_rebuild_and_copy(package2, MAILBOX_EXOSPHERE_CONFIGURATION->target_firmware);
|
||||||
|
|
||||||
print(SCREEN_LOG_LEVEL_INFO, u8"[NXBOOT]: Reading Exosphère...\n");
|
print(SCREEN_LOG_LEVEL_INFO, u8"[NXBOOT]: Reading Exosphère...\n");
|
||||||
|
|
|
@ -31,4 +31,7 @@ void stratosphere_free_ini1(void);
|
||||||
|
|
||||||
ini1_header_t *stratosphere_merge_inis(ini1_header_t **inis, unsigned int num_inis);
|
ini1_header_t *stratosphere_merge_inis(ini1_header_t **inis, unsigned int num_inis);
|
||||||
|
|
||||||
|
|
||||||
|
#define STRATOSPHERE_NOGC_KEY "nogc"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue