From 3da8f21d205cd6b8aff313aa604ef09dc9895881 Mon Sep 17 00:00:00 2001
From: TotalJustice <47043333+ITotalJustice@users.noreply.github.com>
Date: Fri, 26 May 2023 21:51:45 +0100
Subject: [PATCH 01/45] add ctest patch, add per patch toggle, made overlay
more organised
---
Makefile | 2 +-
README.md | 70 +++++++-------
overlay/src/main.cpp | 149 +++++++++++++++++++++++++-----
sysmod/src/main.cpp | 212 ++++++++++++++++++++++++++-----------------
4 files changed, 288 insertions(+), 145 deletions(-)
diff --git a/Makefile b/Makefile
index 3536911..6a53e19 100644
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@ MAKEFILES := sysmod overlay
TARGETS := $(foreach dir,$(MAKEFILES),$(CURDIR)/$(dir))
# the below was taken from atmosphere + switch-examples makefile
-export VERSION := 1.3.0
+export VERSION := 1.4.0
export GIT_BRANCH := $(shell git symbolic-ref --short HEAD)
ifeq ($(strip $(shell git status --porcelain 2>/dev/null)),)
diff --git a/README.md b/README.md
index 6d293de..20c133e 100644
--- a/README.md
+++ b/README.md
@@ -1,14 +1,14 @@
# sys-patch
-A script-like system module that patches fs, es and ldr on boot.
+A script-like system module that patches **fs**, **es**, **ldr** and **nifm** on boot.
---
## Config
-sys-patch features a simple config. This can be manually editied or updated using the overlay.
+**sys-patch** features a simple config. This can be manually edited or updated using the overlay.
-the config file can be found in `/config/sys-patch/config.ini`, if the file does not exist, the file will be created when sys-patch is run.
+The configuration file can be found in `/config/sys-patch/config.ini`. The file is generated once the module is ran for the first time.
```ini
[options]
@@ -22,11 +22,11 @@ version_skip=1 ; 1=(default) skips out of date patterns, 0=search all patterns
## Overlay
-the overlay can be used to change the config options and to see what patches are applied (if any).
+The overlay can be used to change the config options and to see what patches are applied.
- Unpatched means the patch wasn't applied (likely not found).
- Patched (green) means it was patched by sys-patch.
-- Patched (yellow) means it was already patched, likely by sigpatches or a custom atmosphere build.
+- Patched (yellow) means it was already patched, likely by sigpatches or a custom Atmosphere build.
@@ -40,63 +40,59 @@ the overlay can be used to change the config options and to see what patches are
## Building
### prerequisites
-- install devkitpro
+- Install [devkitpro](https://devkitpro.org/wiki/Getting_Started)
+- Run the following:
+ ```sh
+ git clone --recurse-submodules https://github.com/ITotalJustice/sys-patch.git
+ cd ./sys-patch
+ make
+ ```
-```sh
-git clone --recurse-submodules https://github.com/ITotalJustice/sys-patch.git
-cd sys-patch
-make
-```
-
-the output of `out/` can be copied to your sd card. for the sysmodule to take effect, rebot your switch, or, use [sysmodules overlay](https://github.com/WerWolv/ovl-sysmodules/tree/master/source) to start it.
+The output of `out/` can be copied to your SD card.
+To activate the sys-module, reboot your switch, or, use [sysmodules overlay](https://github.com/WerWolv/ovl-sysmodules/releases/latest) with the accompanying overlay to activate it.
---
## What is being patched?
-Here's a quick run down of what's being patched
-
-- fs
-- es
-- ldr
-
-fs and es need new patches after every new fw version.
+Here's a quick run down of what's being patched:
-ldr on the other hand needs new patches after every new atmosphere release. this is due to ldr service being reimplemented by atmosphere. in fw 10.0.0, a new check was added to ofw which we needed to patch out. As atmosphere closely follows what ofw does, it also added this check. This is why a new patch is needed per atmosphere update.
+- **fs**
+- **es**
+- **ldr**
+- **nifm**
----
-
-## How does it work?
+**fs** and **es** need new patches after every new firmware version.
+**ldr** needs new patches after every new [Atmosphere](https://github.com/Atmosphere-NX/Atmosphere/) release.
+**nifm** ctest patch allows the device to connect to a network without needing to make a connection to a server.
-it uses a collection of patterns to find the piece of code to patch. alternatively, it could just use offsets, however this would mean this tool would have to be updated after every new fw update, that's not ideal.
-
-the patches are applied at boot, then, the sysmod stops running. the memory footpint of the sysmod is very very small, only using 16kib in total. the size of the binary itself is only ~50kib! this doesnt really mean much, but im pretty proud of it :)
+The patches are applied on boot. Once done, the sys-module stops running.
+The memory footprint *(16kib)* and the binary size *(~50kib)* are both very small.
---
-## Does this mean i should stop downloading / using sigpatches?
+## FAQ:
-No, i would personally recommend continuing to use sigpatches. Reason being is that should this tool ever break, i likely wont be quick to fix it.
+### If I am using sigpatches already, is there any point in using this?
----
+Yes, in 3 situations.
-## If i am using sigpatches already, is there any point in using this as well?
+1. A new **ldr** patch needs to be created after every Atmosphere update. Sometimes, a new silent Atmosphere update is released. This tool will always patch **ldr** without having to update patches.
-Yes, in 2 niche cases.
+2. Building Atmosphere from src will require you to generate a new **ldr** patch for that custom built Atmosphere. This is easy enough due to the public scripts / tools that exist out there, however this will always be able to patch **ldr**.
-1. A new ldr patch needs to be created after every atmosphere update. Sometimes, a new silent atmosphere update is released. This tool will always patch ldr without having to update patches.
+3. If you forget to update your patches when you update your firmware / Atmosphere, this sys-module should be able to patch everything. So it can be used as a fall back.
-2. Building atmosphere from src will require you to generate a new ldr patch for that custom built atmosphere. This is easy enough due to the public scripts / tools that exist out there, however this will always be able to
+### Does this mean that I should stop downloading / using sigpatches?
-Also, if you forget to update your patches when you update fw / atmosphere, this sysmod should be able to patch everything just fine! so it's nice to have as a fallback.
+No, I would personally recommend continuing to use sigpatches. Reason being is that should this tool ever break, i likely wont be quick to fix it.
---
## Credits / Thanks
-software is built on the shoulders of giants. this tool wouldn't be possible wthout these people:
+Software is built on the shoulders of giants. This tool wouldn't be possible without these people:
-- DarkMatterCore
- MrDude
- BornToHonk (farni)
- TeJay
diff --git a/overlay/src/main.cpp b/overlay/src/main.cpp
index 402742c..7feef65 100644
--- a/overlay/src/main.cpp
+++ b/overlay/src/main.cpp
@@ -43,12 +43,10 @@ auto create_dir(const char* path) -> bool {
}
struct ConfigEntry {
- const char* const section;
- const char* const key;
- bool value;
-
ConfigEntry(const char* _section, const char* _key, bool default_value) :
- section{_section}, key{_key}, value{default_value} {}
+ section{_section}, key{_key}, value{default_value} {
+ this->load_value_from_ini();
+ }
void load_value_from_ini() {
this->value = ini_getbool(this->section, this->key, this->value, CONFIG_PATH);
@@ -62,23 +60,17 @@ struct ConfigEntry {
});
return item;
}
+
+ const char* const section;
+ const char* const key;
+ bool value;
};
-class GuiMain final : public tsl::Gui {
+class GuiOptions final : public tsl::Gui {
public:
- GuiMain() { }
+ GuiOptions() { }
- // Called when this Gui gets loaded to create the UI
- // Allocate all elements on the heap. libtesla will make sure to clean them up when not needed anymore
tsl::elm::Element* createUI() override {
- create_dir("/config/");
- create_dir("/config/sys-patch/");
-
- config_patch_sysmmc.load_value_from_ini();
- config_patch_emummc.load_value_from_ini();
- config_logging.load_value_from_ini();
- config_version_skip.load_value_from_ini();
-
auto frame = new tsl::elm::OverlayFrame("sys-patch", VERSION_WITH_HASH);
auto list = new tsl::elm::List();
@@ -88,6 +80,74 @@ class GuiMain final : public tsl::Gui {
list->addItem(config_logging.create_list_item("Logging"));
list->addItem(config_version_skip.create_list_item("Version skip"));
+ frame->setContent(list);
+ return frame;
+ }
+
+ ConfigEntry config_patch_sysmmc{"options", "patch_sysmmc", true};
+ ConfigEntry config_patch_emummc{"options", "patch_emummc", true};
+ ConfigEntry config_logging{"options", "patch_logging", true};
+ ConfigEntry config_version_skip{"options", "version_skip", true};
+};
+
+class GuiToggle final : public tsl::Gui {
+public:
+ GuiToggle() { }
+
+ tsl::elm::Element* createUI() override {
+ auto frame = new tsl::elm::OverlayFrame("sys-patch", VERSION_WITH_HASH);
+ auto list = new tsl::elm::List();
+
+ list->addItem(new tsl::elm::CategoryHeader("FS - 0100000000000000"));
+ list->addItem(config_noacidsigchk1.create_list_item("noacidsigchk1"));
+ list->addItem(config_noacidsigchk2.create_list_item("noacidsigchk2"));
+ list->addItem(config_noncasigchk_old.create_list_item("noncasigchk_old"));
+ list->addItem(config_noncasigchk_new.create_list_item("noncasigchk_new"));
+ list->addItem(config_nocntchk_old.create_list_item("nocntchk_old"));
+ list->addItem(config_nocntchk_new.create_list_item("nocntchk_new"));
+
+ list->addItem(new tsl::elm::CategoryHeader("LDR - 0100000000000001"));
+ list->addItem(config_noacidsigchk.create_list_item("noacidsigchk"));
+
+ list->addItem(new tsl::elm::CategoryHeader("ES - 0100000000000033"));
+ list->addItem(config_es1.create_list_item("es1"));
+ list->addItem(config_es2.create_list_item("es2"));
+ list->addItem(config_es3.create_list_item("es3"));
+ list->addItem(config_es4.create_list_item("es4"));
+ list->addItem(config_es5.create_list_item("es5"));
+ list->addItem(config_es6.create_list_item("es6"));
+
+ list->addItem(new tsl::elm::CategoryHeader("NIFM - 010000000000000F"));
+ list->addItem(config_ctest.create_list_item("ctest"));
+
+ frame->setContent(list);
+ return frame;
+ }
+
+ ConfigEntry config_noacidsigchk1{"fs", "noacidsigchk1", true};
+ ConfigEntry config_noacidsigchk2{"fs", "noacidsigchk2", true};
+ ConfigEntry config_noncasigchk_old{"fs", "noncasigchk_old", true};
+ ConfigEntry config_noncasigchk_new{"fs", "noncasigchk_new", true};
+ ConfigEntry config_nocntchk_old{"fs", "nocntchk_old", true};
+ ConfigEntry config_nocntchk_new{"fs", "nocntchk_new", true};
+ ConfigEntry config_noacidsigchk{"ldr", "noacidsigchk", true};
+ ConfigEntry config_es1{"es", "es1", true};
+ ConfigEntry config_es2{"es", "es2", true};
+ ConfigEntry config_es3{"es", "es3", true};
+ ConfigEntry config_es4{"es", "es4", true};
+ ConfigEntry config_es5{"es", "es5", true};
+ ConfigEntry config_es6{"es", "es6", true};
+ ConfigEntry config_ctest{"nifm", "ctest", false};
+};
+
+class GuiLog final : public tsl::Gui {
+public:
+ GuiLog() { }
+
+ tsl::elm::Element* createUI() override {
+ auto frame = new tsl::elm::OverlayFrame("sys-patch", VERSION_WITH_HASH);
+ auto list = new tsl::elm::List();
+
if (does_file_exist(LOG_PATH)) {
struct CallbackUser {
tsl::elm::List* list;
@@ -119,7 +179,7 @@ class GuiMain final : public tsl::Gui {
} else {
user->list->addItem(new tsl::elm::ListItem(Key, "Patched", colour_file));
}
- } else if (value.starts_with("Unpatched")) {
+ } else if (value.starts_with("Unpatched") || value.starts_with("Disabled")) {
user->list->addItem(new tsl::elm::ListItem(Key, Value, colour_unpatched));
} else if (user->last_section == "stats") {
user->list->addItem(new tsl::elm::ListItem(Key, Value, tsl::style::color::ColorDescription));
@@ -130,17 +190,58 @@ class GuiMain final : public tsl::Gui {
return 1;
}, &callback_userdata, LOG_PATH);
} else {
-
+ list->addItem(new tsl::elm::ListItem("No log found!"));
}
frame->setContent(list);
return frame;
}
+};
- ConfigEntry config_patch_sysmmc{"options", "patch_sysmmc", true};
- ConfigEntry config_patch_emummc{"options", "patch_emummc", true};
- ConfigEntry config_logging{"options", "patch_logging", true};
- ConfigEntry config_version_skip{"options", "version_skip", true};
+class GuiMain final : public tsl::Gui {
+public:
+ GuiMain() { }
+
+ tsl::elm::Element* createUI() override {
+ auto frame = new tsl::elm::OverlayFrame("sys-patch", VERSION_WITH_HASH);
+ auto list = new tsl::elm::List();
+
+ auto options = new tsl::elm::ListItem("Options");
+ auto toggle = new tsl::elm::ListItem("Toggle patches");
+ auto log = new tsl::elm::ListItem("Log");
+
+ options->setClickListener([](u64 keys) -> bool {
+ if (keys & HidNpadButton_A) {
+ tsl::changeTo();
+ return true;
+ }
+ return false;
+ });
+
+ toggle->setClickListener([](u64 keys) -> bool {
+ if (keys & HidNpadButton_A) {
+ tsl::changeTo();
+ return true;
+ }
+ return false;
+ });
+
+ log->setClickListener([](u64 keys) -> bool {
+ if (keys & HidNpadButton_A) {
+ tsl::changeTo();
+ return true;
+ }
+ return false;
+ });
+
+ list->addItem(new tsl::elm::CategoryHeader("Menu"));
+ list->addItem(options);
+ list->addItem(toggle);
+ list->addItem(log);
+
+ frame->setContent(list);
+ return frame;
+ }
};
// libtesla already initialized fs, hid, pl, pmdmnt, hid:sys and set:sys
@@ -154,5 +255,7 @@ class SysPatchOverlay final : public tsl::Overlay {
} // namespace
int main(int argc, char **argv) {
+ create_dir("/config/");
+ create_dir("/config/sys-patch/");
return tsl::loop(argc, argv);
}
diff --git a/sysmod/src/main.cpp b/sysmod/src/main.cpp
index f405f8d..bd3c0d3 100644
--- a/sysmod/src/main.cpp
+++ b/sysmod/src/main.cpp
@@ -31,52 +31,67 @@ struct DebugEventInfo {
u8 _0x30[0x10];
};
-struct PatternData {
- constexpr PatternData(const char* s) {
- // skip leading 0x (if any)
- if (s[0] == '0' && (s[1] == 'x' || s[1] == 'X')) {
- s += 2;
- }
-
- // invalid string will cause a compile-time error due to no return
- constexpr auto hexstr_2_nibble = [](char c) -> u8 {
- if (c >= 'A' && c <= 'F') { return c - 'A' + 10; }
- if (c >= 'a' && c <= 'f') { return c - 'a' + 10; }
- if (c >= '0' && c <= '9') { return c - '0'; }
- };
+template
+constexpr void str2hex(const char* s, T* data, u8& size) {
+ // skip leading 0x (if any)
+ if (s[0] == '0' && (s[1] == 'x' || s[1] == 'X')) {
+ s += 2;
+ }
- // parse and convert string
- while (*s != '\0') {
- if (*s == '.') {
- data[size] = REGEX_SKIP;
- s++;
- } else {
- data[size] |= hexstr_2_nibble(*s++) << 4;
- data[size] |= hexstr_2_nibble(*s++) << 0;
- }
- size++;
+ // invalid string will cause a compile-time error due to no return
+ constexpr auto hexstr_2_nibble = [](char c) -> u8 {
+ if (c >= 'A' && c <= 'F') { return c - 'A' + 10; }
+ if (c >= 'a' && c <= 'f') { return c - 'a' + 10; }
+ if (c >= '0' && c <= '9') { return c - '0'; }
+ };
+
+ // parse and convert string
+ while (*s != '\0') {
+ if (sizeof(T) == sizeof(u16) && *s == '.') {
+ data[size] = REGEX_SKIP;
+ s++;
+ } else {
+ data[size] |= hexstr_2_nibble(*s++) << 4;
+ data[size] |= hexstr_2_nibble(*s++) << 0;
}
+ size++;
}
+}
- // 32 is a reasonable max length for a byte pattern
- // will compile-time error is size is too small
- u16 data[32]{};
+struct PatternData {
+ constexpr PatternData(const char* s) {
+ str2hex(s, data, size);
+ }
+
+ u16 data[44]{}; // reasonable max pattern length, adjust as needed
u8 size{};
};
struct PatchData {
+ constexpr PatchData(const char* s) {
+ str2hex(s, data, size);
+ }
+
template
- constexpr PatchData(T _data) {
- data = _data;
- size = sizeof(T);
+ constexpr PatchData(T v) {
+ for (u32 i = 0; i < sizeof(T); i++) {
+ data[size++] = v & 0xFF;
+ v >>= 8;
+ }
+ }
+
+ auto cmp(const void* _data) -> bool {
+ return !std::memcmp(data, _data, size);
}
- u64 data;
- u8 size;
+
+ u8 data[20]{}; // reasonable max patch length, adjust as needed
+ u8 size{};
};
-enum class PatchedResult {
+enum class PatchResult {
NOT_FOUND,
SKIPPED,
+ DISABLED,
PATCHED_FILE,
PATCHED_SYSPATCH,
FAILED_WRITE,
@@ -91,14 +106,16 @@ struct Patterns {
bool (*const cond)(u32 inst); // check condition of the instruction
PatchData (*const patch)(u32 inst); // the patch data to be applied
- bool (*const applied)(u32 inst); // check to see if patch already applied
+ bool (*const applied)(const u8* data, u32 inst); // check to see if patch already applied
+
+ bool enabled; // controlled by config.ini
const u32 min_fw_ver{FW_VER_ANY}; // set to FW_VER_ANY to ignore
const u32 max_fw_ver{FW_VER_ANY}; // set to FW_VER_ANY to ignore
const u32 min_ams_ver{FW_VER_ANY}; // set to FW_VER_ANY to ignore
const u32 max_ams_ver{FW_VER_ANY}; // set to FW_VER_ANY to ignore
- PatchedResult result{PatchedResult::NOT_FOUND};
+ PatchResult result{PatchResult::NOT_FOUND};
};
struct PatchEntry {
@@ -148,7 +165,7 @@ constexpr auto mov2_cond(u32 inst) -> bool {
if (hosversionBefore(15,0,0)) {
return (inst >> 24) == 0x92; // and x0, x19, #0xffffffff
} else {
- return (inst >> 24) == 0x2A;
+ return (inst >> 24) == 0x2A; // mov x0, x20
}
}
@@ -158,37 +175,37 @@ constexpr auto bne_cond(u32 inst) -> bool {
return type == 0x54 || cond == 0x0;
}
-constexpr auto ret0_patch(u32 inst) -> PatchData {
- return std::byteswap(0xE0031F2AU);
+constexpr auto ctest_cond(u32 inst) -> bool {
+ return true; // we overwrite the function so we don't care to check
}
-constexpr auto nop_patch(u32 inst) -> PatchData {
- return std::byteswap(0x1F2003D5U);
-}
+// to view patches, use https://armconverter.com/?lock=arm64
+constexpr PatchData ret0_patch_data{ "0xE0031F2A" };
+constexpr PatchData nop_patch_data{ "0x1F2003D5" };
+constexpr PatchData mov0_patch_data{ "0xE0031FAA" };
+constexpr PatchData ctest_patch_data{ "00309AD2001EA1F2610100D4E0031FAAC0035FD6" };
-constexpr auto subs_patch(u32 inst) -> PatchData {
- return subi_cond(inst) ? (u8)0x1 : (u8)0x0;
-}
+constexpr auto ret0_patch(u32 inst) -> PatchData { return ret0_patch_data; }
+constexpr auto nop_patch(u32 inst) -> PatchData { return nop_patch_data; }
+constexpr auto subs_patch(u32 inst) -> PatchData { return subi_cond(inst) ? (u8)0x1 : (u8)0x0; }
+constexpr auto mov0_patch(u32 inst) -> PatchData { return mov0_patch_data; }
+constexpr auto ctest_patch(u32 inst) -> PatchData { return ctest_patch_data; }
constexpr auto b_patch(u32 inst) -> PatchData {
- const auto opcode = 0x14 << 24;
- const auto offset = (inst >> 5) & 0x7FFFF;
+ const u32 opcode = 0x14 << 24;
+ const u32 offset = (inst >> 5) & 0x7FFFF;
return opcode | offset;
}
-constexpr auto mov0_patch(u32 inst) -> PatchData {
- return std::byteswap(0xE0031FAAU);
-}
-
-constexpr auto ret0_applied(u32 inst) -> bool {
- return ret0_patch(inst).data == inst;
+constexpr auto ret0_applied(const u8* data, u32 inst) -> bool {
+ return ret0_patch(inst).cmp(data);
}
-constexpr auto nop_applied(u32 inst) -> bool {
- return nop_patch(inst).data == inst;
+constexpr auto nop_applied(const u8* data, u32 inst) -> bool {
+ return nop_patch(inst).cmp(data);
}
-constexpr auto subs_applied(u32 inst) -> bool {
+constexpr auto subs_applied(const u8* data, u32 inst) -> bool {
const auto type_i = (inst >> 24) & 0xFF;
const auto imm = (inst >> 10) & 0xFFF;
const auto type_r = (inst >> 21) & 0x7F9;
@@ -196,34 +213,42 @@ constexpr auto subs_applied(u32 inst) -> bool {
return ((type_i == 0x71) && (imm == 0x1)) || ((type_r == 0x358) && (reg == 0x0));
}
-constexpr auto b_applied(u32 inst) -> bool {
+constexpr auto b_applied(const u8* data, u32 inst) -> bool {
return 0x14 == (inst >> 24);
}
-constexpr auto mov0_applied(u32 inst) -> bool {
- return mov0_patch(inst).data == inst;
+constexpr auto mov0_applied(const u8* data, u32 inst) -> bool {
+ return mov0_patch(inst).cmp(data);
+}
+
+constexpr auto ctest_applied(const u8* data, u32 inst) -> bool {
+ return ctest_patch(inst).cmp(data);
}
constinit Patterns fs_patterns[] = {
- { "noacidsigchk1", "0xC8FE4739", -24, 0, bl_cond, ret0_patch, ret0_applied, FW_VER_ANY, MAKEHOSVERSION(9,2,0) },
- { "noacidsigchk2", "0x0210911F000072", -5, 0, bl_cond, ret0_patch, ret0_applied, FW_VER_ANY, MAKEHOSVERSION(9,2,0) },
- { "noncasigchk_old", "0x1E42B9", -5, 0, tbz_cond, nop_patch, nop_applied, MAKEHOSVERSION(10,0,0), MAKEHOSVERSION(14,2,1) },
- { "noncasigchk_new", "0x3E4479", -5, 0, tbz_cond, nop_patch, nop_applied, MAKEHOSVERSION(15,0,0) },
- { "nocntchk_old", "0x081C00121F05007181000054", -4, 0, bl_cond, ret0_patch, ret0_applied, MAKEHOSVERSION(10,0,0), MAKEHOSVERSION(14,2,1) },
- { "nocntchk_new", "0x081C00121F05007141010054", -4, 0, bl_cond, ret0_patch, ret0_applied, MAKEHOSVERSION(15,0,0) },
+ { "noacidsigchk1", "0xC8FE4739", -24, 0, bl_cond, ret0_patch, ret0_applied, true, FW_VER_ANY, MAKEHOSVERSION(9,2,0) },
+ { "noacidsigchk2", "0x0210911F000072", -5, 0, bl_cond, ret0_patch, ret0_applied, true, FW_VER_ANY, MAKEHOSVERSION(9,2,0) },
+ { "noncasigchk_old", "0x1E42B9", -5, 0, tbz_cond, nop_patch, nop_applied, true, MAKEHOSVERSION(10,0,0), MAKEHOSVERSION(14,2,1) },
+ { "noncasigchk_new", "0x3E4479", -5, 0, tbz_cond, nop_patch, nop_applied, true, MAKEHOSVERSION(15,0,0) },
+ { "nocntchk_old", "0x081C00121F05007181000054", -4, 0, bl_cond, ret0_patch, ret0_applied, true, MAKEHOSVERSION(10,0,0), MAKEHOSVERSION(14,2,1) },
+ { "nocntchk_new", "0x081C00121F05007141010054", -4, 0, bl_cond, ret0_patch, ret0_applied, true, MAKEHOSVERSION(15,0,0) },
};
constinit Patterns ldr_patterns[] = {
- { "noacidsigchk", "0xFD7BC6A8C0035FD6", 16, 2, subs_cond, subs_patch, subs_applied },
+ { "noacidsigchk", "0xFD7BC6A8C0035FD6", 16, 2, subs_cond, subs_patch, subs_applied, true },
};
constinit Patterns es_patterns[] = {
- { "es1", "0x1F90013128928052", -4, 0, cbz_cond, b_patch, b_applied, FW_VER_ANY, MAKEHOSVERSION(13,2,1) },
- { "es2", "0xC07240F9E1930091", -4, 0, tbz_cond, nop_patch, nop_applied, FW_VER_ANY, MAKEHOSVERSION(10,2,0) },
- { "es3", "0xF3031FAA02000014", -4, 0, bne_cond, nop_patch, nop_applied, FW_VER_ANY, MAKEHOSVERSION(10,2,0) },
- { "es4", "0xC0FDFF35A8C35838", -4, 0, mov_cond, nop_patch, nop_applied, MAKEHOSVERSION(11,0,0), MAKEHOSVERSION(13,2,1) },
- { "es5", "0xE023009145EEFF97", -4, 0, cbz_cond, b_patch, b_applied, MAKEHOSVERSION(11,0,0), MAKEHOSVERSION(13,2,1) },
- { "es6", "0x.6300...0094A0..D1..FF97", 16, 0, mov2_cond, mov0_patch, mov0_applied, MAKEHOSVERSION(14,0,0) },
+ { "es1", "0x1F90013128928052", -4, 0, cbz_cond, b_patch, b_applied, true, FW_VER_ANY, MAKEHOSVERSION(13,2,1) },
+ { "es2", "0xC07240F9E1930091", -4, 0, tbz_cond, nop_patch, nop_applied, true, FW_VER_ANY, MAKEHOSVERSION(10,2,0) },
+ { "es3", "0xF3031FAA02000014", -4, 0, bne_cond, nop_patch, nop_applied, true, FW_VER_ANY, MAKEHOSVERSION(10,2,0) },
+ { "es4", "0xC0FDFF35A8C35838", -4, 0, mov_cond, nop_patch, nop_applied, true, MAKEHOSVERSION(11,0,0), MAKEHOSVERSION(13,2,1) },
+ { "es5", "0xE023009145EEFF97", -4, 0, cbz_cond, b_patch, b_applied, true, MAKEHOSVERSION(11,0,0), MAKEHOSVERSION(13,2,1) },
+ { "es6", "0x.6300...0094A0..D1..FF97", 16, 0, mov2_cond, mov0_patch, mov0_applied, true, MAKEHOSVERSION(14,0,0) },
+};
+
+constinit Patterns nifm_patterns[] = {
+ { "ctest", "................F50301AAF40300AA....F30314AAE00314AA9F0201397F8E04F8", 0, 0, ctest_cond, ctest_patch, ctest_applied, true },
};
// NOTE: add system titles that you want to be patched to this table.
@@ -234,6 +259,7 @@ constinit PatchEntry patches[] = {
{ "ldr", 0x0100000000000001, ldr_patterns, MAKEHOSVERSION(10,0,0) },
// es was added in fw 2
{ "es", 0x0100000000000033, es_patterns, MAKEHOSVERSION(2,0,0) },
+ { "nifm", 0x010000000000000F, nifm_patterns },
};
struct EmummcPaths {
@@ -257,18 +283,23 @@ auto is_emummc() -> bool {
void patcher(Handle handle, std::span data, u64 addr, std::span patterns) {
for (auto& p : patterns) {
+ // skip if disabled (controller by config.ini)
+ if (p.result == PatchResult::DISABLED) {
+ continue;
+ }
+
// skip if version isn't valid
if (VERSION_SKIP &&
((p.min_fw_ver && p.min_fw_ver > FW_VERSION) ||
(p.max_fw_ver && p.max_fw_ver < FW_VERSION) ||
(p.min_ams_ver && p.min_ams_ver > AMS_VERSION) ||
(p.max_ams_ver && p.max_ams_ver < AMS_VERSION))) {
- p.result = PatchedResult::SKIPPED;
+ p.result = PatchResult::SKIPPED;
continue;
}
// skip if already patched
- if (p.result == PatchedResult::PATCHED_FILE || p.result == PatchedResult::PATCHED_SYSPATCH) {
+ if (p.result == PatchResult::PATCHED_FILE || p.result == PatchResult::PATCHED_SYSPATCH) {
continue;
}
@@ -301,15 +332,15 @@ void patcher(Handle handle, std::span data, u64 addr, std::span bool {
((patch.min_fw_ver && patch.min_fw_ver > FW_VERSION) ||
(patch.max_fw_ver && patch.max_fw_ver < FW_VERSION))) {
for (auto& p : patch.patterns) {
- p.result = PatchedResult::SKIPPED;
+ p.result = PatchResult::SKIPPED;
}
return true;
}
@@ -410,13 +441,14 @@ auto ini_load_or_write_default(const char* section, const char* key, long _defau
}
}
-auto patch_result_to_str(PatchedResult result) -> const char* {
+auto patch_result_to_str(PatchResult result) -> const char* {
switch (result) {
- case PatchedResult::NOT_FOUND: return "Unpatched";
- case PatchedResult::SKIPPED: return "Skipped";
- case PatchedResult::PATCHED_FILE: return "Patched (file)";
- case PatchedResult::PATCHED_SYSPATCH: return "Patched (sys-patch)";
- case PatchedResult::FAILED_WRITE: return "Failed (svcWriteDebugProcessMemory)";
+ case PatchResult::NOT_FOUND: return "Unpatched";
+ case PatchResult::SKIPPED: return "Skipped";
+ case PatchResult::DISABLED: return "Disabled";
+ case PatchResult::PATCHED_FILE: return "Patched (file)";
+ case PatchResult::PATCHED_SYSPATCH: return "Patched (sys-patch)";
+ case PatchResult::FAILED_WRITE: return "Failed (svcWriteDebugProcessMemory)";
}
std::unreachable();
@@ -507,10 +539,22 @@ int main(int argc, char* argv[]) {
create_dir("/config/sys-patch/");
ini_remove(log_path);
+ // load options
const auto patch_sysmmc = ini_load_or_write_default("options", "patch_sysmmc", 1, ini_path);
const auto patch_emummc = ini_load_or_write_default("options", "patch_emummc", 1, ini_path);
const auto enable_logging = ini_load_or_write_default("options", "enable_logging", 1, ini_path);
VERSION_SKIP = ini_load_or_write_default("options", "version_skip", 1, ini_path);
+
+ // load patch toggles
+ for (auto& patch : patches) {
+ for (auto& p : patch.patterns) {
+ p.enabled = ini_load_or_write_default(patch.name, p.patch_name, p.enabled, ini_path);
+ if (!p.enabled) {
+ p.result = PatchResult::DISABLED;
+ }
+ }
+ }
+
const auto emummc = is_emummc();
bool enable_patching = true;
@@ -540,7 +584,7 @@ int main(int argc, char* argv[]) {
for (auto& patch : patches) {
for (auto& p : patch.patterns) {
if (!enable_patching) {
- p.result = PatchedResult::SKIPPED;
+ p.result = PatchResult::SKIPPED;
}
ini_puts(patch.name, p.patch_name, patch_result_to_str(p.result), log_path);
}
From d5fbbd40d3fcf4c3d3338ed9f9a0b2e133de14bc Mon Sep 17 00:00:00 2001
From: TotalJustice <47043333+ITotalJustice@users.noreply.github.com>
Date: Sat, 27 May 2023 23:40:19 +0100
Subject: [PATCH 02/45] fix detecting if nifm ctest patch is already applied
the patch itself always worked, however it failed to detect if the patch was already applied.
this isn't a big issue, and the only one to notice was probably me ;)
---
Makefile | 2 +-
README.md | 1 +
sysmod/src/main.cpp | 8 ++++----
3 files changed, 6 insertions(+), 5 deletions(-)
diff --git a/Makefile b/Makefile
index 6a53e19..d0dec9d 100644
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@ MAKEFILES := sysmod overlay
TARGETS := $(foreach dir,$(MAKEFILES),$(CURDIR)/$(dir))
# the below was taken from atmosphere + switch-examples makefile
-export VERSION := 1.4.0
+export VERSION := 1.4.1
export GIT_BRANCH := $(shell git symbolic-ref --short HEAD)
ifeq ($(strip $(shell git status --porcelain 2>/dev/null)),)
diff --git a/README.md b/README.md
index 20c133e..2d7a56c 100644
--- a/README.md
+++ b/README.md
@@ -101,3 +101,4 @@ Software is built on the shoulders of giants. This tool wouldn't be possible wit
- DevkitPro (toolchain)
- [minIni](https://github.com/compuphase/minIni)
- [libtesla](https://github.com/WerWolv/libtesla)
+- [Shoutout to the best switch cfw setup guide](https://rentry.org/SwitchHackingIsEasy)
diff --git a/sysmod/src/main.cpp b/sysmod/src/main.cpp
index bd3c0d3..4c983b3 100644
--- a/sysmod/src/main.cpp
+++ b/sysmod/src/main.cpp
@@ -176,14 +176,14 @@ constexpr auto bne_cond(u32 inst) -> bool {
}
constexpr auto ctest_cond(u32 inst) -> bool {
- return true; // we overwrite the function so we don't care to check
+ return std::byteswap(0xF50301AA) == inst; // mov x21, x1
}
// to view patches, use https://armconverter.com/?lock=arm64
constexpr PatchData ret0_patch_data{ "0xE0031F2A" };
constexpr PatchData nop_patch_data{ "0x1F2003D5" };
constexpr PatchData mov0_patch_data{ "0xE0031FAA" };
-constexpr PatchData ctest_patch_data{ "00309AD2001EA1F2610100D4E0031FAAC0035FD6" };
+constexpr PatchData ctest_patch_data{ "0x00309AD2001EA1F2610100D4E0031FAAC0035FD6" };
constexpr auto ret0_patch(u32 inst) -> PatchData { return ret0_patch_data; }
constexpr auto nop_patch(u32 inst) -> PatchData { return nop_patch_data; }
@@ -248,7 +248,7 @@ constinit Patterns es_patterns[] = {
};
constinit Patterns nifm_patterns[] = {
- { "ctest", "................F50301AAF40300AA....F30314AAE00314AA9F0201397F8E04F8", 0, 0, ctest_cond, ctest_patch, ctest_applied, true },
+ { "ctest", "....................F40300AA....F30314AAE00314AA9F0201397F8E04F8", 16, -16, ctest_cond, ctest_patch, ctest_applied, true },
};
// NOTE: add system titles that you want to be patched to this table.
@@ -338,7 +338,7 @@ void patcher(Handle handle, std::span data, u64 addr, std::span
Date: Sun, 28 May 2023 01:18:23 +0100
Subject: [PATCH 03/45] fix options "logging" key missmatch between sysmod and
overlay
---
Makefile | 2 +-
README.md | 8 ++++----
overlay/src/main.cpp | 2 +-
sysmod/src/main.cpp | 2 +-
4 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/Makefile b/Makefile
index d0dec9d..031f582 100644
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@ MAKEFILES := sysmod overlay
TARGETS := $(foreach dir,$(MAKEFILES),$(CURDIR)/$(dir))
# the below was taken from atmosphere + switch-examples makefile
-export VERSION := 1.4.1
+export VERSION := 1.4.2
export GIT_BRANCH := $(shell git symbolic-ref --short HEAD)
ifeq ($(strip $(shell git status --porcelain 2>/dev/null)),)
diff --git a/README.md b/README.md
index 2d7a56c..f302f63 100644
--- a/README.md
+++ b/README.md
@@ -12,10 +12,10 @@ The configuration file can be found in `/config/sys-patch/config.ini`. The file
```ini
[options]
-patch_sysmmc=1 ; 1=(default) patch sysmmc, 0=don't patch sysmmc
-patch_emummc=1 ; 1=(default) patch emummc, 0=don't patch emummc
-logging=1 ; 1=(default) output /config/sys-patch/log.ini 0=no log
-version_skip=1 ; 1=(default) skips out of date patterns, 0=search all patterns
+patch_sysmmc=1 ; 1=(default) patch sysmmc, 0=don't patch sysmmc
+patch_emummc=1 ; 1=(default) patch emummc, 0=don't patch emummc
+enable_logging=1 ; 1=(default) output /config/sys-patch/log.ini 0=no log
+version_skip=1 ; 1=(default) skips out of date patterns, 0=search all patterns
```
---
diff --git a/overlay/src/main.cpp b/overlay/src/main.cpp
index 7feef65..4f5c2dc 100644
--- a/overlay/src/main.cpp
+++ b/overlay/src/main.cpp
@@ -86,7 +86,7 @@ class GuiOptions final : public tsl::Gui {
ConfigEntry config_patch_sysmmc{"options", "patch_sysmmc", true};
ConfigEntry config_patch_emummc{"options", "patch_emummc", true};
- ConfigEntry config_logging{"options", "patch_logging", true};
+ ConfigEntry config_logging{"options", "enable_logging", true};
ConfigEntry config_version_skip{"options", "version_skip", true};
};
diff --git a/sysmod/src/main.cpp b/sysmod/src/main.cpp
index 4c983b3..6a3cf16 100644
--- a/sysmod/src/main.cpp
+++ b/sysmod/src/main.cpp
@@ -437,7 +437,7 @@ auto ini_load_or_write_default(const char* section, const char* key, long _defau
ini_putl(section, key, _default, path);
return _default;
} else {
- return ini_getl(section, key, _default, path);
+ return ini_getbool(section, key, _default, path);
}
}
From 982843ac187ac7b0b2a3c2021dd13d3608edaee3 Mon Sep 17 00:00:00 2001
From: ITotalJustice <47043333+ITotalJustice@users.noreply.github.com>
Date: Tue, 24 Oct 2023 22:05:55 +0100
Subject: [PATCH 04/45] update noncasigchk for fw 17.
credit goes to the anon that created the patch, thank you.
---
Makefile | 2 +-
overlay/src/main.cpp | 2 ++
sysmod/src/main.cpp | 3 ++-
3 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/Makefile b/Makefile
index 031f582..0633d39 100644
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@ MAKEFILES := sysmod overlay
TARGETS := $(foreach dir,$(MAKEFILES),$(CURDIR)/$(dir))
# the below was taken from atmosphere + switch-examples makefile
-export VERSION := 1.4.2
+export VERSION := 1.5.0
export GIT_BRANCH := $(shell git symbolic-ref --short HEAD)
ifeq ($(strip $(shell git status --porcelain 2>/dev/null)),)
diff --git a/overlay/src/main.cpp b/overlay/src/main.cpp
index 4f5c2dc..eeea59a 100644
--- a/overlay/src/main.cpp
+++ b/overlay/src/main.cpp
@@ -103,6 +103,7 @@ class GuiToggle final : public tsl::Gui {
list->addItem(config_noacidsigchk2.create_list_item("noacidsigchk2"));
list->addItem(config_noncasigchk_old.create_list_item("noncasigchk_old"));
list->addItem(config_noncasigchk_new.create_list_item("noncasigchk_new"));
+ list->addItem(config_noncasigchk_new2.create_list_item("noncasigchk_new2"));
list->addItem(config_nocntchk_old.create_list_item("nocntchk_old"));
list->addItem(config_nocntchk_new.create_list_item("nocntchk_new"));
@@ -128,6 +129,7 @@ class GuiToggle final : public tsl::Gui {
ConfigEntry config_noacidsigchk2{"fs", "noacidsigchk2", true};
ConfigEntry config_noncasigchk_old{"fs", "noncasigchk_old", true};
ConfigEntry config_noncasigchk_new{"fs", "noncasigchk_new", true};
+ ConfigEntry config_noncasigchk_new2{"fs", "noncasigchk_new2", true};
ConfigEntry config_nocntchk_old{"fs", "nocntchk_old", true};
ConfigEntry config_nocntchk_new{"fs", "nocntchk_new", true};
ConfigEntry config_noacidsigchk{"ldr", "noacidsigchk", true};
diff --git a/sysmod/src/main.cpp b/sysmod/src/main.cpp
index 6a3cf16..6e9e29c 100644
--- a/sysmod/src/main.cpp
+++ b/sysmod/src/main.cpp
@@ -229,7 +229,8 @@ constinit Patterns fs_patterns[] = {
{ "noacidsigchk1", "0xC8FE4739", -24, 0, bl_cond, ret0_patch, ret0_applied, true, FW_VER_ANY, MAKEHOSVERSION(9,2,0) },
{ "noacidsigchk2", "0x0210911F000072", -5, 0, bl_cond, ret0_patch, ret0_applied, true, FW_VER_ANY, MAKEHOSVERSION(9,2,0) },
{ "noncasigchk_old", "0x1E42B9", -5, 0, tbz_cond, nop_patch, nop_applied, true, MAKEHOSVERSION(10,0,0), MAKEHOSVERSION(14,2,1) },
- { "noncasigchk_new", "0x3E4479", -5, 0, tbz_cond, nop_patch, nop_applied, true, MAKEHOSVERSION(15,0,0) },
+ { "noncasigchk_new", "0x3E4479", -5, 0, tbz_cond, nop_patch, nop_applied, true, MAKEHOSVERSION(15,0,0), MAKEHOSVERSION(16,1,0) },
+ { "noncasigchk_new2", "0x258052", -5, 0, tbz_cond, nop_patch, nop_applied, true, MAKEHOSVERSION(17,0,0) },
{ "nocntchk_old", "0x081C00121F05007181000054", -4, 0, bl_cond, ret0_patch, ret0_applied, true, MAKEHOSVERSION(10,0,0), MAKEHOSVERSION(14,2,1) },
{ "nocntchk_new", "0x081C00121F05007141010054", -4, 0, bl_cond, ret0_patch, ret0_applied, true, MAKEHOSVERSION(15,0,0) },
};
From 2610c25ae58af6cff4936000cb40d327ecf453b2 Mon Sep 17 00:00:00 2001
From: impeeza <41979604+impeeza@users.noreply.github.com>
Date: Thu, 28 Mar 2024 15:54:53 -0500
Subject: [PATCH 05/45] FW 18 Update
FW 18 Update
---
Makefile | 2 +-
overlay/src/main.cpp | 2 ++
sysmod/src/main.cpp | 1 +
3 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/Makefile b/Makefile
index 0633d39..ebd04c1 100644
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@ MAKEFILES := sysmod overlay
TARGETS := $(foreach dir,$(MAKEFILES),$(CURDIR)/$(dir))
# the below was taken from atmosphere + switch-examples makefile
-export VERSION := 1.5.0
+export VERSION := 1.5.1
export GIT_BRANCH := $(shell git symbolic-ref --short HEAD)
ifeq ($(strip $(shell git status --porcelain 2>/dev/null)),)
diff --git a/overlay/src/main.cpp b/overlay/src/main.cpp
index eeea59a..f957055 100644
--- a/overlay/src/main.cpp
+++ b/overlay/src/main.cpp
@@ -117,6 +117,7 @@ class GuiToggle final : public tsl::Gui {
list->addItem(config_es4.create_list_item("es4"));
list->addItem(config_es5.create_list_item("es5"));
list->addItem(config_es6.create_list_item("es6"));
+ list->addItem(config_es7.create_list_item("es7"));
list->addItem(new tsl::elm::CategoryHeader("NIFM - 010000000000000F"));
list->addItem(config_ctest.create_list_item("ctest"));
@@ -139,6 +140,7 @@ class GuiToggle final : public tsl::Gui {
ConfigEntry config_es4{"es", "es4", true};
ConfigEntry config_es5{"es", "es5", true};
ConfigEntry config_es6{"es", "es6", true};
+ ConfigEntry config_es7{"es", "es7", true};
ConfigEntry config_ctest{"nifm", "ctest", false};
};
diff --git a/sysmod/src/main.cpp b/sysmod/src/main.cpp
index 6e9e29c..076525d 100644
--- a/sysmod/src/main.cpp
+++ b/sysmod/src/main.cpp
@@ -246,6 +246,7 @@ constinit Patterns es_patterns[] = {
{ "es4", "0xC0FDFF35A8C35838", -4, 0, mov_cond, nop_patch, nop_applied, true, MAKEHOSVERSION(11,0,0), MAKEHOSVERSION(13,2,1) },
{ "es5", "0xE023009145EEFF97", -4, 0, cbz_cond, b_patch, b_applied, true, MAKEHOSVERSION(11,0,0), MAKEHOSVERSION(13,2,1) },
{ "es6", "0x.6300...0094A0..D1..FF97", 16, 0, mov2_cond, mov0_patch, mov0_applied, true, MAKEHOSVERSION(14,0,0) },
+ { "es7", "0x.6F00...0094A0..D1..FF97", 16, 0, mov2_cond, mov0_patch, mov0_applied, true, MAKEHOSVERSION(18,0,0) },
};
constinit Patterns nifm_patterns[] = {
From 01e2fbfecfb805799c36deb32fefb38b9b61d22d Mon Sep 17 00:00:00 2001
From: impeeza <41979604+impeeza@users.noreply.github.com>
Date: Thu, 28 Mar 2024 16:00:01 -0500
Subject: [PATCH 06/45] Update README.md
---
README.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/README.md b/README.md
index f302f63..ad833ca 100644
--- a/README.md
+++ b/README.md
@@ -102,3 +102,4 @@ Software is built on the shoulders of giants. This tool wouldn't be possible wit
- [minIni](https://github.com/compuphase/minIni)
- [libtesla](https://github.com/WerWolv/libtesla)
- [Shoutout to the best switch cfw setup guide](https://rentry.org/SwitchHackingIsEasy)
+- N
From e3ad7ec7b5bb60b9f9488f14a7702f94f2e38734 Mon Sep 17 00:00:00 2001
From: Peter Galonza
Date: Wed, 5 Jun 2024 22:44:57 +0300
Subject: [PATCH 07/45] feature: change workflow
Add change log and release
---
.github/workflows/build-jobs.yaml | 23 ++++++++++
.github/workflows/build.yml | 14 ++++++
.github/workflows/build_depoly.yml | 21 ---------
.github/workflows/release.yml | 38 ++++++++++++++++
Makefile | 5 +++
configs/cliff.toml | 69 ++++++++++++++++++++++++++++++
6 files changed, 149 insertions(+), 21 deletions(-)
create mode 100644 .github/workflows/build-jobs.yaml
create mode 100644 .github/workflows/build.yml
delete mode 100644 .github/workflows/build_depoly.yml
create mode 100644 .github/workflows/release.yml
create mode 100644 configs/cliff.toml
diff --git a/.github/workflows/build-jobs.yaml b/.github/workflows/build-jobs.yaml
new file mode 100644
index 0000000..231ad8d
--- /dev/null
+++ b/.github/workflows/build-jobs.yaml
@@ -0,0 +1,23 @@
+name: Build jobs
+
+on:
+ workflow_call:
+
+jobs:
+ build:
+ name: build
+ runs-on: ubuntu-latest
+ container: ghcr.io/${{ github.repository_owner }}/devkita64-atmosphere:latest
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+ with:
+ submodules: recursive
+ - name: Build sys-patch
+ run: |
+ make dist
+ - name: Upload artifacts
+ uses: actions/upload-artifact@v4
+ with:
+ name: sys-patch-artifacts
+ path: ./sys-patch.zip
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
new file mode 100644
index 0000000..6443090
--- /dev/null
+++ b/.github/workflows/build.yml
@@ -0,0 +1,14 @@
+name: Build sys-patch
+
+on:
+ push:
+ branches:
+ - master
+ - feature-integration
+ paths-ignore:
+ - 'Dockerfile'
+ - '.github/workflows/image.yml'
+
+jobs:
+ build-workflow:
+ uses: ./.github/workflows/build-jobs.yaml
diff --git a/.github/workflows/build_depoly.yml b/.github/workflows/build_depoly.yml
deleted file mode 100644
index 9516f19..0000000
--- a/.github/workflows/build_depoly.yml
+++ /dev/null
@@ -1,21 +0,0 @@
-name: build
-on: [push, pull_request]
-
-jobs:
- build:
- runs-on: ubuntu-latest
- container: devkitpro/devkita64:latest
-
- steps:
- - name: Checkout 🛎️
- uses: actions/checkout@master
- with:
- submodules: recursive
-
- - name: Build
- run: make dist -j2
-
- - uses: actions/upload-artifact@master
- with:
- name: sys-patch
- path: sys-patch.zip
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
new file mode 100644
index 0000000..ce4f921
--- /dev/null
+++ b/.github/workflows/release.yml
@@ -0,0 +1,38 @@
+name: Create release
+
+on:
+ push:
+ tags:
+ - '[0-9]+.[0-9]+.[0-9]+'
+
+permissions:
+ contents: write
+
+jobs:
+ build-workflow:
+ uses: ./.github/workflows/build-jobs.yaml
+ create-release:
+ runs-on: ubuntu-latest
+ needs: build-workflow
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+ with:
+ fetch-depth: 0
+ - name: Generate a changelog
+ uses: orhun/git-cliff-action@v3
+ with:
+ config: ./configs/cliff.toml
+ args: --verbose
+ - name: Download artifact
+ uses: actions/download-artifact@v4
+ with:
+ name: sys-patch-artifacts
+ path: "./"
+ - name: Create release
+ uses: ncipollo/release-action@v1
+ with:
+ artifacts: "sys-patch.zip"
+ prerelease: false
+ name: "ns-sys-patch ${{ github.ref_name }}"
+ bodyFile: "git-cliff/CHANGELOG.md"
diff --git a/Makefile b/Makefile
index ebd04c1..43cec76 100644
--- a/Makefile
+++ b/Makefile
@@ -3,7 +3,12 @@ TARGETS := $(foreach dir,$(MAKEFILES),$(CURDIR)/$(dir))
# the below was taken from atmosphere + switch-examples makefile
export VERSION := 1.5.1
+
+ifneq ($(strip $(shell git symbolic-ref --short HEAD 2>/dev/null)),)
export GIT_BRANCH := $(shell git symbolic-ref --short HEAD)
+else
+export GIT_BRANCH := notbranch
+endif
ifeq ($(strip $(shell git status --porcelain 2>/dev/null)),)
export GIT_REVISION := $(GIT_BRANCH)-$(shell git rev-parse --short HEAD)
diff --git a/configs/cliff.toml b/configs/cliff.toml
new file mode 100644
index 0000000..f976285
--- /dev/null
+++ b/configs/cliff.toml
@@ -0,0 +1,69 @@
+# git-cliff ~ configuration file
+# https://git-cliff.org/docs/configuration
+
+[changelog]
+# changelog header
+header = """
+# Changelog\n
+All notable changes to this project will be documented in this file.
+
+The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
+and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).\n
+"""
+# template for the changelog body
+# https://keats.github.io/tera/docs/#introduction
+body = """
+{% if version -%}
+ ## [{{ version | trim_start_matches(pat="v") }}] - {{ timestamp | date(format="%Y-%m-%d") }}
+{% else -%}
+ ## [Unreleased]
+{% endif -%}
+{% for group, commits in commits | group_by(attribute="group") %}
+ ### {{ group | upper_first }}
+ {% for commit in commits %}
+ - {{ commit.message | upper_first }}\
+ {% endfor %}
+{% endfor %}\n
+"""
+# template for the changelog footer
+footer = """
+
+"""
+# remove the leading and trailing whitespace from the templates
+trim = true
+
+[git]
+# parse the commits based on https://www.conventionalcommits.org
+conventional_commits = true
+# filter out the commits that are not conventional
+filter_unconventional = false
+# process each line of a commit as an individual commit
+split_commits = false
+# regex for parsing and grouping commits
+commit_parsers = [
+ { message = "^feat", group = "Features" },
+ { message = "^fix", group = "Bug Fixes" },
+ { message = "^doc", group = "Documentation" },
+ { message = "^perf", group = "Performance" },
+ { message = "^refactor", group = "Refactor" },
+ { message = "^style", group = "Styling" },
+ { message = "^test", group = "Testing" },
+ { message = "^chore\\(release\\): prepare for", skip = true },
+ { message = "^chore", group = "Miscellaneous Tasks" },
+ { body = ".*security", group = "Security" },
+ { body = ".*", group = "Other (unconventional)" },
+]
+# protect breaking changes from being skipped due to matching a skipping commit_parser
+protect_breaking_commits = false
+# filter out the commits that are not matched by commit parsers
+filter_commits = true
+# regex for matching git tags
+tag_pattern = "[0-9]+.[0-9]+.[0-9]+"
+# regex for skipping tags
+skip_tags = "v0.1.0-beta.1"
+# regex for ignoring tags
+ignore_tags = ""
+# sort the tags topologically
+topo_order = false
+# sort the commits inside sections by oldest/newest order
+sort_commits = "oldest"
From 0eb731bce9d689f714835db83a8b957828a06fa1 Mon Sep 17 00:00:00 2001
From: Peter Galonza
Date: Thu, 6 Jun 2024 22:58:34 +0300
Subject: [PATCH 08/45] feature: add parallel jobs for make
---
.github/workflows/build-jobs.yaml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/build-jobs.yaml b/.github/workflows/build-jobs.yaml
index 231ad8d..cecd417 100644
--- a/.github/workflows/build-jobs.yaml
+++ b/.github/workflows/build-jobs.yaml
@@ -15,7 +15,7 @@ jobs:
submodules: recursive
- name: Build sys-patch
run: |
- make dist
+ make dist -j $(nproc)
- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
From d951a6fa653431414b54c92935c79e5aebf6f22e Mon Sep 17 00:00:00 2001
From: Peter Galonza
Date: Sat, 8 Jun 2024 23:33:37 +0300
Subject: [PATCH 09/45] feature: change libtesla repo
---
.gitmodules | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/.gitmodules b/.gitmodules
index 9b1605c..d35ee52 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,4 +1,4 @@
[submodule "overlay/libtesla"]
path = overlay/libtesla
- url = https://github.com/ITotalJustice/libtesla.git
- branch = tj
+ url = https://github.com/pgalonza/ns-libtesla
+ branch = master
From 4a12f5e4c5c75072b323719d209e9feb37be1ef5 Mon Sep 17 00:00:00 2001
From: impeeza <41979604+impeeza@users.noreply.github.com>
Date: Sat, 8 Jun 2024 15:57:09 -0500
Subject: [PATCH 10/45] Update build-jobs.yaml
---
.github/workflows/build-jobs.yaml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/build-jobs.yaml b/.github/workflows/build-jobs.yaml
index cecd417..1b67049 100644
--- a/.github/workflows/build-jobs.yaml
+++ b/.github/workflows/build-jobs.yaml
@@ -7,7 +7,7 @@ jobs:
build:
name: build
runs-on: ubuntu-latest
- container: ghcr.io/${{ github.repository_owner }}/devkita64-atmosphere:latest
+ container: ghcr.io/pgalonza/devkita64-atmosphere:latest
steps:
- name: Checkout
uses: actions/checkout@v4
From 2562919ad67d0574fae3b78465caef649ce023ab Mon Sep 17 00:00:00 2001
From: impeeza <41979604+impeeza@users.noreply.github.com>
Date: Sat, 8 Jun 2024 17:42:59 -0500
Subject: [PATCH 11/45] Update .gitmodules
---
.gitmodules | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.gitmodules b/.gitmodules
index d35ee52..2088864 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,4 +1,4 @@
[submodule "overlay/libtesla"]
path = overlay/libtesla
- url = https://github.com/pgalonza/ns-libtesla
+ url = https://github.com/WerWolv/libtesla
branch = master
From 1b9327c9d8ed8002caf65cfaa11f2b1b04638490 Mon Sep 17 00:00:00 2001
From: impeeza <41979604+impeeza@users.noreply.github.com>
Date: Sat, 8 Jun 2024 22:36:49 -0500
Subject: [PATCH 12/45] =?UTF-8?q?Add=20New=20patterns=20for=20latest=20Atm?=
=?UTF-8?q?osph=C3=A8re=20Changes?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Add New patterns for latest Atmosphère Changes
Atmosphère's Commit 05fde7b introduce new way the validation of the Acid signature is done.
---
sysmod/src/main.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/sysmod/src/main.cpp b/sysmod/src/main.cpp
index 076525d..e760f33 100644
--- a/sysmod/src/main.cpp
+++ b/sysmod/src/main.cpp
@@ -236,7 +236,7 @@ constinit Patterns fs_patterns[] = {
};
constinit Patterns ldr_patterns[] = {
- { "noacidsigchk", "0xFD7BC6A8C0035FD6", 16, 2, subs_cond, subs_patch, subs_applied, true },
+ { "noacidsigchk", "0xFD7B.A8C0035FD6", 16, 2, subs_cond, subs_patch, subs_applied, true },
};
constinit Patterns es_patterns[] = {
@@ -245,7 +245,7 @@ constinit Patterns es_patterns[] = {
{ "es3", "0xF3031FAA02000014", -4, 0, bne_cond, nop_patch, nop_applied, true, FW_VER_ANY, MAKEHOSVERSION(10,2,0) },
{ "es4", "0xC0FDFF35A8C35838", -4, 0, mov_cond, nop_patch, nop_applied, true, MAKEHOSVERSION(11,0,0), MAKEHOSVERSION(13,2,1) },
{ "es5", "0xE023009145EEFF97", -4, 0, cbz_cond, b_patch, b_applied, true, MAKEHOSVERSION(11,0,0), MAKEHOSVERSION(13,2,1) },
- { "es6", "0x.6300...0094A0..D1..FF97", 16, 0, mov2_cond, mov0_patch, mov0_applied, true, MAKEHOSVERSION(14,0,0) },
+ { "es6", "0x.6300...0094A0..D1..FF97", 16, 0, mov2_cond, mov0_patch, mov0_applied, true, MAKEHOSVERSION(14,0,0), MAKEHOSVERSION(17,0,1) },
{ "es7", "0x.6F00...0094A0..D1..FF97", 16, 0, mov2_cond, mov0_patch, mov0_applied, true, MAKEHOSVERSION(18,0,0) },
};
From 88297f8150a906dc65aa225e135ea0c61d3ab21c Mon Sep 17 00:00:00 2001
From: impeeza <41979604+impeeza@users.noreply.github.com>
Date: Tue, 11 Jun 2024 12:18:04 -0500
Subject: [PATCH 13/45] Bump version
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Bump version to 1.5.2 due to the changes needed to handle the new way to treat ACID signatures on Atmosphère 1.7.1
---
Makefile | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Makefile b/Makefile
index 43cec76..66ad6e7 100644
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@ MAKEFILES := sysmod overlay
TARGETS := $(foreach dir,$(MAKEFILES),$(CURDIR)/$(dir))
# the below was taken from atmosphere + switch-examples makefile
-export VERSION := 1.5.1
+export VERSION := 1.5.2
ifneq ($(strip $(shell git symbolic-ref --short HEAD 2>/dev/null)),)
export GIT_BRANCH := $(shell git symbolic-ref --short HEAD)
From c7aee425a70e975819568a4917779b570e2d392a Mon Sep 17 00:00:00 2001
From: impeeza
Date: Sat, 19 Oct 2024 20:15:03 -0500
Subject: [PATCH 14/45] 1.5.3
---
Makefile | 2 +-
overlay/src/main.cpp | 14 ++++++++------
sysmod/src/main.cpp | 17 ++++++++++++++---
sysmod/sys-patch.json | 1 +
4 files changed, 24 insertions(+), 10 deletions(-)
diff --git a/Makefile b/Makefile
index 66ad6e7..e0006b2 100644
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@ MAKEFILES := sysmod overlay
TARGETS := $(foreach dir,$(MAKEFILES),$(CURDIR)/$(dir))
# the below was taken from atmosphere + switch-examples makefile
-export VERSION := 1.5.2
+export VERSION := 1.5.3
ifneq ($(strip $(shell git symbolic-ref --short HEAD 2>/dev/null)),)
export GIT_BRANCH := $(shell git symbolic-ref --short HEAD)
diff --git a/overlay/src/main.cpp b/overlay/src/main.cpp
index f957055..b4960b6 100644
--- a/overlay/src/main.cpp
+++ b/overlay/src/main.cpp
@@ -104,8 +104,8 @@ class GuiToggle final : public tsl::Gui {
list->addItem(config_noncasigchk_old.create_list_item("noncasigchk_old"));
list->addItem(config_noncasigchk_new.create_list_item("noncasigchk_new"));
list->addItem(config_noncasigchk_new2.create_list_item("noncasigchk_new2"));
- list->addItem(config_nocntchk_old.create_list_item("nocntchk_old"));
- list->addItem(config_nocntchk_new.create_list_item("nocntchk_new"));
+ list->addItem(config_nocntchk.create_list_item("nocntchk"));
+ list->addItem(config_nocntchk_FW19.create_list_item("nocntchk_FW19"));
list->addItem(new tsl::elm::CategoryHeader("LDR - 0100000000000001"));
list->addItem(config_noacidsigchk.create_list_item("noacidsigchk"));
@@ -117,7 +117,8 @@ class GuiToggle final : public tsl::Gui {
list->addItem(config_es4.create_list_item("es4"));
list->addItem(config_es5.create_list_item("es5"));
list->addItem(config_es6.create_list_item("es6"));
- list->addItem(config_es7.create_list_item("es7"));
+ list->addItem(config_es7fw18.create_list_item("es7_FW18"));
+ list->addItem(config_es7fw1819.create_list_item("es7_FW18-19"));
list->addItem(new tsl::elm::CategoryHeader("NIFM - 010000000000000F"));
list->addItem(config_ctest.create_list_item("ctest"));
@@ -131,8 +132,8 @@ class GuiToggle final : public tsl::Gui {
ConfigEntry config_noncasigchk_old{"fs", "noncasigchk_old", true};
ConfigEntry config_noncasigchk_new{"fs", "noncasigchk_new", true};
ConfigEntry config_noncasigchk_new2{"fs", "noncasigchk_new2", true};
- ConfigEntry config_nocntchk_old{"fs", "nocntchk_old", true};
- ConfigEntry config_nocntchk_new{"fs", "nocntchk_new", true};
+ ConfigEntry config_nocntchk{"fs", "nocntchk", true};
+ ConfigEntry config_nocntchk_FW19{"fs", "nocntchk_FW19", true};
ConfigEntry config_noacidsigchk{"ldr", "noacidsigchk", true};
ConfigEntry config_es1{"es", "es1", true};
ConfigEntry config_es2{"es", "es2", true};
@@ -140,7 +141,8 @@ class GuiToggle final : public tsl::Gui {
ConfigEntry config_es4{"es", "es4", true};
ConfigEntry config_es5{"es", "es5", true};
ConfigEntry config_es6{"es", "es6", true};
- ConfigEntry config_es7{"es", "es7", true};
+ ConfigEntry config_es7fw18{"es", "es7_FW18", true};
+ ConfigEntry config_es7fw1819{"es", "es7_FW18-19", true};
ConfigEntry config_ctest{"nifm", "ctest", false};
};
diff --git a/sysmod/src/main.cpp b/sysmod/src/main.cpp
index e760f33..bbf512c 100644
--- a/sysmod/src/main.cpp
+++ b/sysmod/src/main.cpp
@@ -181,11 +181,13 @@ constexpr auto ctest_cond(u32 inst) -> bool {
// to view patches, use https://armconverter.com/?lock=arm64
constexpr PatchData ret0_patch_data{ "0xE0031F2A" };
+constexpr PatchData ret1_patch_data{ "0x10000014" };
constexpr PatchData nop_patch_data{ "0x1F2003D5" };
constexpr PatchData mov0_patch_data{ "0xE0031FAA" };
constexpr PatchData ctest_patch_data{ "0x00309AD2001EA1F2610100D4E0031FAAC0035FD6" };
constexpr auto ret0_patch(u32 inst) -> PatchData { return ret0_patch_data; }
+constexpr auto ret1_patch(u32 inst) -> PatchData { return ret1_patch_data; }
constexpr auto nop_patch(u32 inst) -> PatchData { return nop_patch_data; }
constexpr auto subs_patch(u32 inst) -> PatchData { return subi_cond(inst) ? (u8)0x1 : (u8)0x0; }
constexpr auto mov0_patch(u32 inst) -> PatchData { return mov0_patch_data; }
@@ -201,6 +203,10 @@ constexpr auto ret0_applied(const u8* data, u32 inst) -> bool {
return ret0_patch(inst).cmp(data);
}
+constexpr auto ret1_applied(const u8* data, u32 inst) -> bool {
+ return ret1_patch(inst).cmp(data);
+}
+
constexpr auto nop_applied(const u8* data, u32 inst) -> bool {
return nop_patch(inst).cmp(data);
}
@@ -231,8 +237,11 @@ constinit Patterns fs_patterns[] = {
{ "noncasigchk_old", "0x1E42B9", -5, 0, tbz_cond, nop_patch, nop_applied, true, MAKEHOSVERSION(10,0,0), MAKEHOSVERSION(14,2,1) },
{ "noncasigchk_new", "0x3E4479", -5, 0, tbz_cond, nop_patch, nop_applied, true, MAKEHOSVERSION(15,0,0), MAKEHOSVERSION(16,1,0) },
{ "noncasigchk_new2", "0x258052", -5, 0, tbz_cond, nop_patch, nop_applied, true, MAKEHOSVERSION(17,0,0) },
- { "nocntchk_old", "0x081C00121F05007181000054", -4, 0, bl_cond, ret0_patch, ret0_applied, true, MAKEHOSVERSION(10,0,0), MAKEHOSVERSION(14,2,1) },
- { "nocntchk_new", "0x081C00121F05007141010054", -4, 0, bl_cond, ret0_patch, ret0_applied, true, MAKEHOSVERSION(15,0,0) },
+ { "nocntchk", "0x081C00121F050071..0054", -4, 0, bl_cond, ret0_patch, ret0_applied, true, MAKEHOSVERSION(10,0,0), MAKEHOSVERSION(19,0,0) },
+ //new good patch tested on fw 19 (thnks mrdude)
+ { "nocntchk_FW19", "0x1C0012.050071..0054..00.60", -9, 0, bl_cond, ret0_patch, ret0_applied, true, MAKEHOSVERSION(19,0,0) },
+ //
+
};
constinit Patterns ldr_patterns[] = {
@@ -246,7 +255,9 @@ constinit Patterns es_patterns[] = {
{ "es4", "0xC0FDFF35A8C35838", -4, 0, mov_cond, nop_patch, nop_applied, true, MAKEHOSVERSION(11,0,0), MAKEHOSVERSION(13,2,1) },
{ "es5", "0xE023009145EEFF97", -4, 0, cbz_cond, b_patch, b_applied, true, MAKEHOSVERSION(11,0,0), MAKEHOSVERSION(13,2,1) },
{ "es6", "0x.6300...0094A0..D1..FF97", 16, 0, mov2_cond, mov0_patch, mov0_applied, true, MAKEHOSVERSION(14,0,0), MAKEHOSVERSION(17,0,1) },
- { "es7", "0x.6F00...0094A0..D1..FF97", 16, 0, mov2_cond, mov0_patch, mov0_applied, true, MAKEHOSVERSION(18,0,0) },
+ //new good patch tested on fw 18-19
+ { "es7_FW18", "0x.6F00...0094A0..D1..FF97", 16, 0, mov2_cond, mov0_patch, mov0_applied, true, MAKEHOSVERSION(18,0,0) },
+ { "es7_FW18-19", "0xFF97..132A...A9........FF.0491C0035FD6", 2, 0, mov2_cond, mov0_patch, mov0_applied, true, MAKEHOSVERSION(18,0,0), MAKEHOSVERSION(19,0,0) },
};
constinit Patterns nifm_patterns[] = {
diff --git a/sysmod/sys-patch.json b/sysmod/sys-patch.json
index 1b0dcc5..c1ca57a 100644
--- a/sysmod/sys-patch.json
+++ b/sysmod/sys-patch.json
@@ -166,6 +166,7 @@
"type": "debug_flags",
"value": {
"allow_debug": false,
+ "force_debug_prod": false,
"force_debug": true
}
}]
From aff2498024337f9b584788f2dd17275b5b1e6a72 Mon Sep 17 00:00:00 2001
From: impeeza
Date: Thu, 24 Oct 2024 18:19:03 -0500
Subject: [PATCH 15/45] Consolidate Patches
---
overlay/src/main.cpp | 6 ++----
sysmod/src/main.cpp | 6 ++----
2 files changed, 4 insertions(+), 8 deletions(-)
diff --git a/overlay/src/main.cpp b/overlay/src/main.cpp
index b4960b6..d766580 100644
--- a/overlay/src/main.cpp
+++ b/overlay/src/main.cpp
@@ -117,8 +117,7 @@ class GuiToggle final : public tsl::Gui {
list->addItem(config_es4.create_list_item("es4"));
list->addItem(config_es5.create_list_item("es5"));
list->addItem(config_es6.create_list_item("es6"));
- list->addItem(config_es7fw18.create_list_item("es7_FW18"));
- list->addItem(config_es7fw1819.create_list_item("es7_FW18-19"));
+ list->addItem(config_es7.create_list_item("es7"));
list->addItem(new tsl::elm::CategoryHeader("NIFM - 010000000000000F"));
list->addItem(config_ctest.create_list_item("ctest"));
@@ -141,8 +140,7 @@ class GuiToggle final : public tsl::Gui {
ConfigEntry config_es4{"es", "es4", true};
ConfigEntry config_es5{"es", "es5", true};
ConfigEntry config_es6{"es", "es6", true};
- ConfigEntry config_es7fw18{"es", "es7_FW18", true};
- ConfigEntry config_es7fw1819{"es", "es7_FW18-19", true};
+ ConfigEntry config_es7{"es", "es7", true};
ConfigEntry config_ctest{"nifm", "ctest", false};
};
diff --git a/sysmod/src/main.cpp b/sysmod/src/main.cpp
index bbf512c..7c7293b 100644
--- a/sysmod/src/main.cpp
+++ b/sysmod/src/main.cpp
@@ -254,10 +254,8 @@ constinit Patterns es_patterns[] = {
{ "es3", "0xF3031FAA02000014", -4, 0, bne_cond, nop_patch, nop_applied, true, FW_VER_ANY, MAKEHOSVERSION(10,2,0) },
{ "es4", "0xC0FDFF35A8C35838", -4, 0, mov_cond, nop_patch, nop_applied, true, MAKEHOSVERSION(11,0,0), MAKEHOSVERSION(13,2,1) },
{ "es5", "0xE023009145EEFF97", -4, 0, cbz_cond, b_patch, b_applied, true, MAKEHOSVERSION(11,0,0), MAKEHOSVERSION(13,2,1) },
- { "es6", "0x.6300...0094A0..D1..FF97", 16, 0, mov2_cond, mov0_patch, mov0_applied, true, MAKEHOSVERSION(14,0,0), MAKEHOSVERSION(17,0,1) },
- //new good patch tested on fw 18-19
- { "es7_FW18", "0x.6F00...0094A0..D1..FF97", 16, 0, mov2_cond, mov0_patch, mov0_applied, true, MAKEHOSVERSION(18,0,0) },
- { "es7_FW18-19", "0xFF97..132A...A9........FF.0491C0035FD6", 2, 0, mov2_cond, mov0_patch, mov0_applied, true, MAKEHOSVERSION(18,0,0), MAKEHOSVERSION(19,0,0) },
+ { "es6", "0x..00...0094A0..D1..FF97", 16, 0, mov2_cond, mov0_patch, mov0_applied, true, MAKEHOSVERSION(14,0,0), MAKEHOSVERSION(18,1,0) },
+ { "es7", "0xFF97..132A...A9........FF.0491C0035FD6", 2, 0, mov2_cond, mov0_patch, mov0_applied, true, MAKEHOSVERSION(18,0,0), MAKEHOSVERSION(19,0,0) },
};
constinit Patterns nifm_patterns[] = {
From c8e5936eabc80f6fb1aa2a2e29c6a0415e76264c Mon Sep 17 00:00:00 2001
From: impeeza
Date: Thu, 24 Oct 2024 18:45:26 -0500
Subject: [PATCH 16/45] Typo Correction
---
sysmod/src/main.cpp | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/sysmod/src/main.cpp b/sysmod/src/main.cpp
index 7c7293b..32a055f 100644
--- a/sysmod/src/main.cpp
+++ b/sysmod/src/main.cpp
@@ -80,7 +80,7 @@ struct PatchData {
}
}
- auto cmp(const void* _data) -> bool {
+ constexpr auto cmp(const void* _data) -> bool {
return !std::memcmp(data, _data, size);
}
@@ -241,7 +241,6 @@ constinit Patterns fs_patterns[] = {
//new good patch tested on fw 19 (thnks mrdude)
{ "nocntchk_FW19", "0x1C0012.050071..0054..00.60", -9, 0, bl_cond, ret0_patch, ret0_applied, true, MAKEHOSVERSION(19,0,0) },
//
-
};
constinit Patterns ldr_patterns[] = {
From b2bb089c381918ee29455a2928647be86799ace3 Mon Sep 17 00:00:00 2001
From: borntohonk <6264306+borntohonk@users.noreply.github.com>
Date: Sat, 26 Oct 2024 10:44:14 +0200
Subject: [PATCH 17/45] Add nim crashfix for blanker/incognito
---
Makefile | 2 +-
overlay/src/main.cpp | 18 +++++++---------
sysmod/src/main.cpp | 50 +++++++++++++++++++++++++++++---------------
3 files changed, 41 insertions(+), 29 deletions(-)
diff --git a/Makefile b/Makefile
index e0006b2..5d4b3a8 100644
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@ MAKEFILES := sysmod overlay
TARGETS := $(foreach dir,$(MAKEFILES),$(CURDIR)/$(dir))
# the below was taken from atmosphere + switch-examples makefile
-export VERSION := 1.5.3
+export VERSION := 1.5.4
ifneq ($(strip $(shell git symbolic-ref --short HEAD 2>/dev/null)),)
export GIT_BRANCH := $(shell git symbolic-ref --short HEAD)
diff --git a/overlay/src/main.cpp b/overlay/src/main.cpp
index d766580..46a1500 100644
--- a/overlay/src/main.cpp
+++ b/overlay/src/main.cpp
@@ -105,7 +105,7 @@ class GuiToggle final : public tsl::Gui {
list->addItem(config_noncasigchk_new.create_list_item("noncasigchk_new"));
list->addItem(config_noncasigchk_new2.create_list_item("noncasigchk_new2"));
list->addItem(config_nocntchk.create_list_item("nocntchk"));
- list->addItem(config_nocntchk_FW19.create_list_item("nocntchk_FW19"));
+ list->addItem(config_nocntchk2.create_list_item("nocntchk2"));
list->addItem(new tsl::elm::CategoryHeader("LDR - 0100000000000001"));
list->addItem(config_noacidsigchk.create_list_item("noacidsigchk"));
@@ -114,14 +114,13 @@ class GuiToggle final : public tsl::Gui {
list->addItem(config_es1.create_list_item("es1"));
list->addItem(config_es2.create_list_item("es2"));
list->addItem(config_es3.create_list_item("es3"));
- list->addItem(config_es4.create_list_item("es4"));
- list->addItem(config_es5.create_list_item("es5"));
- list->addItem(config_es6.create_list_item("es6"));
- list->addItem(config_es7.create_list_item("es7"));
list->addItem(new tsl::elm::CategoryHeader("NIFM - 010000000000000F"));
list->addItem(config_ctest.create_list_item("ctest"));
+ list->addItem(new tsl::elm::CategoryHeader("NIM - 0100000000000025"));
+ list->addItem(config_nim.create_list_item("nim"));
+
frame->setContent(list);
return frame;
}
@@ -132,16 +131,13 @@ class GuiToggle final : public tsl::Gui {
ConfigEntry config_noncasigchk_new{"fs", "noncasigchk_new", true};
ConfigEntry config_noncasigchk_new2{"fs", "noncasigchk_new2", true};
ConfigEntry config_nocntchk{"fs", "nocntchk", true};
- ConfigEntry config_nocntchk_FW19{"fs", "nocntchk_FW19", true};
+ ConfigEntry config_nocntchk2{"fs", "nocntchk2", true};
ConfigEntry config_noacidsigchk{"ldr", "noacidsigchk", true};
ConfigEntry config_es1{"es", "es1", true};
ConfigEntry config_es2{"es", "es2", true};
ConfigEntry config_es3{"es", "es3", true};
- ConfigEntry config_es4{"es", "es4", true};
- ConfigEntry config_es5{"es", "es5", true};
- ConfigEntry config_es6{"es", "es6", true};
- ConfigEntry config_es7{"es", "es7", true};
- ConfigEntry config_ctest{"nifm", "ctest", false};
+ ConfigEntry config_ctest{"nifm", "ctest", true};
+ ConfigEntry config_nim{"nim", "nim", true};
};
class GuiLog final : public tsl::Gui {
diff --git a/sysmod/src/main.cpp b/sysmod/src/main.cpp
index 32a055f..cce3ae3 100644
--- a/sysmod/src/main.cpp
+++ b/sysmod/src/main.cpp
@@ -162,13 +162,21 @@ constexpr auto mov_cond(u32 inst) -> bool {
}
constexpr auto mov2_cond(u32 inst) -> bool {
- if (hosversionBefore(15,0,0)) {
- return (inst >> 24) == 0x92; // and x0, x19, #0xffffffff
- } else {
+ if (hosversionBefore(12,0,0) || !hosversionBefore(15,0,0)) {
return (inst >> 24) == 0x2A; // mov x0, x20
+ } else {
+ return (inst >> 24) == 0x92; // and x0, x19, #0xffffffff
}
}
+constexpr auto and_cond(u32 inst) -> bool {
+ return ((inst >> 24) & 0x1F) == 0x0A;
+}
+
+constexpr auto adr_cond(u32 inst) -> bool {
+ return (inst >> 24) == 0x10; // adr x2, LAB
+}
+
constexpr auto bne_cond(u32 inst) -> bool {
const auto type = inst >> 24;
const auto cond = inst & 0x10;
@@ -183,7 +191,10 @@ constexpr auto ctest_cond(u32 inst) -> bool {
constexpr PatchData ret0_patch_data{ "0xE0031F2A" };
constexpr PatchData ret1_patch_data{ "0x10000014" };
constexpr PatchData nop_patch_data{ "0x1F2003D5" };
+//mov x0, xzr
constexpr PatchData mov0_patch_data{ "0xE0031FAA" };
+//mov x2, xzr
+constexpr PatchData mov2_patch_data{ "0xE2031FAA" };
constexpr PatchData ctest_patch_data{ "0x00309AD2001EA1F2610100D4E0031FAAC0035FD6" };
constexpr auto ret0_patch(u32 inst) -> PatchData { return ret0_patch_data; }
@@ -191,6 +202,7 @@ constexpr auto ret1_patch(u32 inst) -> PatchData { return ret1_patch_data; }
constexpr auto nop_patch(u32 inst) -> PatchData { return nop_patch_data; }
constexpr auto subs_patch(u32 inst) -> PatchData { return subi_cond(inst) ? (u8)0x1 : (u8)0x0; }
constexpr auto mov0_patch(u32 inst) -> PatchData { return mov0_patch_data; }
+constexpr auto mov2_patch(u32 inst) -> PatchData { return mov2_patch_data; }
constexpr auto ctest_patch(u32 inst) -> PatchData { return ctest_patch_data; }
constexpr auto b_patch(u32 inst) -> PatchData {
@@ -227,6 +239,10 @@ constexpr auto mov0_applied(const u8* data, u32 inst) -> bool {
return mov0_patch(inst).cmp(data);
}
+constexpr auto mov2_applied(const u8* data, u32 inst) -> bool {
+ return mov2_patch(inst).cmp(data);
+}
+
constexpr auto ctest_applied(const u8* data, u32 inst) -> bool {
return ctest_patch(inst).cmp(data);
}
@@ -236,29 +252,28 @@ constinit Patterns fs_patterns[] = {
{ "noacidsigchk2", "0x0210911F000072", -5, 0, bl_cond, ret0_patch, ret0_applied, true, FW_VER_ANY, MAKEHOSVERSION(9,2,0) },
{ "noncasigchk_old", "0x1E42B9", -5, 0, tbz_cond, nop_patch, nop_applied, true, MAKEHOSVERSION(10,0,0), MAKEHOSVERSION(14,2,1) },
{ "noncasigchk_new", "0x3E4479", -5, 0, tbz_cond, nop_patch, nop_applied, true, MAKEHOSVERSION(15,0,0), MAKEHOSVERSION(16,1,0) },
- { "noncasigchk_new2", "0x258052", -5, 0, tbz_cond, nop_patch, nop_applied, true, MAKEHOSVERSION(17,0,0) },
- { "nocntchk", "0x081C00121F050071..0054", -4, 0, bl_cond, ret0_patch, ret0_applied, true, MAKEHOSVERSION(10,0,0), MAKEHOSVERSION(19,0,0) },
- //new good patch tested on fw 19 (thnks mrdude)
- { "nocntchk_FW19", "0x1C0012.050071..0054..00.60", -9, 0, bl_cond, ret0_patch, ret0_applied, true, MAKEHOSVERSION(19,0,0) },
- //
+ { "noncasigchk_new2", "0x258052", -5, 0, tbz_cond, nop_patch, nop_applied, true, MAKEHOSVERSION(17,0,0), FW_VER_ANY },
+ { "nocntchk", "0x081C00121F050071..0054", -4, 0, bl_cond, ret0_patch, ret0_applied, true, MAKEHOSVERSION(10,0,0), MAKEHOSVERSION(18,1,0) },
+ { "nocntchk2", "0x091C00123F05007161010054", -8, 0, bl_cond, ret0_patch, ret0_applied, true, MAKEHOSVERSION(19,0,0), FW_VER_ANY },
};
constinit Patterns ldr_patterns[] = {
- { "noacidsigchk", "0xFD7B.A8C0035FD6", 16, 2, subs_cond, subs_patch, subs_applied, true },
+ { "noacidsigchk", "0xFD7B.A8C0035FD6", 16, 2, subs_cond, subs_patch, subs_applied, true, FW_VER_ANY },
};
constinit Patterns es_patterns[] = {
- { "es1", "0x1F90013128928052", -4, 0, cbz_cond, b_patch, b_applied, true, FW_VER_ANY, MAKEHOSVERSION(13,2,1) },
- { "es2", "0xC07240F9E1930091", -4, 0, tbz_cond, nop_patch, nop_applied, true, FW_VER_ANY, MAKEHOSVERSION(10,2,0) },
- { "es3", "0xF3031FAA02000014", -4, 0, bne_cond, nop_patch, nop_applied, true, FW_VER_ANY, MAKEHOSVERSION(10,2,0) },
- { "es4", "0xC0FDFF35A8C35838", -4, 0, mov_cond, nop_patch, nop_applied, true, MAKEHOSVERSION(11,0,0), MAKEHOSVERSION(13,2,1) },
- { "es5", "0xE023009145EEFF97", -4, 0, cbz_cond, b_patch, b_applied, true, MAKEHOSVERSION(11,0,0), MAKEHOSVERSION(13,2,1) },
- { "es6", "0x..00...0094A0..D1..FF97", 16, 0, mov2_cond, mov0_patch, mov0_applied, true, MAKEHOSVERSION(14,0,0), MAKEHOSVERSION(18,1,0) },
- { "es7", "0xFF97..132A...A9........FF.0491C0035FD6", 2, 0, mov2_cond, mov0_patch, mov0_applied, true, MAKEHOSVERSION(18,0,0), MAKEHOSVERSION(19,0,0) },
+ { "es1", "0x..00.....e0.0091..0094..4092...d1", 16, 0, and_cond, mov0_patch, mov0_applied, true, FW_VER_ANY, MAKEHOSVERSION(1,0,0) },
+ { "es2", "0x..00.....e0.0091..0094..4092...a9", 16, 0, and_cond, mov0_patch, mov0_applied, true, MAKEHOSVERSION(2,0,0), MAKEHOSVERSION(8,1,1) },
+ { "es3", "0x..00...0094a0..d1..ff97.......a9", 16, 0, mov2_cond, mov0_patch, mov0_applied, true, MAKEHOSVERSION(9,0,0), FW_VER_ANY }, //9.0.0 - 19.0.0+
};
constinit Patterns nifm_patterns[] = {
- { "ctest", "....................F40300AA....F30314AAE00314AA9F0201397F8E04F8", 16, -16, ctest_cond, ctest_patch, ctest_applied, true },
+ { "ctest", "....................F40300AA....F30314AAE00314AA9F0201397F8E04F8", 16, -16, ctest_cond, ctest_patch, ctest_applied, true, FW_VER_ANY },
+};
+
+constinit Patterns nim_patterns[] = {
+ { "nim", "0x.0F00351F2003D5", 8, 0, adr_cond, mov2_patch, mov2_applied, true, MAKEHOSVERSION(17,0,0), FW_VER_ANY },
+ // { "nim2", "0x600F00351F2003D5", 8, 0, adr_cond, mov2_patch, mov2_applied, true, MAKEHOSVERSION(19,0,0), FW_VER_ANY },
};
// NOTE: add system titles that you want to be patched to this table.
@@ -270,6 +285,7 @@ constinit PatchEntry patches[] = {
// es was added in fw 2
{ "es", 0x0100000000000033, es_patterns, MAKEHOSVERSION(2,0,0) },
{ "nifm", 0x010000000000000F, nifm_patterns },
+ { "nim", 0x0100000000000025, nim_patterns },
};
struct EmummcPaths {
From 3de28533751593b2bb385d009c290a70e7852b42 Mon Sep 17 00:00:00 2001
From: impeeza <41979604+impeeza@users.noreply.github.com>
Date: Sun, 27 Oct 2024 13:01:20 -0500
Subject: [PATCH 18/45] Update build-jobs.yaml
add a comment for a generic container
container: devkitpro/devkita64:latest
---
.github/workflows/build-jobs.yaml | 2 ++
1 file changed, 2 insertions(+)
diff --git a/.github/workflows/build-jobs.yaml b/.github/workflows/build-jobs.yaml
index 1b67049..9858275 100644
--- a/.github/workflows/build-jobs.yaml
+++ b/.github/workflows/build-jobs.yaml
@@ -8,6 +8,8 @@ jobs:
name: build
runs-on: ubuntu-latest
container: ghcr.io/pgalonza/devkita64-atmosphere:latest
+ #or you can use a generic one
+ #container: devkitpro/devkita64:latest
steps:
- name: Checkout
uses: actions/checkout@v4
From 9293335118fc684b29b446ea41d2c6e23f030060 Mon Sep 17 00:00:00 2001
From: borntohonk <6264306+borntohonk@users.noreply.github.com>
Date: Sun, 27 Oct 2024 10:57:15 +0100
Subject: [PATCH 19/45] :)
---
.github/workflows/build-jobs.yaml | 59 ++++++++++++++++++++++---------
.github/workflows/build.yml | 14 --------
.github/workflows/release.yml | 38 --------------------
Makefile | 2 +-
README.md | 14 +++-----
overlay/src/main.cpp | 10 ++++--
sysmod/src/main.cpp | 46 +++++++++++++++++++-----
7 files changed, 95 insertions(+), 88 deletions(-)
delete mode 100644 .github/workflows/build.yml
delete mode 100644 .github/workflows/release.yml
diff --git a/.github/workflows/build-jobs.yaml b/.github/workflows/build-jobs.yaml
index 9858275..dfd713e 100644
--- a/.github/workflows/build-jobs.yaml
+++ b/.github/workflows/build-jobs.yaml
@@ -2,24 +2,51 @@ name: Build jobs
on:
workflow_call:
+ workflow_dispatch:
+ push:
jobs:
build:
- name: build
runs-on: ubuntu-latest
- container: ghcr.io/pgalonza/devkita64-atmosphere:latest
- #or you can use a generic one
- #container: devkitpro/devkita64:latest
+ container: devkitpro/devkita64
+
steps:
- - name: Checkout
- uses: actions/checkout@v4
- with:
- submodules: recursive
- - name: Build sys-patch
- run: |
- make dist -j $(nproc)
- - name: Upload artifacts
- uses: actions/upload-artifact@v4
- with:
- name: sys-patch-artifacts
- path: ./sys-patch.zip
+ - name: Checkout
+ uses: actions/checkout@v4
+ with:
+ fetch-tags: true
+ path: sys-patch
+ submodules: recursive
+
+ - name: Build sys-patch
+ run: |
+ make -C sys-patch -j$(nproc) dist && \
+ VERSION=$(grep 'export VERSION := ' sys-patch/Makefile | cut -c 19-)
+ TAGVERSION=$(curl -s https://api.github.com/repos/$GITHUB_REPOSITORY/releases/latest | grep "tag_name" | head -1 | cut -d '"' -f 4)
+ echo "VERSION=${VERSION}" >> $GITHUB_ENV
+ echo "TAGVERSION=${TAGVERSION}" >> $GITHUB_ENV
+
+ - name: Upload artifact
+ uses: actions/upload-artifact@v4
+ with:
+ include-hidden-files: true
+ overwrite: true
+ name: sys-patch-${{ env.VERSION }}
+ path: sys-patch/out/
+
+ - name: Fetch git cli and upload release
+ env:
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ run: |
+ if [ ${{ env.TAGVERSION }} = v${{ env.VERSION }} ];
+ then echo "Tag version and makefile version are same, don't publish release, only artifact uploaded."
+ else
+ wget -q $(curl -s https://api.github.com/repos/cli/cli/releases/latest | grep "browser_download_url" | grep "linux_amd64.tar.gz" | head -1 | cut -d '"' -f 4) && \
+ tar -xzf gh*.tar.gz && \
+ chmod +x gh*/bin/gh && \
+ chmod +x gh*/bin/gh && \
+ cp gh*/bin/gh /bin/gh && \
+ rm gh*.tar.gz && \
+ rm -rf gh*
+ gh release create v${{ env.VERSION }} sys-patch/sys-patch.zip --title "Sys-patch version ${{ env.VERSION }}" --repo github.com/$GITHUB_REPOSITORY
+ fi
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
deleted file mode 100644
index 6443090..0000000
--- a/.github/workflows/build.yml
+++ /dev/null
@@ -1,14 +0,0 @@
-name: Build sys-patch
-
-on:
- push:
- branches:
- - master
- - feature-integration
- paths-ignore:
- - 'Dockerfile'
- - '.github/workflows/image.yml'
-
-jobs:
- build-workflow:
- uses: ./.github/workflows/build-jobs.yaml
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
deleted file mode 100644
index ce4f921..0000000
--- a/.github/workflows/release.yml
+++ /dev/null
@@ -1,38 +0,0 @@
-name: Create release
-
-on:
- push:
- tags:
- - '[0-9]+.[0-9]+.[0-9]+'
-
-permissions:
- contents: write
-
-jobs:
- build-workflow:
- uses: ./.github/workflows/build-jobs.yaml
- create-release:
- runs-on: ubuntu-latest
- needs: build-workflow
- steps:
- - name: Checkout
- uses: actions/checkout@v4
- with:
- fetch-depth: 0
- - name: Generate a changelog
- uses: orhun/git-cliff-action@v3
- with:
- config: ./configs/cliff.toml
- args: --verbose
- - name: Download artifact
- uses: actions/download-artifact@v4
- with:
- name: sys-patch-artifacts
- path: "./"
- - name: Create release
- uses: ncipollo/release-action@v1
- with:
- artifacts: "sys-patch.zip"
- prerelease: false
- name: "ns-sys-patch ${{ github.ref_name }}"
- bodyFile: "git-cliff/CHANGELOG.md"
diff --git a/Makefile b/Makefile
index 5d4b3a8..40c7fc0 100644
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@ MAKEFILES := sysmod overlay
TARGETS := $(foreach dir,$(MAKEFILES),$(CURDIR)/$(dir))
# the below was taken from atmosphere + switch-examples makefile
-export VERSION := 1.5.4
+export VERSION := 1.5.6
ifneq ($(strip $(shell git symbolic-ref --short HEAD 2>/dev/null)),)
export GIT_BRANCH := $(shell git symbolic-ref --short HEAD)
diff --git a/README.md b/README.md
index ad833ca..f1940d8 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
# sys-patch
-A script-like system module that patches **fs**, **es**, **ldr** and **nifm** on boot.
+A script-like system module that patches **fs**, **es**, **ldr**, **nifm** and **nim** on boot.
---
@@ -57,14 +57,10 @@ To activate the sys-module, reboot your switch, or, use [sysmodules overlay](htt
Here's a quick run down of what's being patched:
-- **fs**
-- **es**
-- **ldr**
-- **nifm**
-
-**fs** and **es** need new patches after every new firmware version.
-**ldr** needs new patches after every new [Atmosphere](https://github.com/Atmosphere-NX/Atmosphere/) release.
-**nifm** ctest patch allows the device to connect to a network without needing to make a connection to a server.
+- **fs** and **es** need new patches after every new firmware version.
+- **ldr** needs new patches after every new [Atmosphere](https://github.com/Atmosphere-NX/Atmosphere/) release.
+- **nifm** ctest patch allows the device to connect to a network without needing to make a connection to a server
+- **nim** patches to the ssl function call within nim that queries "https://api.hac.%.ctest.srv.nintendo.net/v1/time", and crashes the console if console ssl certificate is not intact. This patch instead makes the console not crash.
The patches are applied on boot. Once done, the sys-module stops running.
The memory footprint *(16kib)* and the binary size *(~50kib)* are both very small.
diff --git a/overlay/src/main.cpp b/overlay/src/main.cpp
index 46a1500..2afb6f3 100644
--- a/overlay/src/main.cpp
+++ b/overlay/src/main.cpp
@@ -103,7 +103,6 @@ class GuiToggle final : public tsl::Gui {
list->addItem(config_noacidsigchk2.create_list_item("noacidsigchk2"));
list->addItem(config_noncasigchk_old.create_list_item("noncasigchk_old"));
list->addItem(config_noncasigchk_new.create_list_item("noncasigchk_new"));
- list->addItem(config_noncasigchk_new2.create_list_item("noncasigchk_new2"));
list->addItem(config_nocntchk.create_list_item("nocntchk"));
list->addItem(config_nocntchk2.create_list_item("nocntchk2"));
@@ -121,6 +120,11 @@ class GuiToggle final : public tsl::Gui {
list->addItem(new tsl::elm::CategoryHeader("NIM - 0100000000000025"));
list->addItem(config_nim.create_list_item("nim"));
+ list->addItem(new tsl::elm::CategoryHeader("Disable CA Verification - apply all"));
+ list->addItem(config_ssl1.create_list_item("disablecaverification1"));
+ list->addItem(config_ssl2.create_list_item("disablecaverification2"));
+ list->addItem(config_ssl3.create_list_item("disablecaverification3"));
+
frame->setContent(list);
return frame;
}
@@ -129,7 +133,6 @@ class GuiToggle final : public tsl::Gui {
ConfigEntry config_noacidsigchk2{"fs", "noacidsigchk2", true};
ConfigEntry config_noncasigchk_old{"fs", "noncasigchk_old", true};
ConfigEntry config_noncasigchk_new{"fs", "noncasigchk_new", true};
- ConfigEntry config_noncasigchk_new2{"fs", "noncasigchk_new2", true};
ConfigEntry config_nocntchk{"fs", "nocntchk", true};
ConfigEntry config_nocntchk2{"fs", "nocntchk2", true};
ConfigEntry config_noacidsigchk{"ldr", "noacidsigchk", true};
@@ -138,6 +141,9 @@ class GuiToggle final : public tsl::Gui {
ConfigEntry config_es3{"es", "es3", true};
ConfigEntry config_ctest{"nifm", "ctest", true};
ConfigEntry config_nim{"nim", "nim", true};
+ ConfigEntry config_ssl1{"ssl", "disablecaverification1", false};
+ ConfigEntry config_ssl2{"ssl", "disablecaverification2", false};
+ ConfigEntry config_ssl3{"ssl", "disablecaverification3", false};
};
class GuiLog final : public tsl::Gui {
diff --git a/sysmod/src/main.cpp b/sysmod/src/main.cpp
index cce3ae3..521f6ba 100644
--- a/sysmod/src/main.cpp
+++ b/sysmod/src/main.cpp
@@ -141,7 +141,8 @@ constexpr auto subr_cond(u32 inst) -> bool {
}
constexpr auto bl_cond(u32 inst) -> bool {
- return ((inst >> 26) & 0x3F) == 0x25;
+ const auto type = inst >> 24;
+ return type == 0x25 || type == 0x94;
}
constexpr auto tbz_cond(u32 inst) -> bool {
@@ -169,6 +170,10 @@ constexpr auto mov2_cond(u32 inst) -> bool {
}
}
+constexpr auto mov_cond3(u32 inst) -> bool {
+ return (inst >> 24) == 0xD2; // mov x10, #0x3
+}
+
constexpr auto and_cond(u32 inst) -> bool {
return ((inst >> 24) & 0x1F) == 0x0A;
}
@@ -183,6 +188,14 @@ constexpr auto bne_cond(u32 inst) -> bool {
return type == 0x54 || cond == 0x0;
}
+constexpr auto beq_cond(u32 inst) -> bool {
+ return (inst >> 24) == 0x54; // beq, 0x710011c94c
+}
+
+constexpr auto str_cond(u32 inst) -> bool {
+ return (inst >> 24) == 0xB9; // str, w8,[x19, #0x15c]
+}
+
constexpr auto ctest_cond(u32 inst) -> bool {
return std::byteswap(0xF50301AA) == inst; // mov x21, x1
}
@@ -195,6 +208,8 @@ constexpr PatchData nop_patch_data{ "0x1F2003D5" };
constexpr PatchData mov0_patch_data{ "0xE0031FAA" };
//mov x2, xzr
constexpr PatchData mov2_patch_data{ "0xE2031FAA" };
+constexpr PatchData ssl1_patch_data{ "0x0A" };
+constexpr PatchData ssl2_patch_data{ "0x08008052" };
constexpr PatchData ctest_patch_data{ "0x00309AD2001EA1F2610100D4E0031FAAC0035FD6" };
constexpr auto ret0_patch(u32 inst) -> PatchData { return ret0_patch_data; }
@@ -203,6 +218,8 @@ constexpr auto nop_patch(u32 inst) -> PatchData { return nop_patch_data; }
constexpr auto subs_patch(u32 inst) -> PatchData { return subi_cond(inst) ? (u8)0x1 : (u8)0x0; }
constexpr auto mov0_patch(u32 inst) -> PatchData { return mov0_patch_data; }
constexpr auto mov2_patch(u32 inst) -> PatchData { return mov2_patch_data; }
+constexpr auto ssl1_patch(u32 inst) -> PatchData { return ssl1_patch_data; }
+constexpr auto ssl2_patch(u32 inst) -> PatchData { return ssl2_patch_data; }
constexpr auto ctest_patch(u32 inst) -> PatchData { return ctest_patch_data; }
constexpr auto b_patch(u32 inst) -> PatchData {
@@ -243,6 +260,14 @@ constexpr auto mov2_applied(const u8* data, u32 inst) -> bool {
return mov2_patch(inst).cmp(data);
}
+constexpr auto ssl1_applied(const u8* data, u32 inst) -> bool {
+ return ssl1_patch(inst).cmp(data);
+}
+
+constexpr auto ssl2_applied(const u8* data, u32 inst) -> bool {
+ return ssl2_patch(inst).cmp(data);
+}
+
constexpr auto ctest_applied(const u8* data, u32 inst) -> bool {
return ctest_patch(inst).cmp(data);
}
@@ -250,15 +275,14 @@ constexpr auto ctest_applied(const u8* data, u32 inst) -> bool {
constinit Patterns fs_patterns[] = {
{ "noacidsigchk1", "0xC8FE4739", -24, 0, bl_cond, ret0_patch, ret0_applied, true, FW_VER_ANY, MAKEHOSVERSION(9,2,0) },
{ "noacidsigchk2", "0x0210911F000072", -5, 0, bl_cond, ret0_patch, ret0_applied, true, FW_VER_ANY, MAKEHOSVERSION(9,2,0) },
- { "noncasigchk_old", "0x1E42B9", -5, 0, tbz_cond, nop_patch, nop_applied, true, MAKEHOSVERSION(10,0,0), MAKEHOSVERSION(14,2,1) },
- { "noncasigchk_new", "0x3E4479", -5, 0, tbz_cond, nop_patch, nop_applied, true, MAKEHOSVERSION(15,0,0), MAKEHOSVERSION(16,1,0) },
- { "noncasigchk_new2", "0x258052", -5, 0, tbz_cond, nop_patch, nop_applied, true, MAKEHOSVERSION(17,0,0), FW_VER_ANY },
- { "nocntchk", "0x081C00121F050071..0054", -4, 0, bl_cond, ret0_patch, ret0_applied, true, MAKEHOSVERSION(10,0,0), MAKEHOSVERSION(18,1,0) },
- { "nocntchk2", "0x091C00123F05007161010054", -8, 0, bl_cond, ret0_patch, ret0_applied, true, MAKEHOSVERSION(19,0,0), FW_VER_ANY },
+ { "noncasigchk_old", "0x0036.......71..0054..4839", -2, 0, tbz_cond, nop_patch, nop_applied, true, MAKEHOSVERSION(10,0,0), MAKEHOSVERSION(16,1,0) },
+ { "noncasigchk_new", "0x.94..0036.258052", 2, 0, tbz_cond, nop_patch, nop_applied, true, MAKEHOSVERSION(17,0,0), FW_VER_ANY }, // 17.0.0 - 19.0.0+
+ { "nocntchk", "0x40f9...9408.0012.050071", 2, 0, bl_cond, ret0_patch, ret0_applied, true, MAKEHOSVERSION(10,0,0), MAKEHOSVERSION(18,1,0) },
+ { "nocntchk2", "0x40f9...94..40b9..0012", 2, 0, bl_cond, ret0_patch, ret0_applied, true, MAKEHOSVERSION(19,0,0), FW_VER_ANY },
};
constinit Patterns ldr_patterns[] = {
- { "noacidsigchk", "0xFD7B.A8C0035FD6", 16, 2, subs_cond, subs_patch, subs_applied, true, FW_VER_ANY },
+ { "noacidsigchk", "0xFD7B.A8C0035FD6", 16, 2, subs_cond, subs_patch, subs_applied, true, FW_VER_ANY },
};
constinit Patterns es_patterns[] = {
@@ -273,7 +297,12 @@ constinit Patterns nifm_patterns[] = {
constinit Patterns nim_patterns[] = {
{ "nim", "0x.0F00351F2003D5", 8, 0, adr_cond, mov2_patch, mov2_applied, true, MAKEHOSVERSION(17,0,0), FW_VER_ANY },
- // { "nim2", "0x600F00351F2003D5", 8, 0, adr_cond, mov2_patch, mov2_applied, true, MAKEHOSVERSION(19,0,0), FW_VER_ANY },
+};
+
+constinit Patterns ssl_patterns[] = {
+ { "disablecaverification1", "0x6A0080D2", 0, 0, mov_cond3, ssl1_patch, ssl1_applied, false, FW_VER_ANY },
+ { "disablecaverification2", "0x2409437AA0000054", 4, 0, beq_cond, ret1_patch, ret1_applied, false, FW_VER_ANY },
+ { "disablecaverification3", "0x88160012", 4, 0, str_cond, ssl2_patch, ssl2_applied, false, FW_VER_ANY },
};
// NOTE: add system titles that you want to be patched to this table.
@@ -286,6 +315,7 @@ constinit PatchEntry patches[] = {
{ "es", 0x0100000000000033, es_patterns, MAKEHOSVERSION(2,0,0) },
{ "nifm", 0x010000000000000F, nifm_patterns },
{ "nim", 0x0100000000000025, nim_patterns },
+ { "ssl", 0x0100000000000024, ssl_patterns },
};
struct EmummcPaths {
From 589e3abbb33c93e6ead49efcf17db78e5f57df1b Mon Sep 17 00:00:00 2001
From: shadow2560 <24191064+shadow2560@users.noreply.github.com>
Date: Tue, 3 Dec 2024 13:45:28 +0100
Subject: [PATCH 20/45] Fix when pattern can be in between 2 READ_BUFFER_SIZE
boundries
Signed-off-by: shadow2560 <24191064+shadow2560@users.noreply.github.com>
---
sysmod/src/main.cpp | 26 +++++++++++++++++++-------
1 file changed, 19 insertions(+), 7 deletions(-)
diff --git a/sysmod/src/main.cpp b/sysmod/src/main.cpp
index 521f6ba..6452a97 100644
--- a/sysmod/src/main.cpp
+++ b/sysmod/src/main.cpp
@@ -410,7 +410,8 @@ auto apply_patch(PatchEntry& patch) -> bool {
u64 pids[0x50]{};
s32 process_count{};
- static u8 buffer[READ_BUFFER_SIZE];
+ constexpr u64 overlap_size = 0x4f;
+ static u8 buffer[READ_BUFFER_SIZE + overlap_size];
// skip if version isn't valid
if (VERSION_SKIP &&
@@ -449,16 +450,27 @@ auto apply_patch(PatchEntry& patch) -> bool {
continue;
}
- // todo: the byte pattern can in between 2 READ_BUFFER_SIZE boundries!
- for (u64 sz = 0; sz < mem_info.size; sz += READ_BUFFER_SIZE) {
- const auto actual_size = std::min(READ_BUFFER_SIZE, mem_info.size);
- if (R_FAILED(svcReadDebugProcessMemory(buffer, handle, mem_info.addr + sz, actual_size))) {
- // todo: log failed reads!
+ // u32 overlap_size = 0;
+ // for (const auto& pattern : patch.patterns) {
+ // overlap_size = std::max(overlap_size, static_cast(pattern.byte_pattern.size));
+ // }
+ // u8* buffer = (u8*)aligned_alloc(alignof(u8*), READ_BUFFER_SIZE + overlap_size);
+ // if (!buffer) {
+ // svcCloseHandle(handle);
+ // return false;
+ // }
+ for (u64 sz = 0; sz < mem_info.size; sz += READ_BUFFER_SIZE - overlap_size) {
+ const auto actual_size = std::min(READ_BUFFER_SIZE, mem_info.size - sz);
+ if (R_FAILED(svcReadDebugProcessMemory(buffer + overlap_size, handle, mem_info.addr + sz, actual_size))) {
break;
} else {
- patcher(handle, std::span{buffer, actual_size}, mem_info.addr + sz, patch.patterns);
+ patcher(handle, std::span{buffer, actual_size + overlap_size}, mem_info.addr + sz - overlap_size, patch.patterns);
+ if (actual_size >= overlap_size) {
+ memcpy(buffer, buffer + actual_size, overlap_size);
+ }
}
}
+ // free(buffer);
}
svcCloseHandle(handle);
return true;
From 5842b3c96c9a377e9915d32ffa1e717b29a8d2bc Mon Sep 17 00:00:00 2001
From: shadow2560 <24191064+shadow2560@users.noreply.github.com>
Date: Tue, 3 Dec 2024 13:48:28 +0100
Subject: [PATCH 21/45] mov_cond3 function renamed to mov3_cond
Signed-off-by: shadow2560 <24191064+shadow2560@users.noreply.github.com>
---
sysmod/src/main.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/sysmod/src/main.cpp b/sysmod/src/main.cpp
index 6452a97..005b2fd 100644
--- a/sysmod/src/main.cpp
+++ b/sysmod/src/main.cpp
@@ -170,7 +170,7 @@ constexpr auto mov2_cond(u32 inst) -> bool {
}
}
-constexpr auto mov_cond3(u32 inst) -> bool {
+constexpr auto mov3_cond(u32 inst) -> bool {
return (inst >> 24) == 0xD2; // mov x10, #0x3
}
@@ -300,7 +300,7 @@ constinit Patterns nim_patterns[] = {
};
constinit Patterns ssl_patterns[] = {
- { "disablecaverification1", "0x6A0080D2", 0, 0, mov_cond3, ssl1_patch, ssl1_applied, false, FW_VER_ANY },
+ { "disablecaverification1", "0x6A0080D2", 0, 0, mov3_cond, ssl1_patch, ssl1_applied, false, FW_VER_ANY },
{ "disablecaverification2", "0x2409437AA0000054", 4, 0, beq_cond, ret1_patch, ret1_applied, false, FW_VER_ANY },
{ "disablecaverification3", "0x88160012", 4, 0, str_cond, ssl2_patch, ssl2_applied, false, FW_VER_ANY },
};
From e86f4711f74a4146a2a6d2c7afdc0b3087bd047a Mon Sep 17 00:00:00 2001
From: borntohonk <6264306+borntohonk@users.noreply.github.com>
Date: Wed, 4 Dec 2024 14:23:26 +0100
Subject: [PATCH 22/45] Set version 1.5.5
---
Makefile | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Makefile b/Makefile
index 40c7fc0..46276e5 100644
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@ MAKEFILES := sysmod overlay
TARGETS := $(foreach dir,$(MAKEFILES),$(CURDIR)/$(dir))
# the below was taken from atmosphere + switch-examples makefile
-export VERSION := 1.5.6
+export VERSION := 1.5.5
ifneq ($(strip $(shell git symbolic-ref --short HEAD 2>/dev/null)),)
export GIT_BRANCH := $(shell git symbolic-ref --short HEAD)
From 9236d1f467c6c2e8944b98982ad250b3e5eeaad4 Mon Sep 17 00:00:00 2001
From: impeeza <41979604+impeeza@users.noreply.github.com>
Date: Sun, 4 May 2025 15:04:26 -0500
Subject: [PATCH 23/45] Add changes propposed by HeikesFootSlave
Add changes propposed by HeikesFootSlave but reverts messages to English. hoppely some day we will add multi language support.
This add a new setting to Clean Config File.
---
Makefile | 2 +-
README.md | 3 +-
common/minIni/minGlue.c | 29 ++++++
common/minIni/minGlue.h | 1 +
common/minIni/minIni.c | 16 ++-
common/minIni/minIni.h | 29 +++---
overlay/src/main.cpp | 2 +
sysmod/src/main.cpp | 209 ++++++++++++++++++++++++++++++++++++++--
8 files changed, 267 insertions(+), 24 deletions(-)
diff --git a/Makefile b/Makefile
index 46276e5..40c7fc0 100644
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@ MAKEFILES := sysmod overlay
TARGETS := $(foreach dir,$(MAKEFILES),$(CURDIR)/$(dir))
# the below was taken from atmosphere + switch-examples makefile
-export VERSION := 1.5.5
+export VERSION := 1.5.6
ifneq ($(strip $(shell git symbolic-ref --short HEAD 2>/dev/null)),)
export GIT_BRANCH := $(shell git symbolic-ref --short HEAD)
diff --git a/README.md b/README.md
index f1940d8..82f05f7 100644
--- a/README.md
+++ b/README.md
@@ -16,6 +16,7 @@ patch_sysmmc=1 ; 1=(default) patch sysmmc, 0=don't patch sysmmc
patch_emummc=1 ; 1=(default) patch emummc, 0=don't patch emummc
enable_logging=1 ; 1=(default) output /config/sys-patch/log.ini 0=no log
version_skip=1 ; 1=(default) skips out of date patterns, 0=search all patterns
+clean_config=1 ; 1=(default) clean the config file 0=don't clean the config file
```
---
@@ -43,7 +44,7 @@ The overlay can be used to change the config options and to see what patches are
- Install [devkitpro](https://devkitpro.org/wiki/Getting_Started)
- Run the following:
```sh
- git clone --recurse-submodules https://github.com/ITotalJustice/sys-patch.git
+ git clone --recurse-submodules https://github.com/impeeza/sys-patch.git
cd ./sys-patch
make
```
diff --git a/common/minIni/minGlue.c b/common/minIni/minGlue.c
index 631ca1e..4ddd798 100644
--- a/common/minIni/minGlue.c
+++ b/common/minIni/minGlue.c
@@ -75,6 +75,35 @@ bool ini_read(char* buffer, u64 size, struct NxFile* nxfile) {
return true;
}
+bool ini_read2(char* buffer, u64 size, struct NxFile* nxfile) {
+ u64 bytes_read = 0;
+
+ if (R_FAILED(fsFileRead(&nxfile->file, nxfile->offset, buffer, size - 1, FsReadOption_None, &bytes_read))) {
+ return false;
+ }
+
+ if (bytes_read == 0) {
+ return false;
+ }
+
+ buffer[bytes_read] = '\0';
+
+ char* eol = strchr(buffer, '\n');
+ if (!eol) {
+ eol = strchr(buffer, '\r');
+ }
+
+ if (eol) {
+ *eol = '\0';
+ nxfile->offset += (eol - buffer + 1);
+ } else {
+ nxfile->offset += bytes_read;
+ return true;
+ }
+
+ return true;
+}
+
bool ini_write(const char* buffer, struct NxFile* nxfile) {
const size_t size = strlen(buffer);
if (R_FAILED(fsFileWrite(&nxfile->file, nxfile->offset, buffer, size, FsWriteOption_None))) {
diff --git a/common/minIni/minGlue.h b/common/minIni/minGlue.h
index 261f13d..1a40bec 100644
--- a/common/minIni/minGlue.h
+++ b/common/minIni/minGlue.h
@@ -22,6 +22,7 @@ bool ini_openwrite(const char* filename, struct NxFile* nxfile);
bool ini_openrewrite(const char* filename, struct NxFile* nxfile);
bool ini_close(struct NxFile* nxfile);
bool ini_read(char* buffer, u64 size, struct NxFile* nxfile);
+bool ini_read2(char* buffer, u64 size, struct NxFile* nxfile);
bool ini_write(const char* buffer, struct NxFile* nxfile);
bool ini_tell(struct NxFile* nxfile, s64* pos);
bool ini_seek(struct NxFile* nxfile, s64* pos);
diff --git a/common/minIni/minIni.c b/common/minIni/minIni.c
index 90ee57b..96dd764 100644
--- a/common/minIni/minIni.c
+++ b/common/minIni/minIni.c
@@ -3,7 +3,7 @@
* These routines are in part based on the article "Multiplatform .INI Files"
* by Joseph J. Graf in the March 1994 issue of Dr. Dobb's Journal.
*
- * Copyright (c) CompuPhase, 2008-2021
+ * Copyright (c) CompuPhase, 2008-2024
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
@@ -949,4 +949,18 @@ int ini_putf(const TCHAR *Section, const TCHAR *Key, INI_REAL Value, const TCHAR
return ini_puts(Section, Key, LocalBuffer, Filename);
}
#endif /* INI_REAL */
+
+/** ini_putbool()
+ * \param Section the name of the section to write the value in
+ * \param Key the name of the entry to write
+ * \param Value the value to write; it should be 0 or 1.
+ * \param Filename the name and full path of the .ini file to write to
+ *
+ * \return 1 if successful, otherwise 0
+ */
+int ini_putbool(const TCHAR *Section, const TCHAR *Key, int Value, const TCHAR *Filename)
+{
+ return ini_puts(Section, Key, Value ? __T("true") : __T("false"), Filename);
+}
+
#endif /* !INI_READONLY */
diff --git a/common/minIni/minIni.h b/common/minIni/minIni.h
index b63451c..9a68c87 100644
--- a/common/minIni/minIni.h
+++ b/common/minIni/minIni.h
@@ -1,6 +1,6 @@
/* minIni - Multi-Platform INI file parser, suitable for embedded systems
*
- * Copyright (c) CompuPhase, 2008-2021
+ * Copyright (c) CompuPhase, 2008-2024
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
@@ -37,24 +37,25 @@
extern "C" {
#endif
-int ini_getbool(const mTCHAR *Section, const mTCHAR *Key, int DefValue, const mTCHAR *Filename);
-long ini_getl(const mTCHAR *Section, const mTCHAR *Key, long DefValue, const mTCHAR *Filename);
-int ini_gets(const mTCHAR *Section, const mTCHAR *Key, const mTCHAR *DefValue, mTCHAR *Buffer, int BufferSize, const mTCHAR *Filename);
-int ini_getsection(int idx, mTCHAR *Buffer, int BufferSize, const mTCHAR *Filename);
-int ini_getkey(const mTCHAR *Section, int idx, mTCHAR *Buffer, int BufferSize, const mTCHAR *Filename);
+int ini_getbool(const mTCHAR *Section, const mTCHAR *Key, int DefValue, const mTCHAR *Filename);
+long ini_getl(const mTCHAR *Section, const mTCHAR *Key, long DefValue, const mTCHAR *Filename);
+int ini_gets(const mTCHAR *Section, const mTCHAR *Key, const mTCHAR *DefValue, mTCHAR *Buffer, int BufferSize, const mTCHAR *Filename);
+int ini_getsection(int idx, mTCHAR *Buffer, int BufferSize, const mTCHAR *Filename);
+int ini_getkey(const mTCHAR *Section, int idx, mTCHAR *Buffer, int BufferSize, const mTCHAR *Filename);
-int ini_hassection(const mTCHAR *Section, const mTCHAR *Filename);
-int ini_haskey(const mTCHAR *Section, const mTCHAR *Key, const mTCHAR *Filename);
+int ini_hassection(const mTCHAR *Section, const mTCHAR *Filename);
+int ini_haskey(const mTCHAR *Section, const mTCHAR *Key, const mTCHAR *Filename);
#if defined INI_REAL
INI_REAL ini_getf(const mTCHAR *Section, const mTCHAR *Key, INI_REAL DefValue, const mTCHAR *Filename);
#endif
#if !defined INI_READONLY
-int ini_putl(const mTCHAR *Section, const mTCHAR *Key, long Value, const mTCHAR *Filename);
-int ini_puts(const mTCHAR *Section, const mTCHAR *Key, const mTCHAR *Value, const mTCHAR *Filename);
+int ini_putbool(const mTCHAR *Section, const mTCHAR *Key, int Value, const mTCHAR *Filename);
+int ini_putl(const mTCHAR *Section, const mTCHAR *Key, long Value, const mTCHAR *Filename);
+int ini_puts(const mTCHAR *Section, const mTCHAR *Key, const mTCHAR *Value, const mTCHAR *Filename);
#if defined INI_REAL
-int ini_putf(const mTCHAR *Section, const mTCHAR *Key, INI_REAL Value, const mTCHAR *Filename);
+int ini_putf(const mTCHAR *Section, const mTCHAR *Key, INI_REAL Value, const mTCHAR *Filename);
#endif
#endif /* INI_READONLY */
@@ -124,15 +125,15 @@ int ini_browse(INI_CALLBACK Callback, void *UserData, const mTCHAR *Filename);
#endif
#if ! defined INI_READONLY
+ bool put(const std::string& Section, const std::string& Key, bool Value)
+ { return ini_putbool(Section.c_str(), Key.c_str(), (int)Value, iniFilename.c_str()) != 0; }
+
bool put(const std::string& Section, const std::string& Key, long Value)
{ return ini_putl(Section.c_str(), Key.c_str(), Value, iniFilename.c_str()) != 0; }
bool put(const std::string& Section, const std::string& Key, int Value)
{ return ini_putl(Section.c_str(), Key.c_str(), (long)Value, iniFilename.c_str()) != 0; }
- bool put(const std::string& Section, const std::string& Key, bool Value)
- { return ini_putl(Section.c_str(), Key.c_str(), (long)Value, iniFilename.c_str()) != 0; }
-
bool put(const std::string& Section, const std::string& Key, const std::string& Value)
{ return ini_puts(Section.c_str(), Key.c_str(), Value.c_str(), iniFilename.c_str()) != 0; }
diff --git a/overlay/src/main.cpp b/overlay/src/main.cpp
index 2afb6f3..d2fecf4 100644
--- a/overlay/src/main.cpp
+++ b/overlay/src/main.cpp
@@ -79,6 +79,7 @@ class GuiOptions final : public tsl::Gui {
list->addItem(config_patch_emummc.create_list_item("Patch emuMMC"));
list->addItem(config_logging.create_list_item("Logging"));
list->addItem(config_version_skip.create_list_item("Version skip"));
+ list->addItem(config_clean_config.create_list_item("Clean configuration"));
frame->setContent(list);
return frame;
@@ -88,6 +89,7 @@ class GuiOptions final : public tsl::Gui {
ConfigEntry config_patch_emummc{"options", "patch_emummc", true};
ConfigEntry config_logging{"options", "enable_logging", true};
ConfigEntry config_version_skip{"options", "version_skip", true};
+ ConfigEntry config_clean_config{"options", "clean_config", true};
};
class GuiToggle final : public tsl::Gui {
diff --git a/sysmod/src/main.cpp b/sysmod/src/main.cpp
index 005b2fd..6f00fd2 100644
--- a/sysmod/src/main.cpp
+++ b/sysmod/src/main.cpp
@@ -18,7 +18,15 @@ u32 AMS_VERSION{}; // set on startup
u32 AMS_TARGET_VERSION{}; // set on startup
u8 AMS_KEYGEN{}; // set on startup
u64 AMS_HASH{}; // set on startup
+bool patch_sysmmc; // set on startup
+bool patch_emummc; // set on startup
+bool enable_logging; // set on startup
bool VERSION_SKIP{}; // set on startup
+bool CLEAN_CONFIG{}; // set on startup
+
+constexpr auto ini_path = "/config/sys-patch/config.ini";
+constexpr auto log_path = "/config/sys-patch/log.ini";
+constexpr auto temp_path = "/config/sys-patch/temp.ini";
struct DebugEventInfo {
u32 event_type;
@@ -597,21 +605,208 @@ void keygen_to_str(char* s, u8 keygen) {
num_2_str(s, keygen);
}
+char* strdup(const char* str) {
+ size_t len = strlen(str) + 1;
+ char* copy = (char*)malloc(len);
+ if (copy != NULL) {
+strncpy(copy, str, len);
+ }
+ return copy;
+}
+
+void trim(char* str) {
+ if (str == NULL)
+ return;
+
+ char* start = str;
+ while (*start && isspace((unsigned char)*start))
+ ++start;
+
+ size_t len = strlen(start);
+ char* end = start + len - 1;
+ while (end > start && isspace((unsigned char)*end))
+ --end;
+
+ *(end + 1) = '\0';
+
+ if (start != str)
+ memmove(str, start, len - (start - str) + 1);
+}
+
+int clean_config_file() {
+ ini_remove(temp_path);
+ NxFile file;
+ bool rc=ini_openread(ini_path, &file);
+ char line[128];
+ char *line_trim = {};
+ char *actual_section = {};
+if (!rc) {
+ return 1;
+ }
+ bool need_rewrite = false;
+ bool keep_section = false;
+ bool keep_config = false;
+ size_t buffer_length=sizeof(line);
+ size_t line_trim_alloc = buffer_length + 1;
+ bool first_line_init = false;
+ int count_buff_line_passed = 0;
+ int z = 0;
+ while (ini_read2(line, buffer_length, &file)) {
+ if (!first_line_init) {
+ line_trim = (char*) calloc(1, line_trim_alloc);
+ if (!line_trim) {
+ ini_close(&file);
+ return -1;
+ }
+ first_line_init = true;
+ }
+ strcat(line_trim, line);
+ if ((line_trim[strlen(line_trim) - 1] != '\r' && line_trim[strlen(line_trim) - 1] != '\n') && strlen(line_trim) > 0) {
+ z++;
+ if (z > count_buff_line_passed) {
+ line_trim_alloc += buffer_length;
+ line_trim = (char*) realloc(line_trim, line_trim_alloc);
+ if (!line_trim) {
+ if (actual_section) free(actual_section);
+ if (line_trim) free(line_trim);
+ ini_close(&file);
+ return -1;
+ }
+ count_buff_line_passed++;
+ }
+ continue;
+ }
+ z = 0;
+ trim(line_trim);
+ if (line_trim[0] == '\0' || line_trim[0] == ';' || line_trim[0] == '\n' || line_trim[0] == '\r') {
+ memset(line_trim, '\0', line_trim_alloc);
+ continue;
+ }
+ if (line_trim[0] == '[' && line_trim[strlen(line_trim) - 1] == ']') {
+ keep_section = false;
+ line_trim[strlen(line_trim) - 1] = '\0';
+ if (actual_section) {
+ free(actual_section);
+ }
+ actual_section = strdup(line_trim + 1);
+ if (strcmp(actual_section, "options") == 0) {
+ keep_section = true;
+ memset(line_trim, '\0', line_trim_alloc);
+ continue;
+ }
+ for (auto& patch : patches) {
+ if (strcmp(patch.name, actual_section) == 0) {
+ keep_section = true;
+ break;
+ }
+ }
+ if (!keep_section) {
+ need_rewrite = true;
+ break;
+ }
+ } else {
+ keep_config = false;
+ if (!keep_section) {
+ need_rewrite = true;
+ break;
+ }
+ char *pos = strchr(line_trim, '=');
+ if (pos != NULL) {
+ *pos = '\0';
+ trim(line_trim);
+ if ((strcmp(actual_section, "options") == 0) && (strcmp(line_trim, "patch_sysmmc") == 0 || strcmp(line_trim, "patch_emummc") == 0 || strcmp(line_trim, "enable_logging") == 0 || strcmp(line_trim, "version_skip") == 0 || strcmp(line_trim, "clean_config") == 0)) {
+ memset(line_trim, '\0', line_trim_alloc);
+ continue;
+ }
+ for (auto& patch : patches) {
+ for (auto& p : patch.patterns) {
+ if (strcmp(p.patch_name, line_trim) == 0) {
+ keep_config = true;
+ break;
+ }
+ }
+ if (keep_config) {
+ break;
+ }
+ }
+ if (!keep_config) {
+ need_rewrite = true;
+ break;
+ }
+ }
+ }
+ memset(line_trim, '\0', line_trim_alloc);
+ }
+ ini_close(&file);
+ if (line_trim) {
+ free(line_trim);
+ }
+ if (actual_section) {
+ free(actual_section);
+ }
+
+ if (!need_rewrite) {
+ return 0;
+ }
+
+ bool user_val = ini_getbool("options", "patch_sysmmc", 1, ini_path);
+ if (ini_putl("options", "patch_sysmmc", user_val, temp_path) == 0) {
+ return -1;
+ }
+ user_val = ini_getbool("options", "patch_emummc", 1, ini_path);
+ if (ini_putl("options", "patch_emummc", user_val, temp_path) == 0) {
+ return -1;
+ }
+ user_val = ini_getbool("options", "enable_logging", 1, ini_path);
+ if (ini_putl("options", "enable_logging", user_val, temp_path) == 0) {
+ return -1;
+ }
+ user_val = ini_getbool("options", "version_skip", 1, ini_path);
+ if (ini_putl("options", "version_skip", user_val, temp_path) == 0) {
+ return -1;
+ }
+ user_val = ini_getbool("options", "clean_config", 1, ini_path);
+ if (ini_putl("options", "clean_config", user_val, temp_path) == 0) {
+ return -1;
+ }
+
+ for (auto& patch : patches) {
+ for (auto& p : patch.patterns) {
+ user_val = ini_getbool(patch.name, p.patch_name, p.enabled, ini_path);
+ if (ini_putl(patch.name, p.patch_name, user_val, temp_path) == 0) {
+ return -1;
+ }
+ }
+ }
+ ini_remove(ini_path);
+ini_rename(temp_path, ini_path);
+ return 1;
+}
+
} // namespace
int main(int argc, char* argv[]) {
- constexpr auto ini_path = "/config/sys-patch/config.ini";
- constexpr auto log_path = "/config/sys-patch/log.ini";
-
create_dir("/config/");
create_dir("/config/sys-patch/");
ini_remove(log_path);
// load options
- const auto patch_sysmmc = ini_load_or_write_default("options", "patch_sysmmc", 1, ini_path);
- const auto patch_emummc = ini_load_or_write_default("options", "patch_emummc", 1, ini_path);
- const auto enable_logging = ini_load_or_write_default("options", "enable_logging", 1, ini_path);
+ patch_sysmmc = ini_load_or_write_default("options", "patch_sysmmc", 1, ini_path);
+ patch_emummc = ini_load_or_write_default("options", "patch_emummc", 1, ini_path);
+ enable_logging = ini_load_or_write_default("options", "enable_logging", 1, ini_path);
VERSION_SKIP = ini_load_or_write_default("options", "version_skip", 1, ini_path);
+ CLEAN_CONFIG = ini_load_or_write_default("options", "clean_config", 1, ini_path);
+
+ if (CLEAN_CONFIG) {
+ int rc = clean_config_file();
+ if (rc == 0) {
+ ini_puts("clean_config_file", "result", "Nicht noetig", log_path);
+ } else if (rc == 1) {
+ ini_puts("clean_config_file", "result", "Bereinigt", log_path);
+ } else {
+ ini_puts("clean_config_file", "result", "Fehler beim bereinigen", log_path);
+ }
+ }
// load patch toggles
for (auto& patch : patches) {
@@ -681,7 +876,7 @@ int main(int argc, char* argv[]) {
// defined in the Makefile
#define DATE (DATE_DAY "." DATE_MONTH "." DATE_YEAR " " DATE_HOUR ":" DATE_MIN ":" DATE_SEC)
- ini_puts("stats", "version", VERSION_WITH_HASH, log_path);
+ ini_puts("stats", "Version", VERSION_WITH_HASH, log_path);
ini_puts("stats", "build_date", DATE, log_path);
ini_puts("stats", "fw_version", fw_version, log_path);
ini_puts("stats", "ams_version", ams_version, log_path);
From 71895fde1ead4d437595d24579292a3731026295 Mon Sep 17 00:00:00 2001
From: impeeza <41979604+impeeza@users.noreply.github.com>
Date: Sun, 4 May 2025 17:28:13 -0500
Subject: [PATCH 24/45] Revert "Add changes propposed by HeikesFootSlave"
---
Makefile | 2 +-
README.md | 3 +-
common/minIni/minGlue.c | 29 ------
common/minIni/minGlue.h | 1 -
common/minIni/minIni.c | 16 +--
common/minIni/minIni.h | 29 +++---
overlay/src/main.cpp | 2 -
sysmod/src/main.cpp | 209 ++--------------------------------------
8 files changed, 24 insertions(+), 267 deletions(-)
diff --git a/Makefile b/Makefile
index 40c7fc0..46276e5 100644
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@ MAKEFILES := sysmod overlay
TARGETS := $(foreach dir,$(MAKEFILES),$(CURDIR)/$(dir))
# the below was taken from atmosphere + switch-examples makefile
-export VERSION := 1.5.6
+export VERSION := 1.5.5
ifneq ($(strip $(shell git symbolic-ref --short HEAD 2>/dev/null)),)
export GIT_BRANCH := $(shell git symbolic-ref --short HEAD)
diff --git a/README.md b/README.md
index 82f05f7..f1940d8 100644
--- a/README.md
+++ b/README.md
@@ -16,7 +16,6 @@ patch_sysmmc=1 ; 1=(default) patch sysmmc, 0=don't patch sysmmc
patch_emummc=1 ; 1=(default) patch emummc, 0=don't patch emummc
enable_logging=1 ; 1=(default) output /config/sys-patch/log.ini 0=no log
version_skip=1 ; 1=(default) skips out of date patterns, 0=search all patterns
-clean_config=1 ; 1=(default) clean the config file 0=don't clean the config file
```
---
@@ -44,7 +43,7 @@ The overlay can be used to change the config options and to see what patches are
- Install [devkitpro](https://devkitpro.org/wiki/Getting_Started)
- Run the following:
```sh
- git clone --recurse-submodules https://github.com/impeeza/sys-patch.git
+ git clone --recurse-submodules https://github.com/ITotalJustice/sys-patch.git
cd ./sys-patch
make
```
diff --git a/common/minIni/minGlue.c b/common/minIni/minGlue.c
index 4ddd798..631ca1e 100644
--- a/common/minIni/minGlue.c
+++ b/common/minIni/minGlue.c
@@ -75,35 +75,6 @@ bool ini_read(char* buffer, u64 size, struct NxFile* nxfile) {
return true;
}
-bool ini_read2(char* buffer, u64 size, struct NxFile* nxfile) {
- u64 bytes_read = 0;
-
- if (R_FAILED(fsFileRead(&nxfile->file, nxfile->offset, buffer, size - 1, FsReadOption_None, &bytes_read))) {
- return false;
- }
-
- if (bytes_read == 0) {
- return false;
- }
-
- buffer[bytes_read] = '\0';
-
- char* eol = strchr(buffer, '\n');
- if (!eol) {
- eol = strchr(buffer, '\r');
- }
-
- if (eol) {
- *eol = '\0';
- nxfile->offset += (eol - buffer + 1);
- } else {
- nxfile->offset += bytes_read;
- return true;
- }
-
- return true;
-}
-
bool ini_write(const char* buffer, struct NxFile* nxfile) {
const size_t size = strlen(buffer);
if (R_FAILED(fsFileWrite(&nxfile->file, nxfile->offset, buffer, size, FsWriteOption_None))) {
diff --git a/common/minIni/minGlue.h b/common/minIni/minGlue.h
index 1a40bec..261f13d 100644
--- a/common/minIni/minGlue.h
+++ b/common/minIni/minGlue.h
@@ -22,7 +22,6 @@ bool ini_openwrite(const char* filename, struct NxFile* nxfile);
bool ini_openrewrite(const char* filename, struct NxFile* nxfile);
bool ini_close(struct NxFile* nxfile);
bool ini_read(char* buffer, u64 size, struct NxFile* nxfile);
-bool ini_read2(char* buffer, u64 size, struct NxFile* nxfile);
bool ini_write(const char* buffer, struct NxFile* nxfile);
bool ini_tell(struct NxFile* nxfile, s64* pos);
bool ini_seek(struct NxFile* nxfile, s64* pos);
diff --git a/common/minIni/minIni.c b/common/minIni/minIni.c
index 96dd764..90ee57b 100644
--- a/common/minIni/minIni.c
+++ b/common/minIni/minIni.c
@@ -3,7 +3,7 @@
* These routines are in part based on the article "Multiplatform .INI Files"
* by Joseph J. Graf in the March 1994 issue of Dr. Dobb's Journal.
*
- * Copyright (c) CompuPhase, 2008-2024
+ * Copyright (c) CompuPhase, 2008-2021
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
@@ -949,18 +949,4 @@ int ini_putf(const TCHAR *Section, const TCHAR *Key, INI_REAL Value, const TCHAR
return ini_puts(Section, Key, LocalBuffer, Filename);
}
#endif /* INI_REAL */
-
-/** ini_putbool()
- * \param Section the name of the section to write the value in
- * \param Key the name of the entry to write
- * \param Value the value to write; it should be 0 or 1.
- * \param Filename the name and full path of the .ini file to write to
- *
- * \return 1 if successful, otherwise 0
- */
-int ini_putbool(const TCHAR *Section, const TCHAR *Key, int Value, const TCHAR *Filename)
-{
- return ini_puts(Section, Key, Value ? __T("true") : __T("false"), Filename);
-}
-
#endif /* !INI_READONLY */
diff --git a/common/minIni/minIni.h b/common/minIni/minIni.h
index 9a68c87..b63451c 100644
--- a/common/minIni/minIni.h
+++ b/common/minIni/minIni.h
@@ -1,6 +1,6 @@
/* minIni - Multi-Platform INI file parser, suitable for embedded systems
*
- * Copyright (c) CompuPhase, 2008-2024
+ * Copyright (c) CompuPhase, 2008-2021
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy
@@ -37,25 +37,24 @@
extern "C" {
#endif
-int ini_getbool(const mTCHAR *Section, const mTCHAR *Key, int DefValue, const mTCHAR *Filename);
-long ini_getl(const mTCHAR *Section, const mTCHAR *Key, long DefValue, const mTCHAR *Filename);
-int ini_gets(const mTCHAR *Section, const mTCHAR *Key, const mTCHAR *DefValue, mTCHAR *Buffer, int BufferSize, const mTCHAR *Filename);
-int ini_getsection(int idx, mTCHAR *Buffer, int BufferSize, const mTCHAR *Filename);
-int ini_getkey(const mTCHAR *Section, int idx, mTCHAR *Buffer, int BufferSize, const mTCHAR *Filename);
+int ini_getbool(const mTCHAR *Section, const mTCHAR *Key, int DefValue, const mTCHAR *Filename);
+long ini_getl(const mTCHAR *Section, const mTCHAR *Key, long DefValue, const mTCHAR *Filename);
+int ini_gets(const mTCHAR *Section, const mTCHAR *Key, const mTCHAR *DefValue, mTCHAR *Buffer, int BufferSize, const mTCHAR *Filename);
+int ini_getsection(int idx, mTCHAR *Buffer, int BufferSize, const mTCHAR *Filename);
+int ini_getkey(const mTCHAR *Section, int idx, mTCHAR *Buffer, int BufferSize, const mTCHAR *Filename);
-int ini_hassection(const mTCHAR *Section, const mTCHAR *Filename);
-int ini_haskey(const mTCHAR *Section, const mTCHAR *Key, const mTCHAR *Filename);
+int ini_hassection(const mTCHAR *Section, const mTCHAR *Filename);
+int ini_haskey(const mTCHAR *Section, const mTCHAR *Key, const mTCHAR *Filename);
#if defined INI_REAL
INI_REAL ini_getf(const mTCHAR *Section, const mTCHAR *Key, INI_REAL DefValue, const mTCHAR *Filename);
#endif
#if !defined INI_READONLY
-int ini_putbool(const mTCHAR *Section, const mTCHAR *Key, int Value, const mTCHAR *Filename);
-int ini_putl(const mTCHAR *Section, const mTCHAR *Key, long Value, const mTCHAR *Filename);
-int ini_puts(const mTCHAR *Section, const mTCHAR *Key, const mTCHAR *Value, const mTCHAR *Filename);
+int ini_putl(const mTCHAR *Section, const mTCHAR *Key, long Value, const mTCHAR *Filename);
+int ini_puts(const mTCHAR *Section, const mTCHAR *Key, const mTCHAR *Value, const mTCHAR *Filename);
#if defined INI_REAL
-int ini_putf(const mTCHAR *Section, const mTCHAR *Key, INI_REAL Value, const mTCHAR *Filename);
+int ini_putf(const mTCHAR *Section, const mTCHAR *Key, INI_REAL Value, const mTCHAR *Filename);
#endif
#endif /* INI_READONLY */
@@ -125,15 +124,15 @@ int ini_browse(INI_CALLBACK Callback, void *UserData, const mTCHAR *Filename);
#endif
#if ! defined INI_READONLY
- bool put(const std::string& Section, const std::string& Key, bool Value)
- { return ini_putbool(Section.c_str(), Key.c_str(), (int)Value, iniFilename.c_str()) != 0; }
-
bool put(const std::string& Section, const std::string& Key, long Value)
{ return ini_putl(Section.c_str(), Key.c_str(), Value, iniFilename.c_str()) != 0; }
bool put(const std::string& Section, const std::string& Key, int Value)
{ return ini_putl(Section.c_str(), Key.c_str(), (long)Value, iniFilename.c_str()) != 0; }
+ bool put(const std::string& Section, const std::string& Key, bool Value)
+ { return ini_putl(Section.c_str(), Key.c_str(), (long)Value, iniFilename.c_str()) != 0; }
+
bool put(const std::string& Section, const std::string& Key, const std::string& Value)
{ return ini_puts(Section.c_str(), Key.c_str(), Value.c_str(), iniFilename.c_str()) != 0; }
diff --git a/overlay/src/main.cpp b/overlay/src/main.cpp
index d2fecf4..2afb6f3 100644
--- a/overlay/src/main.cpp
+++ b/overlay/src/main.cpp
@@ -79,7 +79,6 @@ class GuiOptions final : public tsl::Gui {
list->addItem(config_patch_emummc.create_list_item("Patch emuMMC"));
list->addItem(config_logging.create_list_item("Logging"));
list->addItem(config_version_skip.create_list_item("Version skip"));
- list->addItem(config_clean_config.create_list_item("Clean configuration"));
frame->setContent(list);
return frame;
@@ -89,7 +88,6 @@ class GuiOptions final : public tsl::Gui {
ConfigEntry config_patch_emummc{"options", "patch_emummc", true};
ConfigEntry config_logging{"options", "enable_logging", true};
ConfigEntry config_version_skip{"options", "version_skip", true};
- ConfigEntry config_clean_config{"options", "clean_config", true};
};
class GuiToggle final : public tsl::Gui {
diff --git a/sysmod/src/main.cpp b/sysmod/src/main.cpp
index 6f00fd2..005b2fd 100644
--- a/sysmod/src/main.cpp
+++ b/sysmod/src/main.cpp
@@ -18,15 +18,7 @@ u32 AMS_VERSION{}; // set on startup
u32 AMS_TARGET_VERSION{}; // set on startup
u8 AMS_KEYGEN{}; // set on startup
u64 AMS_HASH{}; // set on startup
-bool patch_sysmmc; // set on startup
-bool patch_emummc; // set on startup
-bool enable_logging; // set on startup
bool VERSION_SKIP{}; // set on startup
-bool CLEAN_CONFIG{}; // set on startup
-
-constexpr auto ini_path = "/config/sys-patch/config.ini";
-constexpr auto log_path = "/config/sys-patch/log.ini";
-constexpr auto temp_path = "/config/sys-patch/temp.ini";
struct DebugEventInfo {
u32 event_type;
@@ -605,208 +597,21 @@ void keygen_to_str(char* s, u8 keygen) {
num_2_str(s, keygen);
}
-char* strdup(const char* str) {
- size_t len = strlen(str) + 1;
- char* copy = (char*)malloc(len);
- if (copy != NULL) {
-strncpy(copy, str, len);
- }
- return copy;
-}
-
-void trim(char* str) {
- if (str == NULL)
- return;
-
- char* start = str;
- while (*start && isspace((unsigned char)*start))
- ++start;
-
- size_t len = strlen(start);
- char* end = start + len - 1;
- while (end > start && isspace((unsigned char)*end))
- --end;
-
- *(end + 1) = '\0';
-
- if (start != str)
- memmove(str, start, len - (start - str) + 1);
-}
-
-int clean_config_file() {
- ini_remove(temp_path);
- NxFile file;
- bool rc=ini_openread(ini_path, &file);
- char line[128];
- char *line_trim = {};
- char *actual_section = {};
-if (!rc) {
- return 1;
- }
- bool need_rewrite = false;
- bool keep_section = false;
- bool keep_config = false;
- size_t buffer_length=sizeof(line);
- size_t line_trim_alloc = buffer_length + 1;
- bool first_line_init = false;
- int count_buff_line_passed = 0;
- int z = 0;
- while (ini_read2(line, buffer_length, &file)) {
- if (!first_line_init) {
- line_trim = (char*) calloc(1, line_trim_alloc);
- if (!line_trim) {
- ini_close(&file);
- return -1;
- }
- first_line_init = true;
- }
- strcat(line_trim, line);
- if ((line_trim[strlen(line_trim) - 1] != '\r' && line_trim[strlen(line_trim) - 1] != '\n') && strlen(line_trim) > 0) {
- z++;
- if (z > count_buff_line_passed) {
- line_trim_alloc += buffer_length;
- line_trim = (char*) realloc(line_trim, line_trim_alloc);
- if (!line_trim) {
- if (actual_section) free(actual_section);
- if (line_trim) free(line_trim);
- ini_close(&file);
- return -1;
- }
- count_buff_line_passed++;
- }
- continue;
- }
- z = 0;
- trim(line_trim);
- if (line_trim[0] == '\0' || line_trim[0] == ';' || line_trim[0] == '\n' || line_trim[0] == '\r') {
- memset(line_trim, '\0', line_trim_alloc);
- continue;
- }
- if (line_trim[0] == '[' && line_trim[strlen(line_trim) - 1] == ']') {
- keep_section = false;
- line_trim[strlen(line_trim) - 1] = '\0';
- if (actual_section) {
- free(actual_section);
- }
- actual_section = strdup(line_trim + 1);
- if (strcmp(actual_section, "options") == 0) {
- keep_section = true;
- memset(line_trim, '\0', line_trim_alloc);
- continue;
- }
- for (auto& patch : patches) {
- if (strcmp(patch.name, actual_section) == 0) {
- keep_section = true;
- break;
- }
- }
- if (!keep_section) {
- need_rewrite = true;
- break;
- }
- } else {
- keep_config = false;
- if (!keep_section) {
- need_rewrite = true;
- break;
- }
- char *pos = strchr(line_trim, '=');
- if (pos != NULL) {
- *pos = '\0';
- trim(line_trim);
- if ((strcmp(actual_section, "options") == 0) && (strcmp(line_trim, "patch_sysmmc") == 0 || strcmp(line_trim, "patch_emummc") == 0 || strcmp(line_trim, "enable_logging") == 0 || strcmp(line_trim, "version_skip") == 0 || strcmp(line_trim, "clean_config") == 0)) {
- memset(line_trim, '\0', line_trim_alloc);
- continue;
- }
- for (auto& patch : patches) {
- for (auto& p : patch.patterns) {
- if (strcmp(p.patch_name, line_trim) == 0) {
- keep_config = true;
- break;
- }
- }
- if (keep_config) {
- break;
- }
- }
- if (!keep_config) {
- need_rewrite = true;
- break;
- }
- }
- }
- memset(line_trim, '\0', line_trim_alloc);
- }
- ini_close(&file);
- if (line_trim) {
- free(line_trim);
- }
- if (actual_section) {
- free(actual_section);
- }
-
- if (!need_rewrite) {
- return 0;
- }
-
- bool user_val = ini_getbool("options", "patch_sysmmc", 1, ini_path);
- if (ini_putl("options", "patch_sysmmc", user_val, temp_path) == 0) {
- return -1;
- }
- user_val = ini_getbool("options", "patch_emummc", 1, ini_path);
- if (ini_putl("options", "patch_emummc", user_val, temp_path) == 0) {
- return -1;
- }
- user_val = ini_getbool("options", "enable_logging", 1, ini_path);
- if (ini_putl("options", "enable_logging", user_val, temp_path) == 0) {
- return -1;
- }
- user_val = ini_getbool("options", "version_skip", 1, ini_path);
- if (ini_putl("options", "version_skip", user_val, temp_path) == 0) {
- return -1;
- }
- user_val = ini_getbool("options", "clean_config", 1, ini_path);
- if (ini_putl("options", "clean_config", user_val, temp_path) == 0) {
- return -1;
- }
-
- for (auto& patch : patches) {
- for (auto& p : patch.patterns) {
- user_val = ini_getbool(patch.name, p.patch_name, p.enabled, ini_path);
- if (ini_putl(patch.name, p.patch_name, user_val, temp_path) == 0) {
- return -1;
- }
- }
- }
- ini_remove(ini_path);
-ini_rename(temp_path, ini_path);
- return 1;
-}
-
} // namespace
int main(int argc, char* argv[]) {
+ constexpr auto ini_path = "/config/sys-patch/config.ini";
+ constexpr auto log_path = "/config/sys-patch/log.ini";
+
create_dir("/config/");
create_dir("/config/sys-patch/");
ini_remove(log_path);
// load options
- patch_sysmmc = ini_load_or_write_default("options", "patch_sysmmc", 1, ini_path);
- patch_emummc = ini_load_or_write_default("options", "patch_emummc", 1, ini_path);
- enable_logging = ini_load_or_write_default("options", "enable_logging", 1, ini_path);
+ const auto patch_sysmmc = ini_load_or_write_default("options", "patch_sysmmc", 1, ini_path);
+ const auto patch_emummc = ini_load_or_write_default("options", "patch_emummc", 1, ini_path);
+ const auto enable_logging = ini_load_or_write_default("options", "enable_logging", 1, ini_path);
VERSION_SKIP = ini_load_or_write_default("options", "version_skip", 1, ini_path);
- CLEAN_CONFIG = ini_load_or_write_default("options", "clean_config", 1, ini_path);
-
- if (CLEAN_CONFIG) {
- int rc = clean_config_file();
- if (rc == 0) {
- ini_puts("clean_config_file", "result", "Nicht noetig", log_path);
- } else if (rc == 1) {
- ini_puts("clean_config_file", "result", "Bereinigt", log_path);
- } else {
- ini_puts("clean_config_file", "result", "Fehler beim bereinigen", log_path);
- }
- }
// load patch toggles
for (auto& patch : patches) {
@@ -876,7 +681,7 @@ int main(int argc, char* argv[]) {
// defined in the Makefile
#define DATE (DATE_DAY "." DATE_MONTH "." DATE_YEAR " " DATE_HOUR ":" DATE_MIN ":" DATE_SEC)
- ini_puts("stats", "Version", VERSION_WITH_HASH, log_path);
+ ini_puts("stats", "version", VERSION_WITH_HASH, log_path);
ini_puts("stats", "build_date", DATE, log_path);
ini_puts("stats", "fw_version", fw_version, log_path);
ini_puts("stats", "ams_version", ams_version, log_path);
From d0f5451bd41a47bc1a1e22afe488db8bf96bd038 Mon Sep 17 00:00:00 2001
From: borntohonk <6264306+borntohonk@users.noreply.github.com>
Date: Sun, 4 May 2025 09:54:32 +0200
Subject: [PATCH 25/45] Fix nifm for 20.0.0+
---
Makefile | 2 +-
overlay/src/main.cpp | 2 ++
sysmod/src/main.cpp | 8 +++++++-
3 files changed, 10 insertions(+), 2 deletions(-)
diff --git a/Makefile b/Makefile
index 46276e5..40c7fc0 100644
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@ MAKEFILES := sysmod overlay
TARGETS := $(foreach dir,$(MAKEFILES),$(CURDIR)/$(dir))
# the below was taken from atmosphere + switch-examples makefile
-export VERSION := 1.5.5
+export VERSION := 1.5.6
ifneq ($(strip $(shell git symbolic-ref --short HEAD 2>/dev/null)),)
export GIT_BRANCH := $(shell git symbolic-ref --short HEAD)
diff --git a/overlay/src/main.cpp b/overlay/src/main.cpp
index 2afb6f3..91aa64a 100644
--- a/overlay/src/main.cpp
+++ b/overlay/src/main.cpp
@@ -116,6 +116,7 @@ class GuiToggle final : public tsl::Gui {
list->addItem(new tsl::elm::CategoryHeader("NIFM - 010000000000000F"));
list->addItem(config_ctest.create_list_item("ctest"));
+ list->addItem(config_ctest2.create_list_item("ctest2"));
list->addItem(new tsl::elm::CategoryHeader("NIM - 0100000000000025"));
list->addItem(config_nim.create_list_item("nim"));
@@ -140,6 +141,7 @@ class GuiToggle final : public tsl::Gui {
ConfigEntry config_es2{"es", "es2", true};
ConfigEntry config_es3{"es", "es3", true};
ConfigEntry config_ctest{"nifm", "ctest", true};
+ ConfigEntry config_ctest2{"nifm", "ctest2", true};
ConfigEntry config_nim{"nim", "nim", true};
ConfigEntry config_ssl1{"ssl", "disablecaverification1", false};
ConfigEntry config_ssl2{"ssl", "disablecaverification2", false};
diff --git a/sysmod/src/main.cpp b/sysmod/src/main.cpp
index 005b2fd..e50938f 100644
--- a/sysmod/src/main.cpp
+++ b/sysmod/src/main.cpp
@@ -200,6 +200,11 @@ constexpr auto ctest_cond(u32 inst) -> bool {
return std::byteswap(0xF50301AA) == inst; // mov x21, x1
}
+constexpr auto b_cond(u32 inst) -> bool {
+ const auto type = inst >> 24;
+ return type == 0x14 || type == 0x17;
+}
+
// to view patches, use https://armconverter.com/?lock=arm64
constexpr PatchData ret0_patch_data{ "0xE0031F2A" };
constexpr PatchData ret1_patch_data{ "0x10000014" };
@@ -292,7 +297,8 @@ constinit Patterns es_patterns[] = {
};
constinit Patterns nifm_patterns[] = {
- { "ctest", "....................F40300AA....F30314AAE00314AA9F0201397F8E04F8", 16, -16, ctest_cond, ctest_patch, ctest_applied, true, FW_VER_ANY },
+ { "ctest", "....................F40300AA....F30314AAE00314AA9F0201397F8E04F8", 16, -16, ctest_cond, ctest_patch, ctest_applied, true, FW_VER_ANY, MAKEHOSVERSION(18,1,0) }, // 1.0.0 - 18.1.0
+ { "ctest2", "14...........91...........97...............14", 37, 4, b_cond, ctest_patch, ctest_applied, true, MAKEHOSVERSION(19,0,0), FW_VER_ANY }, //19.0.0 - 20.0.1+
};
constinit Patterns nim_patterns[] = {
From 1b33fdd306307cabfc12dcd10c95a69c8ded1789 Mon Sep 17 00:00:00 2001
From: borntohonk <6264306+borntohonk@users.noreply.github.com>
Date: Sat, 26 Jul 2025 12:34:50 +0200
Subject: [PATCH 26/45] replace loader patch with different one
---
Makefile | 2 +-
sysmod/src/main.cpp | 31 ++++++++-----------------------
2 files changed, 9 insertions(+), 24 deletions(-)
diff --git a/Makefile b/Makefile
index 40c7fc0..82371ae 100644
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@ MAKEFILES := sysmod overlay
TARGETS := $(foreach dir,$(MAKEFILES),$(CURDIR)/$(dir))
# the below was taken from atmosphere + switch-examples makefile
-export VERSION := 1.5.6
+export VERSION := 1.5.7
ifneq ($(strip $(shell git symbolic-ref --short HEAD 2>/dev/null)),)
export GIT_BRANCH := $(shell git symbolic-ref --short HEAD)
diff --git a/sysmod/src/main.cpp b/sysmod/src/main.cpp
index e50938f..8db9399 100644
--- a/sysmod/src/main.cpp
+++ b/sysmod/src/main.cpp
@@ -126,18 +126,10 @@ struct PatchEntry {
const u32 max_fw_ver{FW_VER_ANY}; // set to FW_VER_ANY to ignore
};
-constexpr auto subi_cond(u32 inst) -> bool {
- // # Used on Atmosphère-NX 0.11.0 - 0.12.0.
- const auto type = (inst >> 24) & 0xFF;
- const auto imm = (inst >> 10) & 0xFFF;
- return (type == 0x71) && (imm == 0x0A);
-}
-constexpr auto subr_cond(u32 inst) -> bool {
- // # Used on Atmosphère-NX 0.13.0 and later.
- const auto type = (inst >> 21) & 0x7F9;
- const auto reg = (inst >> 16) & 0x1F;
- return (type == 0x358) && (reg == 0x01);
+constexpr auto cmp_cond(u32 inst) -> bool {
+ const auto type = inst >> 24;
+ return type == 0x6B; // cmp w0, w1
}
constexpr auto bl_cond(u32 inst) -> bool {
@@ -149,10 +141,6 @@ constexpr auto tbz_cond(u32 inst) -> bool {
return ((inst >> 24) & 0x7F) == 0x36;
}
-constexpr auto subs_cond(u32 inst) -> bool {
- return subi_cond(inst) || subr_cond(inst);
-}
-
constexpr auto cbz_cond(u32 inst) -> bool {
const auto type = inst >> 24;
return type == 0x34 || type == 0xB4;
@@ -213,6 +201,7 @@ constexpr PatchData nop_patch_data{ "0x1F2003D5" };
constexpr PatchData mov0_patch_data{ "0xE0031FAA" };
//mov x2, xzr
constexpr PatchData mov2_patch_data{ "0xE2031FAA" };
+constexpr PatchData cmp_patch_data{ "0x00" };
constexpr PatchData ssl1_patch_data{ "0x0A" };
constexpr PatchData ssl2_patch_data{ "0x08008052" };
constexpr PatchData ctest_patch_data{ "0x00309AD2001EA1F2610100D4E0031FAAC0035FD6" };
@@ -220,9 +209,9 @@ constexpr PatchData ctest_patch_data{ "0x00309AD2001EA1F2610100D4E0031FAAC0035FD
constexpr auto ret0_patch(u32 inst) -> PatchData { return ret0_patch_data; }
constexpr auto ret1_patch(u32 inst) -> PatchData { return ret1_patch_data; }
constexpr auto nop_patch(u32 inst) -> PatchData { return nop_patch_data; }
-constexpr auto subs_patch(u32 inst) -> PatchData { return subi_cond(inst) ? (u8)0x1 : (u8)0x0; }
constexpr auto mov0_patch(u32 inst) -> PatchData { return mov0_patch_data; }
constexpr auto mov2_patch(u32 inst) -> PatchData { return mov2_patch_data; }
+constexpr auto cmp_patch(u32 inst) -> PatchData { return cmp_patch_data; }
constexpr auto ssl1_patch(u32 inst) -> PatchData { return ssl1_patch_data; }
constexpr auto ssl2_patch(u32 inst) -> PatchData { return ssl2_patch_data; }
constexpr auto ctest_patch(u32 inst) -> PatchData { return ctest_patch_data; }
@@ -245,12 +234,8 @@ constexpr auto nop_applied(const u8* data, u32 inst) -> bool {
return nop_patch(inst).cmp(data);
}
-constexpr auto subs_applied(const u8* data, u32 inst) -> bool {
- const auto type_i = (inst >> 24) & 0xFF;
- const auto imm = (inst >> 10) & 0xFFF;
- const auto type_r = (inst >> 21) & 0x7F9;
- const auto reg = (inst >> 16) & 0x1F;
- return ((type_i == 0x71) && (imm == 0x1)) || ((type_r == 0x358) && (reg == 0x0));
+constexpr auto cmp_applied(const u8* data, u32 inst) -> bool {
+ return cmp_patch(inst).cmp(data);
}
constexpr auto b_applied(const u8* data, u32 inst) -> bool {
@@ -287,7 +272,7 @@ constinit Patterns fs_patterns[] = {
};
constinit Patterns ldr_patterns[] = {
- { "noacidsigchk", "0xFD7B.A8C0035FD6", 16, 2, subs_cond, subs_patch, subs_applied, true, FW_VER_ANY },
+ { "noacidsigchk", "17..009401C0BE121F00", 9, 2, cmp_cond, cmp_patch, cmp_applied, true, FW_VER_ANY }, // 1F00016B - cmp w0, w1 patched to 1F00006B - cmp w0, w0
};
constinit Patterns es_patterns[] = {
From 0de0f4abac478b662139fb6a191debfdd95dcab0 Mon Sep 17 00:00:00 2001
From: borntohonk <6264306+borntohonk@users.noreply.github.com>
Date: Tue, 11 Nov 2025 14:09:40 +0100
Subject: [PATCH 27/45] fix fs and nim for 21.0.0
---
overlay/src/main.cpp | 9 +++++++--
sysmod/src/main.cpp | 6 ++++--
2 files changed, 11 insertions(+), 4 deletions(-)
diff --git a/overlay/src/main.cpp b/overlay/src/main.cpp
index 91aa64a..762bd63 100644
--- a/overlay/src/main.cpp
+++ b/overlay/src/main.cpp
@@ -102,6 +102,7 @@ class GuiToggle final : public tsl::Gui {
list->addItem(config_noacidsigchk1.create_list_item("noacidsigchk1"));
list->addItem(config_noacidsigchk2.create_list_item("noacidsigchk2"));
list->addItem(config_noncasigchk_old.create_list_item("noncasigchk_old"));
+ list->addItem(config_noncasigchk_old2.create_list_item("noncasigchk_old2"));
list->addItem(config_noncasigchk_new.create_list_item("noncasigchk_new"));
list->addItem(config_nocntchk.create_list_item("nocntchk"));
list->addItem(config_nocntchk2.create_list_item("nocntchk2"));
@@ -119,7 +120,9 @@ class GuiToggle final : public tsl::Gui {
list->addItem(config_ctest2.create_list_item("ctest2"));
list->addItem(new tsl::elm::CategoryHeader("NIM - 0100000000000025"));
- list->addItem(config_nim.create_list_item("nim"));
+ list->addItem(config_nim.create_list_item("nim_old"));
+ list->addItem(config_nim.create_list_item("nim_new"));
+
list->addItem(new tsl::elm::CategoryHeader("Disable CA Verification - apply all"));
list->addItem(config_ssl1.create_list_item("disablecaverification1"));
@@ -133,6 +136,7 @@ class GuiToggle final : public tsl::Gui {
ConfigEntry config_noacidsigchk1{"fs", "noacidsigchk1", true};
ConfigEntry config_noacidsigchk2{"fs", "noacidsigchk2", true};
ConfigEntry config_noncasigchk_old{"fs", "noncasigchk_old", true};
+ ConfigEntry config_noncasigchk_old2{"fs", "noncasigchk_old2", true};
ConfigEntry config_noncasigchk_new{"fs", "noncasigchk_new", true};
ConfigEntry config_nocntchk{"fs", "nocntchk", true};
ConfigEntry config_nocntchk2{"fs", "nocntchk2", true};
@@ -142,7 +146,8 @@ class GuiToggle final : public tsl::Gui {
ConfigEntry config_es3{"es", "es3", true};
ConfigEntry config_ctest{"nifm", "ctest", true};
ConfigEntry config_ctest2{"nifm", "ctest2", true};
- ConfigEntry config_nim{"nim", "nim", true};
+ ConfigEntry config_nim{"nim_old", "nim_old", true};
+ ConfigEntry config_nim{"nim_new", "nim_new", true};
ConfigEntry config_ssl1{"ssl", "disablecaverification1", false};
ConfigEntry config_ssl2{"ssl", "disablecaverification2", false};
ConfigEntry config_ssl3{"ssl", "disablecaverification3", false};
diff --git a/sysmod/src/main.cpp b/sysmod/src/main.cpp
index 8db9399..7134a68 100644
--- a/sysmod/src/main.cpp
+++ b/sysmod/src/main.cpp
@@ -266,7 +266,8 @@ constinit Patterns fs_patterns[] = {
{ "noacidsigchk1", "0xC8FE4739", -24, 0, bl_cond, ret0_patch, ret0_applied, true, FW_VER_ANY, MAKEHOSVERSION(9,2,0) },
{ "noacidsigchk2", "0x0210911F000072", -5, 0, bl_cond, ret0_patch, ret0_applied, true, FW_VER_ANY, MAKEHOSVERSION(9,2,0) },
{ "noncasigchk_old", "0x0036.......71..0054..4839", -2, 0, tbz_cond, nop_patch, nop_applied, true, MAKEHOSVERSION(10,0,0), MAKEHOSVERSION(16,1,0) },
- { "noncasigchk_new", "0x.94..0036.258052", 2, 0, tbz_cond, nop_patch, nop_applied, true, MAKEHOSVERSION(17,0,0), FW_VER_ANY }, // 17.0.0 - 19.0.0+
+ { "noncasigchk_old2", "0x.94..0036.258052", 2, 0, tbz_cond, nop_patch, nop_applied, true, MAKEHOSVERSION(17,0,0), MAKEHOSVERSION(20,5,0) }, // 17.0.0 - 20.5.0
+ { "noncasigchk_new", "0x.94..0036.........258052", 2, 0, tbz_cond, nop_patch, nop_applied, true, MAKEHOSVERSION(21,0,0), FW_VER_ANY }, // 21.0.0+
{ "nocntchk", "0x40f9...9408.0012.050071", 2, 0, bl_cond, ret0_patch, ret0_applied, true, MAKEHOSVERSION(10,0,0), MAKEHOSVERSION(18,1,0) },
{ "nocntchk2", "0x40f9...94..40b9..0012", 2, 0, bl_cond, ret0_patch, ret0_applied, true, MAKEHOSVERSION(19,0,0), FW_VER_ANY },
};
@@ -287,7 +288,8 @@ constinit Patterns nifm_patterns[] = {
};
constinit Patterns nim_patterns[] = {
- { "nim", "0x.0F00351F2003D5", 8, 0, adr_cond, mov2_patch, mov2_applied, true, MAKEHOSVERSION(17,0,0), FW_VER_ANY },
+ { "nim_old", "0x.0F00351F2003D5", 8, 0, adr_cond, mov2_patch, mov2_applied, true, MAKEHOSVERSION(17,0,0), MAKEHOSVERSION(20,5,0) },
+ { "nim_new", "0x.0700351F2003D5", 8, 0, adr_cond, mov2_patch, mov2_applied, true, MAKEHOSVERSION(21,0,0), FW_VER_ANY },
};
constinit Patterns ssl_patterns[] = {
From 01ead824eff681600e3cc424f4e1821d7d435aa7 Mon Sep 17 00:00:00 2001
From: impeeza <41979604+impeeza@users.noreply.github.com>
Date: Tue, 11 Nov 2025 11:36:14 -0500
Subject: [PATCH 28/45] Revert "fix fs, nim for 21.0.0, replace loader patch"
---
Makefile | 2 +-
overlay/src/main.cpp | 9 ++-------
sysmod/src/main.cpp | 37 +++++++++++++++++++++++++------------
3 files changed, 28 insertions(+), 20 deletions(-)
diff --git a/Makefile b/Makefile
index 82371ae..40c7fc0 100644
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@ MAKEFILES := sysmod overlay
TARGETS := $(foreach dir,$(MAKEFILES),$(CURDIR)/$(dir))
# the below was taken from atmosphere + switch-examples makefile
-export VERSION := 1.5.7
+export VERSION := 1.5.6
ifneq ($(strip $(shell git symbolic-ref --short HEAD 2>/dev/null)),)
export GIT_BRANCH := $(shell git symbolic-ref --short HEAD)
diff --git a/overlay/src/main.cpp b/overlay/src/main.cpp
index 762bd63..91aa64a 100644
--- a/overlay/src/main.cpp
+++ b/overlay/src/main.cpp
@@ -102,7 +102,6 @@ class GuiToggle final : public tsl::Gui {
list->addItem(config_noacidsigchk1.create_list_item("noacidsigchk1"));
list->addItem(config_noacidsigchk2.create_list_item("noacidsigchk2"));
list->addItem(config_noncasigchk_old.create_list_item("noncasigchk_old"));
- list->addItem(config_noncasigchk_old2.create_list_item("noncasigchk_old2"));
list->addItem(config_noncasigchk_new.create_list_item("noncasigchk_new"));
list->addItem(config_nocntchk.create_list_item("nocntchk"));
list->addItem(config_nocntchk2.create_list_item("nocntchk2"));
@@ -120,9 +119,7 @@ class GuiToggle final : public tsl::Gui {
list->addItem(config_ctest2.create_list_item("ctest2"));
list->addItem(new tsl::elm::CategoryHeader("NIM - 0100000000000025"));
- list->addItem(config_nim.create_list_item("nim_old"));
- list->addItem(config_nim.create_list_item("nim_new"));
-
+ list->addItem(config_nim.create_list_item("nim"));
list->addItem(new tsl::elm::CategoryHeader("Disable CA Verification - apply all"));
list->addItem(config_ssl1.create_list_item("disablecaverification1"));
@@ -136,7 +133,6 @@ class GuiToggle final : public tsl::Gui {
ConfigEntry config_noacidsigchk1{"fs", "noacidsigchk1", true};
ConfigEntry config_noacidsigchk2{"fs", "noacidsigchk2", true};
ConfigEntry config_noncasigchk_old{"fs", "noncasigchk_old", true};
- ConfigEntry config_noncasigchk_old2{"fs", "noncasigchk_old2", true};
ConfigEntry config_noncasigchk_new{"fs", "noncasigchk_new", true};
ConfigEntry config_nocntchk{"fs", "nocntchk", true};
ConfigEntry config_nocntchk2{"fs", "nocntchk2", true};
@@ -146,8 +142,7 @@ class GuiToggle final : public tsl::Gui {
ConfigEntry config_es3{"es", "es3", true};
ConfigEntry config_ctest{"nifm", "ctest", true};
ConfigEntry config_ctest2{"nifm", "ctest2", true};
- ConfigEntry config_nim{"nim_old", "nim_old", true};
- ConfigEntry config_nim{"nim_new", "nim_new", true};
+ ConfigEntry config_nim{"nim", "nim", true};
ConfigEntry config_ssl1{"ssl", "disablecaverification1", false};
ConfigEntry config_ssl2{"ssl", "disablecaverification2", false};
ConfigEntry config_ssl3{"ssl", "disablecaverification3", false};
diff --git a/sysmod/src/main.cpp b/sysmod/src/main.cpp
index 7134a68..e50938f 100644
--- a/sysmod/src/main.cpp
+++ b/sysmod/src/main.cpp
@@ -126,10 +126,18 @@ struct PatchEntry {
const u32 max_fw_ver{FW_VER_ANY}; // set to FW_VER_ANY to ignore
};
+constexpr auto subi_cond(u32 inst) -> bool {
+ // # Used on Atmosphère-NX 0.11.0 - 0.12.0.
+ const auto type = (inst >> 24) & 0xFF;
+ const auto imm = (inst >> 10) & 0xFFF;
+ return (type == 0x71) && (imm == 0x0A);
+}
-constexpr auto cmp_cond(u32 inst) -> bool {
- const auto type = inst >> 24;
- return type == 0x6B; // cmp w0, w1
+constexpr auto subr_cond(u32 inst) -> bool {
+ // # Used on Atmosphère-NX 0.13.0 and later.
+ const auto type = (inst >> 21) & 0x7F9;
+ const auto reg = (inst >> 16) & 0x1F;
+ return (type == 0x358) && (reg == 0x01);
}
constexpr auto bl_cond(u32 inst) -> bool {
@@ -141,6 +149,10 @@ constexpr auto tbz_cond(u32 inst) -> bool {
return ((inst >> 24) & 0x7F) == 0x36;
}
+constexpr auto subs_cond(u32 inst) -> bool {
+ return subi_cond(inst) || subr_cond(inst);
+}
+
constexpr auto cbz_cond(u32 inst) -> bool {
const auto type = inst >> 24;
return type == 0x34 || type == 0xB4;
@@ -201,7 +213,6 @@ constexpr PatchData nop_patch_data{ "0x1F2003D5" };
constexpr PatchData mov0_patch_data{ "0xE0031FAA" };
//mov x2, xzr
constexpr PatchData mov2_patch_data{ "0xE2031FAA" };
-constexpr PatchData cmp_patch_data{ "0x00" };
constexpr PatchData ssl1_patch_data{ "0x0A" };
constexpr PatchData ssl2_patch_data{ "0x08008052" };
constexpr PatchData ctest_patch_data{ "0x00309AD2001EA1F2610100D4E0031FAAC0035FD6" };
@@ -209,9 +220,9 @@ constexpr PatchData ctest_patch_data{ "0x00309AD2001EA1F2610100D4E0031FAAC0035FD
constexpr auto ret0_patch(u32 inst) -> PatchData { return ret0_patch_data; }
constexpr auto ret1_patch(u32 inst) -> PatchData { return ret1_patch_data; }
constexpr auto nop_patch(u32 inst) -> PatchData { return nop_patch_data; }
+constexpr auto subs_patch(u32 inst) -> PatchData { return subi_cond(inst) ? (u8)0x1 : (u8)0x0; }
constexpr auto mov0_patch(u32 inst) -> PatchData { return mov0_patch_data; }
constexpr auto mov2_patch(u32 inst) -> PatchData { return mov2_patch_data; }
-constexpr auto cmp_patch(u32 inst) -> PatchData { return cmp_patch_data; }
constexpr auto ssl1_patch(u32 inst) -> PatchData { return ssl1_patch_data; }
constexpr auto ssl2_patch(u32 inst) -> PatchData { return ssl2_patch_data; }
constexpr auto ctest_patch(u32 inst) -> PatchData { return ctest_patch_data; }
@@ -234,8 +245,12 @@ constexpr auto nop_applied(const u8* data, u32 inst) -> bool {
return nop_patch(inst).cmp(data);
}
-constexpr auto cmp_applied(const u8* data, u32 inst) -> bool {
- return cmp_patch(inst).cmp(data);
+constexpr auto subs_applied(const u8* data, u32 inst) -> bool {
+ const auto type_i = (inst >> 24) & 0xFF;
+ const auto imm = (inst >> 10) & 0xFFF;
+ const auto type_r = (inst >> 21) & 0x7F9;
+ const auto reg = (inst >> 16) & 0x1F;
+ return ((type_i == 0x71) && (imm == 0x1)) || ((type_r == 0x358) && (reg == 0x0));
}
constexpr auto b_applied(const u8* data, u32 inst) -> bool {
@@ -266,14 +281,13 @@ constinit Patterns fs_patterns[] = {
{ "noacidsigchk1", "0xC8FE4739", -24, 0, bl_cond, ret0_patch, ret0_applied, true, FW_VER_ANY, MAKEHOSVERSION(9,2,0) },
{ "noacidsigchk2", "0x0210911F000072", -5, 0, bl_cond, ret0_patch, ret0_applied, true, FW_VER_ANY, MAKEHOSVERSION(9,2,0) },
{ "noncasigchk_old", "0x0036.......71..0054..4839", -2, 0, tbz_cond, nop_patch, nop_applied, true, MAKEHOSVERSION(10,0,0), MAKEHOSVERSION(16,1,0) },
- { "noncasigchk_old2", "0x.94..0036.258052", 2, 0, tbz_cond, nop_patch, nop_applied, true, MAKEHOSVERSION(17,0,0), MAKEHOSVERSION(20,5,0) }, // 17.0.0 - 20.5.0
- { "noncasigchk_new", "0x.94..0036.........258052", 2, 0, tbz_cond, nop_patch, nop_applied, true, MAKEHOSVERSION(21,0,0), FW_VER_ANY }, // 21.0.0+
+ { "noncasigchk_new", "0x.94..0036.258052", 2, 0, tbz_cond, nop_patch, nop_applied, true, MAKEHOSVERSION(17,0,0), FW_VER_ANY }, // 17.0.0 - 19.0.0+
{ "nocntchk", "0x40f9...9408.0012.050071", 2, 0, bl_cond, ret0_patch, ret0_applied, true, MAKEHOSVERSION(10,0,0), MAKEHOSVERSION(18,1,0) },
{ "nocntchk2", "0x40f9...94..40b9..0012", 2, 0, bl_cond, ret0_patch, ret0_applied, true, MAKEHOSVERSION(19,0,0), FW_VER_ANY },
};
constinit Patterns ldr_patterns[] = {
- { "noacidsigchk", "17..009401C0BE121F00", 9, 2, cmp_cond, cmp_patch, cmp_applied, true, FW_VER_ANY }, // 1F00016B - cmp w0, w1 patched to 1F00006B - cmp w0, w0
+ { "noacidsigchk", "0xFD7B.A8C0035FD6", 16, 2, subs_cond, subs_patch, subs_applied, true, FW_VER_ANY },
};
constinit Patterns es_patterns[] = {
@@ -288,8 +302,7 @@ constinit Patterns nifm_patterns[] = {
};
constinit Patterns nim_patterns[] = {
- { "nim_old", "0x.0F00351F2003D5", 8, 0, adr_cond, mov2_patch, mov2_applied, true, MAKEHOSVERSION(17,0,0), MAKEHOSVERSION(20,5,0) },
- { "nim_new", "0x.0700351F2003D5", 8, 0, adr_cond, mov2_patch, mov2_applied, true, MAKEHOSVERSION(21,0,0), FW_VER_ANY },
+ { "nim", "0x.0F00351F2003D5", 8, 0, adr_cond, mov2_patch, mov2_applied, true, MAKEHOSVERSION(17,0,0), FW_VER_ANY },
};
constinit Patterns ssl_patterns[] = {
From 45312d8897466d7dc563b95a99bc6bee1605292b Mon Sep 17 00:00:00 2001
From: borntohonk <6264306+borntohonk@users.noreply.github.com>
Date: Tue, 11 Nov 2025 17:52:36 +0100
Subject: [PATCH 29/45] add 21.0.0 support
---
Makefile | 2 +-
overlay/src/main.cpp | 8 ++++++--
sysmod/src/main.cpp | 36 ++++++++++++------------------------
3 files changed, 19 insertions(+), 27 deletions(-)
diff --git a/Makefile b/Makefile
index 40c7fc0..82371ae 100644
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@ MAKEFILES := sysmod overlay
TARGETS := $(foreach dir,$(MAKEFILES),$(CURDIR)/$(dir))
# the below was taken from atmosphere + switch-examples makefile
-export VERSION := 1.5.6
+export VERSION := 1.5.7
ifneq ($(strip $(shell git symbolic-ref --short HEAD 2>/dev/null)),)
export GIT_BRANCH := $(shell git symbolic-ref --short HEAD)
diff --git a/overlay/src/main.cpp b/overlay/src/main.cpp
index 91aa64a..59237fb 100644
--- a/overlay/src/main.cpp
+++ b/overlay/src/main.cpp
@@ -102,6 +102,7 @@ class GuiToggle final : public tsl::Gui {
list->addItem(config_noacidsigchk1.create_list_item("noacidsigchk1"));
list->addItem(config_noacidsigchk2.create_list_item("noacidsigchk2"));
list->addItem(config_noncasigchk_old.create_list_item("noncasigchk_old"));
+ list->addItem(config_noncasigchk_old2.create_list_item("noncasigchk_old2"));
list->addItem(config_noncasigchk_new.create_list_item("noncasigchk_new"));
list->addItem(config_nocntchk.create_list_item("nocntchk"));
list->addItem(config_nocntchk2.create_list_item("nocntchk2"));
@@ -119,7 +120,8 @@ class GuiToggle final : public tsl::Gui {
list->addItem(config_ctest2.create_list_item("ctest2"));
list->addItem(new tsl::elm::CategoryHeader("NIM - 0100000000000025"));
- list->addItem(config_nim.create_list_item("nim"));
+ list->addItem(config_nim_old.create_list_item("nim_old"));
+ list->addItem(config_nim_new.create_list_item("nim_new"));
list->addItem(new tsl::elm::CategoryHeader("Disable CA Verification - apply all"));
list->addItem(config_ssl1.create_list_item("disablecaverification1"));
@@ -133,6 +135,7 @@ class GuiToggle final : public tsl::Gui {
ConfigEntry config_noacidsigchk1{"fs", "noacidsigchk1", true};
ConfigEntry config_noacidsigchk2{"fs", "noacidsigchk2", true};
ConfigEntry config_noncasigchk_old{"fs", "noncasigchk_old", true};
+ ConfigEntry config_noncasigchk_old2{"fs", "noncasigchk_old2", true};
ConfigEntry config_noncasigchk_new{"fs", "noncasigchk_new", true};
ConfigEntry config_nocntchk{"fs", "nocntchk", true};
ConfigEntry config_nocntchk2{"fs", "nocntchk2", true};
@@ -142,7 +145,8 @@ class GuiToggle final : public tsl::Gui {
ConfigEntry config_es3{"es", "es3", true};
ConfigEntry config_ctest{"nifm", "ctest", true};
ConfigEntry config_ctest2{"nifm", "ctest2", true};
- ConfigEntry config_nim{"nim", "nim", true};
+ ConfigEntry config_nim_old{"nim_old", "nim_old", true};
+ ConfigEntry config_nim_new{"nim_new", "nim_new", true};
ConfigEntry config_ssl1{"ssl", "disablecaverification1", false};
ConfigEntry config_ssl2{"ssl", "disablecaverification2", false};
ConfigEntry config_ssl3{"ssl", "disablecaverification3", false};
diff --git a/sysmod/src/main.cpp b/sysmod/src/main.cpp
index e50938f..6d6d015 100644
--- a/sysmod/src/main.cpp
+++ b/sysmod/src/main.cpp
@@ -126,18 +126,10 @@ struct PatchEntry {
const u32 max_fw_ver{FW_VER_ANY}; // set to FW_VER_ANY to ignore
};
-constexpr auto subi_cond(u32 inst) -> bool {
- // # Used on Atmosphère-NX 0.11.0 - 0.12.0.
- const auto type = (inst >> 24) & 0xFF;
- const auto imm = (inst >> 10) & 0xFFF;
- return (type == 0x71) && (imm == 0x0A);
-}
-constexpr auto subr_cond(u32 inst) -> bool {
- // # Used on Atmosphère-NX 0.13.0 and later.
- const auto type = (inst >> 21) & 0x7F9;
- const auto reg = (inst >> 16) & 0x1F;
- return (type == 0x358) && (reg == 0x01);
+constexpr auto cmp_cond(u32 inst) -> bool {
+ const auto type = inst >> 24;
+ return type == 0x6B; // cmp w0, w1
}
constexpr auto bl_cond(u32 inst) -> bool {
@@ -149,9 +141,6 @@ constexpr auto tbz_cond(u32 inst) -> bool {
return ((inst >> 24) & 0x7F) == 0x36;
}
-constexpr auto subs_cond(u32 inst) -> bool {
- return subi_cond(inst) || subr_cond(inst);
-}
constexpr auto cbz_cond(u32 inst) -> bool {
const auto type = inst >> 24;
@@ -213,6 +202,7 @@ constexpr PatchData nop_patch_data{ "0x1F2003D5" };
constexpr PatchData mov0_patch_data{ "0xE0031FAA" };
//mov x2, xzr
constexpr PatchData mov2_patch_data{ "0xE2031FAA" };
+constexpr PatchData cmp_patch_data{ "0x00" };
constexpr PatchData ssl1_patch_data{ "0x0A" };
constexpr PatchData ssl2_patch_data{ "0x08008052" };
constexpr PatchData ctest_patch_data{ "0x00309AD2001EA1F2610100D4E0031FAAC0035FD6" };
@@ -220,9 +210,9 @@ constexpr PatchData ctest_patch_data{ "0x00309AD2001EA1F2610100D4E0031FAAC0035FD
constexpr auto ret0_patch(u32 inst) -> PatchData { return ret0_patch_data; }
constexpr auto ret1_patch(u32 inst) -> PatchData { return ret1_patch_data; }
constexpr auto nop_patch(u32 inst) -> PatchData { return nop_patch_data; }
-constexpr auto subs_patch(u32 inst) -> PatchData { return subi_cond(inst) ? (u8)0x1 : (u8)0x0; }
constexpr auto mov0_patch(u32 inst) -> PatchData { return mov0_patch_data; }
constexpr auto mov2_patch(u32 inst) -> PatchData { return mov2_patch_data; }
+constexpr auto cmp_patch(u32 inst) -> PatchData { return cmp_patch_data; }
constexpr auto ssl1_patch(u32 inst) -> PatchData { return ssl1_patch_data; }
constexpr auto ssl2_patch(u32 inst) -> PatchData { return ssl2_patch_data; }
constexpr auto ctest_patch(u32 inst) -> PatchData { return ctest_patch_data; }
@@ -245,12 +235,8 @@ constexpr auto nop_applied(const u8* data, u32 inst) -> bool {
return nop_patch(inst).cmp(data);
}
-constexpr auto subs_applied(const u8* data, u32 inst) -> bool {
- const auto type_i = (inst >> 24) & 0xFF;
- const auto imm = (inst >> 10) & 0xFFF;
- const auto type_r = (inst >> 21) & 0x7F9;
- const auto reg = (inst >> 16) & 0x1F;
- return ((type_i == 0x71) && (imm == 0x1)) || ((type_r == 0x358) && (reg == 0x0));
+constexpr auto cmp_applied(const u8* data, u32 inst) -> bool {
+ return cmp_patch(inst).cmp(data);
}
constexpr auto b_applied(const u8* data, u32 inst) -> bool {
@@ -281,13 +267,14 @@ constinit Patterns fs_patterns[] = {
{ "noacidsigchk1", "0xC8FE4739", -24, 0, bl_cond, ret0_patch, ret0_applied, true, FW_VER_ANY, MAKEHOSVERSION(9,2,0) },
{ "noacidsigchk2", "0x0210911F000072", -5, 0, bl_cond, ret0_patch, ret0_applied, true, FW_VER_ANY, MAKEHOSVERSION(9,2,0) },
{ "noncasigchk_old", "0x0036.......71..0054..4839", -2, 0, tbz_cond, nop_patch, nop_applied, true, MAKEHOSVERSION(10,0,0), MAKEHOSVERSION(16,1,0) },
- { "noncasigchk_new", "0x.94..0036.258052", 2, 0, tbz_cond, nop_patch, nop_applied, true, MAKEHOSVERSION(17,0,0), FW_VER_ANY }, // 17.0.0 - 19.0.0+
+ { "noncasigchk_old2", "0x.94..0036.258052", 2, 0, tbz_cond, nop_patch, nop_applied, true, MAKEHOSVERSION(17,0,0), MAKEHOSVERSION(20,5,0) }, // 17.0.0 - 20.5.0
+ { "noncasigchk_new", "0x.94..0036.........258052", 2, 0, tbz_cond, nop_patch, nop_applied, true, MAKEHOSVERSION(21,0,0), FW_VER_ANY }, // 21.0.0+
{ "nocntchk", "0x40f9...9408.0012.050071", 2, 0, bl_cond, ret0_patch, ret0_applied, true, MAKEHOSVERSION(10,0,0), MAKEHOSVERSION(18,1,0) },
{ "nocntchk2", "0x40f9...94..40b9..0012", 2, 0, bl_cond, ret0_patch, ret0_applied, true, MAKEHOSVERSION(19,0,0), FW_VER_ANY },
};
constinit Patterns ldr_patterns[] = {
- { "noacidsigchk", "0xFD7B.A8C0035FD6", 16, 2, subs_cond, subs_patch, subs_applied, true, FW_VER_ANY },
+ { "noacidsigchk", "17..009401C0BE121F00", 9, 2, cmp_cond, cmp_patch, cmp_applied, true, FW_VER_ANY }, // 1F00016B - cmp w0, w1 patched to 1F00006B - cmp w0, w0
};
constinit Patterns es_patterns[] = {
@@ -302,7 +289,8 @@ constinit Patterns nifm_patterns[] = {
};
constinit Patterns nim_patterns[] = {
- { "nim", "0x.0F00351F2003D5", 8, 0, adr_cond, mov2_patch, mov2_applied, true, MAKEHOSVERSION(17,0,0), FW_VER_ANY },
+ { "nim_old", "0x.0F00351F2003D5", 8, 0, adr_cond, mov2_patch, mov2_applied, true, MAKEHOSVERSION(17,0,0), MAKEHOSVERSION(20,5,0) },
+ { "nim_new", "0x.0700351F2003D5", 8, 0, adr_cond, mov2_patch, mov2_applied, true, MAKEHOSVERSION(21,0,0), FW_VER_ANY },
};
constinit Patterns ssl_patterns[] = {
From 4f8ccf6c82b9f175e9a7577a9c672656a60eb00d Mon Sep 17 00:00:00 2001
From: borntohonk <6264306+borntohonk@users.noreply.github.com>
Date: Sun, 16 Nov 2025 14:47:39 +0100
Subject: [PATCH 30/45] fix new loader patch for atmosphere 1.10.0
---
Makefile | 2 +-
sysmod/src/main.cpp | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/Makefile b/Makefile
index 82371ae..0f3596e 100644
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@ MAKEFILES := sysmod overlay
TARGETS := $(foreach dir,$(MAKEFILES),$(CURDIR)/$(dir))
# the below was taken from atmosphere + switch-examples makefile
-export VERSION := 1.5.7
+export VERSION := 1.5.8
ifneq ($(strip $(shell git symbolic-ref --short HEAD 2>/dev/null)),)
export GIT_BRANCH := $(shell git symbolic-ref --short HEAD)
diff --git a/sysmod/src/main.cpp b/sysmod/src/main.cpp
index 6d6d015..3ce1ec1 100644
--- a/sysmod/src/main.cpp
+++ b/sysmod/src/main.cpp
@@ -274,7 +274,7 @@ constinit Patterns fs_patterns[] = {
};
constinit Patterns ldr_patterns[] = {
- { "noacidsigchk", "17..009401C0BE121F00", 9, 2, cmp_cond, cmp_patch, cmp_applied, true, FW_VER_ANY }, // 1F00016B - cmp w0, w1 patched to 1F00006B - cmp w0, w0
+ { "noacidsigchk", "009401C0BE121F00", 6, 2, cmp_cond, cmp_patch, cmp_applied, true, FW_VER_ANY }, // 1F00016B - cmp w0, w1 patched to 1F00006B - cmp w0, w0
};
constinit Patterns es_patterns[] = {
From 212a60438b3d870dc3bcdc1145e6f71428a42e17 Mon Sep 17 00:00:00 2001
From: borntohonk <6264306+borntohonk@users.noreply.github.com>
Date: Sun, 16 Nov 2025 18:56:19 +0100
Subject: [PATCH 31/45] force acquire latest packages from pacman
---
.github/workflows/build-jobs.yaml | 1 +
1 file changed, 1 insertion(+)
diff --git a/.github/workflows/build-jobs.yaml b/.github/workflows/build-jobs.yaml
index dfd713e..c558f52 100644
--- a/.github/workflows/build-jobs.yaml
+++ b/.github/workflows/build-jobs.yaml
@@ -20,6 +20,7 @@ jobs:
- name: Build sys-patch
run: |
+ dkp-pacman -Syu --noconfirm && \
make -C sys-patch -j$(nproc) dist && \
VERSION=$(grep 'export VERSION := ' sys-patch/Makefile | cut -c 19-)
TAGVERSION=$(curl -s https://api.github.com/repos/$GITHUB_REPOSITORY/releases/latest | grep "tag_name" | head -1 | cut -d '"' -f 4)
From b3a3294565d7d1acd09975e66f9b3e3bf2be8db7 Mon Sep 17 00:00:00 2001
From: borntohonk <6264306+borntohonk@users.noreply.github.com>
Date: Sun, 16 Nov 2025 19:01:29 +0100
Subject: [PATCH 32/45] Revert "force acquire latest packages from pacman"
This reverts commit 212a60438b3d870dc3bcdc1145e6f71428a42e17.
---
.github/workflows/build-jobs.yaml | 1 -
1 file changed, 1 deletion(-)
diff --git a/.github/workflows/build-jobs.yaml b/.github/workflows/build-jobs.yaml
index c558f52..dfd713e 100644
--- a/.github/workflows/build-jobs.yaml
+++ b/.github/workflows/build-jobs.yaml
@@ -20,7 +20,6 @@ jobs:
- name: Build sys-patch
run: |
- dkp-pacman -Syu --noconfirm && \
make -C sys-patch -j$(nproc) dist && \
VERSION=$(grep 'export VERSION := ' sys-patch/Makefile | cut -c 19-)
TAGVERSION=$(curl -s https://api.github.com/repos/$GITHUB_REPOSITORY/releases/latest | grep "tag_name" | head -1 | cut -d '"' -f 4)
From 4161f455c5463524e6887750385fd1e0ddaf989e Mon Sep 17 00:00:00 2001
From: borntohonk <6264306+borntohonk@users.noreply.github.com>
Date: Sun, 16 Nov 2025 20:23:15 +0100
Subject: [PATCH 33/45] actually verify ctest for newer firmware
---
overlay/src/main.cpp | 2 ++
sysmod/src/main.cpp | 8 +++++++-
2 files changed, 9 insertions(+), 1 deletion(-)
diff --git a/overlay/src/main.cpp b/overlay/src/main.cpp
index 59237fb..66c8453 100644
--- a/overlay/src/main.cpp
+++ b/overlay/src/main.cpp
@@ -118,6 +118,7 @@ class GuiToggle final : public tsl::Gui {
list->addItem(new tsl::elm::CategoryHeader("NIFM - 010000000000000F"));
list->addItem(config_ctest.create_list_item("ctest"));
list->addItem(config_ctest2.create_list_item("ctest2"));
+ list->addItem(config_ctest3.create_list_item("ctest3"));
list->addItem(new tsl::elm::CategoryHeader("NIM - 0100000000000025"));
list->addItem(config_nim_old.create_list_item("nim_old"));
@@ -145,6 +146,7 @@ class GuiToggle final : public tsl::Gui {
ConfigEntry config_es3{"es", "es3", true};
ConfigEntry config_ctest{"nifm", "ctest", true};
ConfigEntry config_ctest2{"nifm", "ctest2", true};
+ ConfigEntry config_ctest3{"nifm", "ctest3", true};
ConfigEntry config_nim_old{"nim_old", "nim_old", true};
ConfigEntry config_nim_new{"nim_new", "nim_new", true};
ConfigEntry config_ssl1{"ssl", "disablecaverification1", false};
diff --git a/sysmod/src/main.cpp b/sysmod/src/main.cpp
index 3ce1ec1..7dea935 100644
--- a/sysmod/src/main.cpp
+++ b/sysmod/src/main.cpp
@@ -194,6 +194,10 @@ constexpr auto b_cond(u32 inst) -> bool {
return type == 0x14 || type == 0x17;
}
+constexpr auto stp_cond(u32 inst) -> bool {
+ return (inst >> 24) == 0xA9; // stp x29, x30, [sp, #-0x30]!
+}
+
// to view patches, use https://armconverter.com/?lock=arm64
constexpr PatchData ret0_patch_data{ "0xE0031F2A" };
constexpr PatchData ret1_patch_data{ "0x10000014" };
@@ -285,9 +289,11 @@ constinit Patterns es_patterns[] = {
constinit Patterns nifm_patterns[] = {
{ "ctest", "....................F40300AA....F30314AAE00314AA9F0201397F8E04F8", 16, -16, ctest_cond, ctest_patch, ctest_applied, true, FW_VER_ANY, MAKEHOSVERSION(18,1,0) }, // 1.0.0 - 18.1.0
- { "ctest2", "14...........91...........97...............14", 37, 4, b_cond, ctest_patch, ctest_applied, true, MAKEHOSVERSION(19,0,0), FW_VER_ANY }, //19.0.0 - 20.0.1+
+ { "ctest2", "14...........91...........97...............14", 41, 0, stp_cond, ctest_patch, ctest_applied, true, MAKEHOSVERSION(19,0,0), MAKEHOSVERSION(20,5,0) }, //19.0.0 - 20.5.0
+ { "ctest3", "14...........91...........97...............14", 49, 0, stp_cond, ctest_patch, ctest_applied, true, MAKEHOSVERSION(21,0,0), FW_VER_ANY }, //21.0.0
};
+
constinit Patterns nim_patterns[] = {
{ "nim_old", "0x.0F00351F2003D5", 8, 0, adr_cond, mov2_patch, mov2_applied, true, MAKEHOSVERSION(17,0,0), MAKEHOSVERSION(20,5,0) },
{ "nim_new", "0x.0700351F2003D5", 8, 0, adr_cond, mov2_patch, mov2_applied, true, MAKEHOSVERSION(21,0,0), FW_VER_ANY },
From 2b8ec7c3bc2f3dc9b8b69378b1205a4f39ab8b3d Mon Sep 17 00:00:00 2001
From: impeeza <41979604+impeeza@users.noreply.github.com>
Date: Sun, 16 Nov 2025 17:19:26 -0500
Subject: [PATCH 34/45] Correct Typos on Makefiles
Correct some Typos on Makefiles which avoid the complete clean of files at `make clean`
---
Makefile | 1 +
sysmod/Makefile | 6 +++---
2 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/Makefile b/Makefile
index 0f3596e..e752ef4 100644
--- a/Makefile
+++ b/Makefile
@@ -46,6 +46,7 @@ $(TARGETS):
clean:
@rm -rf out
+ @rm -f sys-patch.zip
@for i in $(TARGETS); do $(MAKE) -C $$i clean || exit 1; done;
dist: all
diff --git a/sysmod/Makefile b/sysmod/Makefile
index 41098a7..2663479 100644
--- a/sysmod/Makefile
+++ b/sysmod/Makefile
@@ -180,14 +180,14 @@ else
@rm -fr $(BUILD) $(TARGET).nsp $(TARGET).nso $(TARGET).npdm $(TARGET).elf
endif
@rm -rf out/
- @rm -f sys-patch.zip
+ @rm -f sys-patch-sysmodule.zip
#---------------------------------------------------------------------------------
dist: all
@echo making dist ...
- @rm -f sys-patch-no-overlay.zip
- @cd out; zip -r ../sys-patch-no-overlay.zip ./*; cd ../
+ @rm -f sys-patch-sysmodule.zip
+ @cd out; zip -r ../sys-patch-sysmodule.zip ./*; cd ../
#---------------------------------------------------------------------------------
else
.PHONY: all
From c37c50365c197fe55cbba9f1c7000a279cb67059 Mon Sep 17 00:00:00 2001
From: borntohonk <6264306+borntohonk@users.noreply.github.com>
Date: Mon, 17 Nov 2025 10:15:27 +0100
Subject: [PATCH 35/45] fix es for 21.0.0
---
overlay/src/main.cpp | 2 ++
sysmod/src/main.cpp | 3 ++-
2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/overlay/src/main.cpp b/overlay/src/main.cpp
index 66c8453..777b8dc 100644
--- a/overlay/src/main.cpp
+++ b/overlay/src/main.cpp
@@ -114,6 +114,7 @@ class GuiToggle final : public tsl::Gui {
list->addItem(config_es1.create_list_item("es1"));
list->addItem(config_es2.create_list_item("es2"));
list->addItem(config_es3.create_list_item("es3"));
+ list->addItem(config_es4.create_list_item("es4"));
list->addItem(new tsl::elm::CategoryHeader("NIFM - 010000000000000F"));
list->addItem(config_ctest.create_list_item("ctest"));
@@ -144,6 +145,7 @@ class GuiToggle final : public tsl::Gui {
ConfigEntry config_es1{"es", "es1", true};
ConfigEntry config_es2{"es", "es2", true};
ConfigEntry config_es3{"es", "es3", true};
+ ConfigEntry config_es4{"es", "es4", true};
ConfigEntry config_ctest{"nifm", "ctest", true};
ConfigEntry config_ctest2{"nifm", "ctest2", true};
ConfigEntry config_ctest3{"nifm", "ctest3", true};
diff --git a/sysmod/src/main.cpp b/sysmod/src/main.cpp
index 7dea935..27a3d61 100644
--- a/sysmod/src/main.cpp
+++ b/sysmod/src/main.cpp
@@ -284,7 +284,8 @@ constinit Patterns ldr_patterns[] = {
constinit Patterns es_patterns[] = {
{ "es1", "0x..00.....e0.0091..0094..4092...d1", 16, 0, and_cond, mov0_patch, mov0_applied, true, FW_VER_ANY, MAKEHOSVERSION(1,0,0) },
{ "es2", "0x..00.....e0.0091..0094..4092...a9", 16, 0, and_cond, mov0_patch, mov0_applied, true, MAKEHOSVERSION(2,0,0), MAKEHOSVERSION(8,1,1) },
- { "es3", "0x..00...0094a0..d1..ff97.......a9", 16, 0, mov2_cond, mov0_patch, mov0_applied, true, MAKEHOSVERSION(9,0,0), FW_VER_ANY }, //9.0.0 - 19.0.0+
+ { "es3", "0x..00...0094a0..d1..ff97.......a9", 16, 0, mov2_cond, mov0_patch, mov0_applied, true, MAKEHOSVERSION(9,0,0), MAKEHOSVERSION(20,5,0) }, //9.0.0 - 20.5.0
+ { "es4", "0x..00....97a0..d1...97e003132a...a9", 16, 0, mov2_cond, mov0_patch, mov0_applied, true, MAKEHOSVERSION(9,0,0), FW_VER_ANY } }, //21.0.0+
};
constinit Patterns nifm_patterns[] = {
From fc0f3941b4e5e74be22417fb835bd89802b12e19 Mon Sep 17 00:00:00 2001
From: borntohonk <6264306+borntohonk@users.noreply.github.com>
Date: Mon, 17 Nov 2025 10:21:58 +0100
Subject: [PATCH 36/45] accidental remnant bracket
---
sysmod/src/main.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sysmod/src/main.cpp b/sysmod/src/main.cpp
index 27a3d61..7b5052b 100644
--- a/sysmod/src/main.cpp
+++ b/sysmod/src/main.cpp
@@ -285,7 +285,7 @@ constinit Patterns es_patterns[] = {
{ "es1", "0x..00.....e0.0091..0094..4092...d1", 16, 0, and_cond, mov0_patch, mov0_applied, true, FW_VER_ANY, MAKEHOSVERSION(1,0,0) },
{ "es2", "0x..00.....e0.0091..0094..4092...a9", 16, 0, and_cond, mov0_patch, mov0_applied, true, MAKEHOSVERSION(2,0,0), MAKEHOSVERSION(8,1,1) },
{ "es3", "0x..00...0094a0..d1..ff97.......a9", 16, 0, mov2_cond, mov0_patch, mov0_applied, true, MAKEHOSVERSION(9,0,0), MAKEHOSVERSION(20,5,0) }, //9.0.0 - 20.5.0
- { "es4", "0x..00....97a0..d1...97e003132a...a9", 16, 0, mov2_cond, mov0_patch, mov0_applied, true, MAKEHOSVERSION(9,0,0), FW_VER_ANY } }, //21.0.0+
+ { "es4", "0x..00....97a0..d1...97e003132a...a9", 16, 0, mov2_cond, mov0_patch, mov0_applied, true, MAKEHOSVERSION(9,0,0), FW_VER_ANY }, //21.0.0+
};
constinit Patterns nifm_patterns[] = {
From b774496fa1617dbff7d2c694602449072e6b5778 Mon Sep 17 00:00:00 2001
From: borntohonk <6264306+borntohonk@users.noreply.github.com>
Date: Mon, 17 Nov 2025 16:06:52 +0100
Subject: [PATCH 37/45] fix typo
---
sysmod/src/main.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sysmod/src/main.cpp b/sysmod/src/main.cpp
index 7b5052b..219375f 100644
--- a/sysmod/src/main.cpp
+++ b/sysmod/src/main.cpp
@@ -285,7 +285,7 @@ constinit Patterns es_patterns[] = {
{ "es1", "0x..00.....e0.0091..0094..4092...d1", 16, 0, and_cond, mov0_patch, mov0_applied, true, FW_VER_ANY, MAKEHOSVERSION(1,0,0) },
{ "es2", "0x..00.....e0.0091..0094..4092...a9", 16, 0, and_cond, mov0_patch, mov0_applied, true, MAKEHOSVERSION(2,0,0), MAKEHOSVERSION(8,1,1) },
{ "es3", "0x..00...0094a0..d1..ff97.......a9", 16, 0, mov2_cond, mov0_patch, mov0_applied, true, MAKEHOSVERSION(9,0,0), MAKEHOSVERSION(20,5,0) }, //9.0.0 - 20.5.0
- { "es4", "0x..00....97a0..d1...97e003132a...a9", 16, 0, mov2_cond, mov0_patch, mov0_applied, true, MAKEHOSVERSION(9,0,0), FW_VER_ANY }, //21.0.0+
+ { "es4", "0x..00....97a0..d1...97e003132a...a9", 16, 0, mov2_cond, mov0_patch, mov0_applied, true, MAKEHOSVERSION(21,0,0), FW_VER_ANY }, //21.0.0+
};
constinit Patterns nifm_patterns[] = {
From 62e15f48bdab0dbaef04acae3df890be8c38e4ca Mon Sep 17 00:00:00 2001
From: impeeza <41979604+impeeza@users.noreply.github.com>
Date: Mon, 17 Nov 2025 12:03:30 -0500
Subject: [PATCH 38/45] Add libnx dependency installation step
Added a step to clone and install libnx dependencies.
---
.github/workflows/build-jobs.yaml | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/.github/workflows/build-jobs.yaml b/.github/workflows/build-jobs.yaml
index dfd713e..48717a8 100644
--- a/.github/workflows/build-jobs.yaml
+++ b/.github/workflows/build-jobs.yaml
@@ -18,6 +18,11 @@ jobs:
path: sys-patch
submodules: recursive
+ - name: deps - libnx
+ run: |
+ git clone https://github.com/switchbrew/libnx.git /tmp/libnx
+ make -C /tmp/libnx install -j4
+
- name: Build sys-patch
run: |
make -C sys-patch -j$(nproc) dist && \
From 64a918fb4651fa0046bb87451313d4f67928243b Mon Sep 17 00:00:00 2001
From: impeeza <41979604+impeeza@users.noreply.github.com>
Date: Mon, 17 Nov 2025 12:04:57 -0500
Subject: [PATCH 39/45] Fix indentation in build-jobs.yaml
---
.github/workflows/build-jobs.yaml | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/.github/workflows/build-jobs.yaml b/.github/workflows/build-jobs.yaml
index 48717a8..5fc4fc8 100644
--- a/.github/workflows/build-jobs.yaml
+++ b/.github/workflows/build-jobs.yaml
@@ -19,9 +19,9 @@ jobs:
submodules: recursive
- name: deps - libnx
- run: |
- git clone https://github.com/switchbrew/libnx.git /tmp/libnx
- make -C /tmp/libnx install -j4
+ run: |
+ git clone https://github.com/switchbrew/libnx.git /tmp/libnx
+ make -C /tmp/libnx install -j4
- name: Build sys-patch
run: |
From a516a22292abecc989cff5163d22f2d7b306cbb8 Mon Sep 17 00:00:00 2001
From: borntohonk <6264306+borntohonk@users.noreply.github.com>
Date: Tue, 18 Nov 2025 11:35:42 +0100
Subject: [PATCH 40/45] Revert libnx build as devkkitpro/devkita64 docker image
was updated with libnx 4.10
---
.github/workflows/build-jobs.yaml | 5 -----
1 file changed, 5 deletions(-)
diff --git a/.github/workflows/build-jobs.yaml b/.github/workflows/build-jobs.yaml
index 5fc4fc8..dfd713e 100644
--- a/.github/workflows/build-jobs.yaml
+++ b/.github/workflows/build-jobs.yaml
@@ -18,11 +18,6 @@ jobs:
path: sys-patch
submodules: recursive
- - name: deps - libnx
- run: |
- git clone https://github.com/switchbrew/libnx.git /tmp/libnx
- make -C /tmp/libnx install -j4
-
- name: Build sys-patch
run: |
make -C sys-patch -j$(nproc) dist && \
From 3d4ce3e0229f3fa380adf65fd0c3c5f60054e323 Mon Sep 17 00:00:00 2001
From: borntohonk <6264306+borntohonk@users.noreply.github.com>
Date: Tue, 18 Nov 2025 12:03:24 +0100
Subject: [PATCH 41/45] add optional no_erpt patches
---
overlay/src/main.cpp | 6 ++++++
sysmod/src/main.cpp | 15 +++++++++++++--
2 files changed, 19 insertions(+), 2 deletions(-)
diff --git a/overlay/src/main.cpp b/overlay/src/main.cpp
index 777b8dc..7d7b642 100644
--- a/overlay/src/main.cpp
+++ b/overlay/src/main.cpp
@@ -110,6 +110,11 @@ class GuiToggle final : public tsl::Gui {
list->addItem(new tsl::elm::CategoryHeader("LDR - 0100000000000001"));
list->addItem(config_noacidsigchk.create_list_item("noacidsigchk"));
+ list->addItem(new tsl::elm::CategoryHeader("ERPT - 010000000000002B"));
+ list->addItem(config_no_erpt.create_list_item("no_erpt"));
+
+ list->addItem(config_no_erpt.create_list_item("no_erpt"));
+
list->addItem(new tsl::elm::CategoryHeader("ES - 0100000000000033"));
list->addItem(config_es1.create_list_item("es1"));
list->addItem(config_es2.create_list_item("es2"));
@@ -142,6 +147,7 @@ class GuiToggle final : public tsl::Gui {
ConfigEntry config_nocntchk{"fs", "nocntchk", true};
ConfigEntry config_nocntchk2{"fs", "nocntchk2", true};
ConfigEntry config_noacidsigchk{"ldr", "noacidsigchk", true};
+ ConfigEntry config_no_erpt{"erpt", "no_erpt", false};
ConfigEntry config_es1{"es", "es1", true};
ConfigEntry config_es2{"es", "es2", true};
ConfigEntry config_es3{"es", "es3", true};
diff --git a/sysmod/src/main.cpp b/sysmod/src/main.cpp
index 219375f..93838b5 100644
--- a/sysmod/src/main.cpp
+++ b/sysmod/src/main.cpp
@@ -201,6 +201,7 @@ constexpr auto stp_cond(u32 inst) -> bool {
// to view patches, use https://armconverter.com/?lock=arm64
constexpr PatchData ret0_patch_data{ "0xE0031F2A" };
constexpr PatchData ret1_patch_data{ "0x10000014" };
+constexpr PatchData erpt_patch_data{ "0xE0031F2AC0035FD6" };
constexpr PatchData nop_patch_data{ "0x1F2003D5" };
//mov x0, xzr
constexpr PatchData mov0_patch_data{ "0xE0031FAA" };
@@ -213,6 +214,7 @@ constexpr PatchData ctest_patch_data{ "0x00309AD2001EA1F2610100D4E0031FAAC0035FD
constexpr auto ret0_patch(u32 inst) -> PatchData { return ret0_patch_data; }
constexpr auto ret1_patch(u32 inst) -> PatchData { return ret1_patch_data; }
+constexpr auto erpt_patch(u32 inst) -> PatchData { return erpt_patch_data; }
constexpr auto nop_patch(u32 inst) -> PatchData { return nop_patch_data; }
constexpr auto mov0_patch(u32 inst) -> PatchData { return mov0_patch_data; }
constexpr auto mov2_patch(u32 inst) -> PatchData { return mov2_patch_data; }
@@ -243,6 +245,10 @@ constexpr auto cmp_applied(const u8* data, u32 inst) -> bool {
return cmp_patch(inst).cmp(data);
}
+constexpr auto erpt_applied(const u8* data, u32 inst) -> bool {
+ return erpt_patch(inst).cmp(data);
+}
+
constexpr auto b_applied(const u8* data, u32 inst) -> bool {
return 0x14 == (inst >> 24);
}
@@ -281,11 +287,15 @@ constinit Patterns ldr_patterns[] = {
{ "noacidsigchk", "009401C0BE121F00", 6, 2, cmp_cond, cmp_patch, cmp_applied, true, FW_VER_ANY }, // 1F00016B - cmp w0, w1 patched to 1F00006B - cmp w0, w0
};
+constinit Patterns erpt_patterns[] = {
+ { "no_erpt", "0xFD7B02A9FD830091F76305A9", -4, 0, stp_cond, erpt_patch, erpt_applied, false },
+};
+
constinit Patterns es_patterns[] = {
{ "es1", "0x..00.....e0.0091..0094..4092...d1", 16, 0, and_cond, mov0_patch, mov0_applied, true, FW_VER_ANY, MAKEHOSVERSION(1,0,0) },
{ "es2", "0x..00.....e0.0091..0094..4092...a9", 16, 0, and_cond, mov0_patch, mov0_applied, true, MAKEHOSVERSION(2,0,0), MAKEHOSVERSION(8,1,1) },
{ "es3", "0x..00...0094a0..d1..ff97.......a9", 16, 0, mov2_cond, mov0_patch, mov0_applied, true, MAKEHOSVERSION(9,0,0), MAKEHOSVERSION(20,5,0) }, //9.0.0 - 20.5.0
- { "es4", "0x..00....97a0..d1...97e003132a...a9", 16, 0, mov2_cond, mov0_patch, mov0_applied, true, MAKEHOSVERSION(21,0,0), FW_VER_ANY }, //21.0.0+
+ { "es4", "0x..00....97a0..d1...97e003132a...a9", 16, 0, mov2_cond, mov0_patch, mov0_applied, true, MAKEHOSVERSION(21,0,0), FW_VER_ANY }, //21.0.0+
};
constinit Patterns nifm_patterns[] = {
@@ -294,7 +304,6 @@ constinit Patterns nifm_patterns[] = {
{ "ctest3", "14...........91...........97...............14", 49, 0, stp_cond, ctest_patch, ctest_applied, true, MAKEHOSVERSION(21,0,0), FW_VER_ANY }, //21.0.0
};
-
constinit Patterns nim_patterns[] = {
{ "nim_old", "0x.0F00351F2003D5", 8, 0, adr_cond, mov2_patch, mov2_applied, true, MAKEHOSVERSION(17,0,0), MAKEHOSVERSION(20,5,0) },
{ "nim_new", "0x.0700351F2003D5", 8, 0, adr_cond, mov2_patch, mov2_applied, true, MAKEHOSVERSION(21,0,0), FW_VER_ANY },
@@ -312,6 +321,8 @@ constinit PatchEntry patches[] = {
{ "fs", 0x0100000000000000, fs_patterns },
// ldr needs to be patched in fw 10+
{ "ldr", 0x0100000000000001, ldr_patterns, MAKEHOSVERSION(10,0,0) },
+ // erpt no write patch
+ { "erpt", 0x010000000000002B, erpt_patterns, MAKEHOSVERSION(10,0,0) },
// es was added in fw 2
{ "es", 0x0100000000000033, es_patterns, MAKEHOSVERSION(2,0,0) },
{ "nifm", 0x010000000000000F, nifm_patterns },
From c826f3239133461a76b201658df6c536b8497db1 Mon Sep 17 00:00:00 2001
From: impeeza <41979604+impeeza@users.noreply.github.com>
Date: Tue, 18 Nov 2025 12:29:23 -0500
Subject: [PATCH 42/45] Remove duplicate list item for 'no_erpt'
Removed duplicate item addition for 'no_erpt'.
---
overlay/src/main.cpp | 2 --
1 file changed, 2 deletions(-)
diff --git a/overlay/src/main.cpp b/overlay/src/main.cpp
index 7d7b642..4839405 100644
--- a/overlay/src/main.cpp
+++ b/overlay/src/main.cpp
@@ -113,8 +113,6 @@ class GuiToggle final : public tsl::Gui {
list->addItem(new tsl::elm::CategoryHeader("ERPT - 010000000000002B"));
list->addItem(config_no_erpt.create_list_item("no_erpt"));
- list->addItem(config_no_erpt.create_list_item("no_erpt"));
-
list->addItem(new tsl::elm::CategoryHeader("ES - 0100000000000033"));
list->addItem(config_es1.create_list_item("es1"));
list->addItem(config_es2.create_list_item("es2"));
From ff5edbc38507249ddfd97bfe541ab5bf12dec916 Mon Sep 17 00:00:00 2001
From: borntohonk <6264306+borntohonk@users.noreply.github.com>
Date: Wed, 19 Nov 2025 07:53:05 +0100
Subject: [PATCH 43/45] fix optional erpt-cond
---
sysmod/src/main.cpp | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/sysmod/src/main.cpp b/sysmod/src/main.cpp
index 93838b5..457b9ce 100644
--- a/sysmod/src/main.cpp
+++ b/sysmod/src/main.cpp
@@ -126,6 +126,10 @@ struct PatchEntry {
const u32 max_fw_ver{FW_VER_ANY}; // set to FW_VER_ANY to ignore
};
+constexpr auto sub_cond(u32 inst) -> bool {
+ const auto type = inst >> 24;
+ return type == 0xD1; // sub sp, sp, #0x150
+}
constexpr auto cmp_cond(u32 inst) -> bool {
const auto type = inst >> 24;
@@ -288,7 +292,7 @@ constinit Patterns ldr_patterns[] = {
};
constinit Patterns erpt_patterns[] = {
- { "no_erpt", "0xFD7B02A9FD830091F76305A9", -4, 0, stp_cond, erpt_patch, erpt_applied, false },
+ { "no_erpt", "0x...D1FD7B02A9FD830091F76305A9", 0, 0, sub_cond, erpt_patch, erpt_applied, false }, // FF4305D1 - sub sp, sp, #0x150 patched to E0031F2AC0035FD6 - mov w0, wzr, ret
};
constinit Patterns es_patterns[] = {
From 203c1c012e7209d6553b771bfb73ed8ff08e68d6 Mon Sep 17 00:00:00 2001
From: borntohonk <6264306+borntohonk@users.noreply.github.com>
Date: Tue, 25 Nov 2025 08:58:33 +0100
Subject: [PATCH 44/45] refactor conds, patterns, and remove ssl patches, add
new olsc patch
---
Makefile | 2 +-
overlay/src/main.cpp | 90 +++++++++++-----------
sysmod/src/main.cpp | 172 ++++++++++++++++---------------------------
3 files changed, 112 insertions(+), 152 deletions(-)
diff --git a/Makefile b/Makefile
index e752ef4..f760ec7 100644
--- a/Makefile
+++ b/Makefile
@@ -2,7 +2,7 @@ MAKEFILES := sysmod overlay
TARGETS := $(foreach dir,$(MAKEFILES),$(CURDIR)/$(dir))
# the below was taken from atmosphere + switch-examples makefile
-export VERSION := 1.5.8
+export VERSION := 1.5.9
ifneq ($(strip $(shell git symbolic-ref --short HEAD 2>/dev/null)),)
export GIT_BRANCH := $(shell git symbolic-ref --short HEAD)
diff --git a/overlay/src/main.cpp b/overlay/src/main.cpp
index 4839405..eb44735 100644
--- a/overlay/src/main.cpp
+++ b/overlay/src/main.cpp
@@ -99,65 +99,69 @@ class GuiToggle final : public tsl::Gui {
auto list = new tsl::elm::List();
list->addItem(new tsl::elm::CategoryHeader("FS - 0100000000000000"));
- list->addItem(config_noacidsigchk1.create_list_item("noacidsigchk1"));
- list->addItem(config_noacidsigchk2.create_list_item("noacidsigchk2"));
- list->addItem(config_noncasigchk_old.create_list_item("noncasigchk_old"));
- list->addItem(config_noncasigchk_old2.create_list_item("noncasigchk_old2"));
- list->addItem(config_noncasigchk_new.create_list_item("noncasigchk_new"));
- list->addItem(config_nocntchk.create_list_item("nocntchk"));
- list->addItem(config_nocntchk2.create_list_item("nocntchk2"));
+ list->addItem(config_noacidsigchk1.create_list_item("noacidsigchk_1.0.0-9.2.0"));
+ list->addItem(config_noacidsigchk2.create_list_item("noacidsigchk_1.0.0-9.2.0"));
+ list->addItem(config_noncasigchk1.create_list_item("noncasigchk_10.0.0-16.1.0"));
+ list->addItem(config_noncasigchk2.create_list_item("noncasigchk_17.0.0+"));
+ list->addItem(config_nocntchk1.create_list_item("nocntchk_10.0.0-18.1.0"));
+ list->addItem(config_nocntchk2.create_list_item("nocntchk_19.0.0-20.5.0"));
+ list->addItem(config_nocntchk3.create_list_item("nocntchk_21.0.0+"));
list->addItem(new tsl::elm::CategoryHeader("LDR - 0100000000000001"));
- list->addItem(config_noacidsigchk.create_list_item("noacidsigchk"));
+ list->addItem(config_noacidsigchk3.create_list_item("noacidsigchk_10.0.0+"));
list->addItem(new tsl::elm::CategoryHeader("ERPT - 010000000000002B"));
list->addItem(config_no_erpt.create_list_item("no_erpt"));
list->addItem(new tsl::elm::CategoryHeader("ES - 0100000000000033"));
- list->addItem(config_es1.create_list_item("es1"));
- list->addItem(config_es2.create_list_item("es2"));
- list->addItem(config_es3.create_list_item("es3"));
- list->addItem(config_es4.create_list_item("es4"));
+ list->addItem(config_es1.create_list_item("es_1.0.0-8.1.1"));
+ list->addItem(config_es2.create_list_item("es_9.0.0-11.0.1"));
+ list->addItem(config_es3.create_list_item("es_12.0.0-18.1.0"));
+ list->addItem(config_es4.create_list_item("es_19.0.0+"));
+
+ list->addItem(new tsl::elm::CategoryHeader("OLSC - 010000000000003E"));
+ list->addItem(config_olsc1.create_list_item("olsc_6.0.0-14.1.2"));
+ list->addItem(config_olsc2.create_list_item("olsc_15.0.0-18.1.0"));
+ list->addItem(config_olsc3.create_list_item("olsc_19.0.0+"));
list->addItem(new tsl::elm::CategoryHeader("NIFM - 010000000000000F"));
- list->addItem(config_ctest.create_list_item("ctest"));
- list->addItem(config_ctest2.create_list_item("ctest2"));
- list->addItem(config_ctest3.create_list_item("ctest3"));
+ list->addItem(config_ctest1.create_list_item("ctest_1.0.0-19.0.1"));
+ list->addItem(config_ctest2.create_list_item("ctest_20.0.0+"));
list->addItem(new tsl::elm::CategoryHeader("NIM - 0100000000000025"));
- list->addItem(config_nim_old.create_list_item("nim_old"));
- list->addItem(config_nim_new.create_list_item("nim_new"));
-
- list->addItem(new tsl::elm::CategoryHeader("Disable CA Verification - apply all"));
- list->addItem(config_ssl1.create_list_item("disablecaverification1"));
- list->addItem(config_ssl2.create_list_item("disablecaverification2"));
- list->addItem(config_ssl3.create_list_item("disablecaverification3"));
+ list->addItem(config_nim1.create_list_item("blankcal0crashfix_17.0.0+"));
+ list->addItem(config_nim_fw1.create_list_item("blockfirmwareupdates_1.0.0-5.1.0"));
+ list->addItem(config_nim_fw2.create_list_item("blockfirmwareupdates_6.0.0-6.2.0"));
+ list->addItem(config_nim_fw3.create_list_item("blockfirmwareupdates_7.0.0-11.0.1"));
+ list->addItem(config_nim_fw4.create_list_item("blockfirmwareupdates_12.0.0+"));
frame->setContent(list);
return frame;
}
- ConfigEntry config_noacidsigchk1{"fs", "noacidsigchk1", true};
- ConfigEntry config_noacidsigchk2{"fs", "noacidsigchk2", true};
- ConfigEntry config_noncasigchk_old{"fs", "noncasigchk_old", true};
- ConfigEntry config_noncasigchk_old2{"fs", "noncasigchk_old2", true};
- ConfigEntry config_noncasigchk_new{"fs", "noncasigchk_new", true};
- ConfigEntry config_nocntchk{"fs", "nocntchk", true};
- ConfigEntry config_nocntchk2{"fs", "nocntchk2", true};
- ConfigEntry config_noacidsigchk{"ldr", "noacidsigchk", true};
- ConfigEntry config_no_erpt{"erpt", "no_erpt", false};
- ConfigEntry config_es1{"es", "es1", true};
- ConfigEntry config_es2{"es", "es2", true};
- ConfigEntry config_es3{"es", "es3", true};
- ConfigEntry config_es4{"es", "es4", true};
- ConfigEntry config_ctest{"nifm", "ctest", true};
- ConfigEntry config_ctest2{"nifm", "ctest2", true};
- ConfigEntry config_ctest3{"nifm", "ctest3", true};
- ConfigEntry config_nim_old{"nim_old", "nim_old", true};
- ConfigEntry config_nim_new{"nim_new", "nim_new", true};
- ConfigEntry config_ssl1{"ssl", "disablecaverification1", false};
- ConfigEntry config_ssl2{"ssl", "disablecaverification2", false};
- ConfigEntry config_ssl3{"ssl", "disablecaverification3", false};
+ ConfigEntry config_noacidsigchk1{"fs", "noacidsigchk_1.0.0-9.2.0", true};
+ ConfigEntry config_noacidsigchk2{"fs", "noacidsigchk_1.0.0-9.2.0", true};
+ ConfigEntry config_noncasigchk1{"fs", "noncasigchk_10.0.0-16.1.0", true};
+ ConfigEntry config_noncasigchk2{"fs", "noncasigchk_17.0.0+", true};
+ ConfigEntry config_nocntchk1{"fs", "nocntchk_10.0.0-18.1.0", true};
+ ConfigEntry config_nocntchk2{"fs", "nocntchk_19.0.0-20.5.0", true};
+ ConfigEntry config_nocntchk3{"fs", "nocntchk_21.0.0+", true};
+ ConfigEntry config_noacidsigchk3{"ldr", "noacidsigchk_10.0.0+", true};
+ ConfigEntry config_no_erpt{"erpt", "no_erpt", true};
+ ConfigEntry config_es1{"es", "es_1.0.0-8.1.1", true};
+ ConfigEntry config_es2{"es", "es_9.0.0-11.0.1", true};
+ ConfigEntry config_es3{"es", "es_12.0.0-18.1.0", true};
+ ConfigEntry config_es4{"es", "es_19.0.0+", true};
+ ConfigEntry config_olsc1{"olsc", "olsc_6.0.0-14.1.2", true};
+ ConfigEntry config_olsc2{"olsc", "olsc_15.0.0-18.1.0", true};
+ ConfigEntry config_olsc3{"olsc", "olsc_19.0.0+", true};
+ ConfigEntry config_ctest1{"nifm", "ctest_1.0.0-19.0.1", true};
+ ConfigEntry config_ctest2{"nifm", "ctest_20.0.0+", true};
+ ConfigEntry config_nim1{"nim", "blankcal0crashfix_17.0.0+", true};
+ ConfigEntry config_nim_fw1{"nim", "blockfirmwareupdates_1.0.0-5.1.0", true};
+ ConfigEntry config_nim_fw2{"nim", "blockfirmwareupdates_6.0.0-6.2.0", true};
+ ConfigEntry config_nim_fw3{"nim", "blockfirmwareupdates_7.0.0-11.0.1", true};
+ ConfigEntry config_nim_fw4{"nim", "blockfirmwareupdates_12.0.0+", true};
};
class GuiLog final : public tsl::Gui {
diff --git a/sysmod/src/main.cpp b/sysmod/src/main.cpp
index 457b9ce..22eba73 100644
--- a/sysmod/src/main.cpp
+++ b/sysmod/src/main.cpp
@@ -63,7 +63,7 @@ struct PatternData {
str2hex(s, data, size);
}
- u16 data[44]{}; // reasonable max pattern length, adjust as needed
+ u16 data[60]{}; // reasonable max pattern length, adjust as needed
u8 size{};
};
@@ -126,6 +126,11 @@ struct PatchEntry {
const u32 max_fw_ver{FW_VER_ANY}; // set to FW_VER_ANY to ignore
};
+// naming convention should if possible adhere to either an arm instruction + _cond,
+// example: "bl_cond"
+// or naming it specific to what is being patched, and including all possible bytes within the address being tested for the given patch.
+// example: "ctest_cond"
+
constexpr auto sub_cond(u32 inst) -> bool {
const auto type = inst >> 24;
return type == 0xD1; // sub sp, sp, #0x150
@@ -133,106 +138,71 @@ constexpr auto sub_cond(u32 inst) -> bool {
constexpr auto cmp_cond(u32 inst) -> bool {
const auto type = inst >> 24;
- return type == 0x6B; // cmp w0, w1
+ return type == 0x6B || // cmp w0, w1
+ type == 0xF1; // cmp x0, #0x1
}
constexpr auto bl_cond(u32 inst) -> bool {
const auto type = inst >> 24;
- return type == 0x25 || type == 0x94;
+ return type == 0x25 ||
+ type == 0x94 ||
+ type == 0x97;
}
constexpr auto tbz_cond(u32 inst) -> bool {
return ((inst >> 24) & 0x7F) == 0x36;
}
-
-constexpr auto cbz_cond(u32 inst) -> bool {
- const auto type = inst >> 24;
- return type == 0x34 || type == 0xB4;
-}
-
-constexpr auto mov_cond(u32 inst) -> bool {
- return ((inst >> 24) & 0x7F) == 0x52;
-}
-
-constexpr auto mov2_cond(u32 inst) -> bool {
- if (hosversionBefore(12,0,0) || !hosversionBefore(15,0,0)) {
- return (inst >> 24) == 0x2A; // mov x0, x20
- } else {
- return (inst >> 24) == 0x92; // and x0, x19, #0xffffffff
- }
-}
-
-constexpr auto mov3_cond(u32 inst) -> bool {
- return (inst >> 24) == 0xD2; // mov x10, #0x3
-}
-
-constexpr auto and_cond(u32 inst) -> bool {
- return ((inst >> 24) & 0x1F) == 0x0A;
-}
-
constexpr auto adr_cond(u32 inst) -> bool {
return (inst >> 24) == 0x10; // adr x2, LAB
}
-constexpr auto bne_cond(u32 inst) -> bool {
+constexpr auto block_fw_updates_cond(u32 inst) -> bool {
const auto type = inst >> 24;
- const auto cond = inst & 0x10;
- return type == 0x54 || cond == 0x0;
-}
-
-constexpr auto beq_cond(u32 inst) -> bool {
- return (inst >> 24) == 0x54; // beq, 0x710011c94c
+ return type == 0xA8 ||
+ type == 0xA9 ||
+ type == 0xF8 ||
+ type == 0xF9;
}
-constexpr auto str_cond(u32 inst) -> bool {
- return (inst >> 24) == 0xB9; // str, w8,[x19, #0x15c]
+constexpr auto es_cond(u32 inst) -> bool {
+ const auto type = inst >> 24;
+ return type == 0xD1 ||
+ type == 0xA9 ||
+ type == 0xAA ||
+ type == 0x2A ||
+ type == 0x92;
}
constexpr auto ctest_cond(u32 inst) -> bool {
- return std::byteswap(0xF50301AA) == inst; // mov x21, x1
-}
-
-constexpr auto b_cond(u32 inst) -> bool {
const auto type = inst >> 24;
- return type == 0x14 || type == 0x17;
+ return type == 0xF9 ||
+ type == 0xA9 ||
+ type == 0xF8;
}
-constexpr auto stp_cond(u32 inst) -> bool {
- return (inst >> 24) == 0xA9; // stp x29, x30, [sp, #-0x30]!
-}
// to view patches, use https://armconverter.com/?lock=arm64
constexpr PatchData ret0_patch_data{ "0xE0031F2A" };
-constexpr PatchData ret1_patch_data{ "0x10000014" };
-constexpr PatchData erpt_patch_data{ "0xE0031F2AC0035FD6" };
+constexpr PatchData ret1_patch_data{ "0x200080D2" };
+constexpr PatchData mov0_ret_patch_data{ "0xE0031F2AC0035FD6" };
constexpr PatchData nop_patch_data{ "0x1F2003D5" };
//mov x0, xzr
constexpr PatchData mov0_patch_data{ "0xE0031FAA" };
//mov x2, xzr
constexpr PatchData mov2_patch_data{ "0xE2031FAA" };
constexpr PatchData cmp_patch_data{ "0x00" };
-constexpr PatchData ssl1_patch_data{ "0x0A" };
-constexpr PatchData ssl2_patch_data{ "0x08008052" };
constexpr PatchData ctest_patch_data{ "0x00309AD2001EA1F2610100D4E0031FAAC0035FD6" };
constexpr auto ret0_patch(u32 inst) -> PatchData { return ret0_patch_data; }
constexpr auto ret1_patch(u32 inst) -> PatchData { return ret1_patch_data; }
-constexpr auto erpt_patch(u32 inst) -> PatchData { return erpt_patch_data; }
+constexpr auto mov0_ret_patch(u32 inst) -> PatchData { return mov0_ret_patch_data; }
constexpr auto nop_patch(u32 inst) -> PatchData { return nop_patch_data; }
constexpr auto mov0_patch(u32 inst) -> PatchData { return mov0_patch_data; }
constexpr auto mov2_patch(u32 inst) -> PatchData { return mov2_patch_data; }
constexpr auto cmp_patch(u32 inst) -> PatchData { return cmp_patch_data; }
-constexpr auto ssl1_patch(u32 inst) -> PatchData { return ssl1_patch_data; }
-constexpr auto ssl2_patch(u32 inst) -> PatchData { return ssl2_patch_data; }
constexpr auto ctest_patch(u32 inst) -> PatchData { return ctest_patch_data; }
-constexpr auto b_patch(u32 inst) -> PatchData {
- const u32 opcode = 0x14 << 24;
- const u32 offset = (inst >> 5) & 0x7FFFF;
- return opcode | offset;
-}
-
constexpr auto ret0_applied(const u8* data, u32 inst) -> bool {
return ret0_patch(inst).cmp(data);
}
@@ -249,12 +219,8 @@ constexpr auto cmp_applied(const u8* data, u32 inst) -> bool {
return cmp_patch(inst).cmp(data);
}
-constexpr auto erpt_applied(const u8* data, u32 inst) -> bool {
- return erpt_patch(inst).cmp(data);
-}
-
-constexpr auto b_applied(const u8* data, u32 inst) -> bool {
- return 0x14 == (inst >> 24);
+constexpr auto mov0_ret_applied(const u8* data, u32 inst) -> bool {
+ return mov0_ret_patch(inst).cmp(data);
}
constexpr auto mov0_applied(const u8* data, u32 inst) -> bool {
@@ -265,58 +231,52 @@ constexpr auto mov2_applied(const u8* data, u32 inst) -> bool {
return mov2_patch(inst).cmp(data);
}
-constexpr auto ssl1_applied(const u8* data, u32 inst) -> bool {
- return ssl1_patch(inst).cmp(data);
-}
-
-constexpr auto ssl2_applied(const u8* data, u32 inst) -> bool {
- return ssl2_patch(inst).cmp(data);
-}
-
constexpr auto ctest_applied(const u8* data, u32 inst) -> bool {
return ctest_patch(inst).cmp(data);
}
constinit Patterns fs_patterns[] = {
- { "noacidsigchk1", "0xC8FE4739", -24, 0, bl_cond, ret0_patch, ret0_applied, true, FW_VER_ANY, MAKEHOSVERSION(9,2,0) },
- { "noacidsigchk2", "0x0210911F000072", -5, 0, bl_cond, ret0_patch, ret0_applied, true, FW_VER_ANY, MAKEHOSVERSION(9,2,0) },
- { "noncasigchk_old", "0x0036.......71..0054..4839", -2, 0, tbz_cond, nop_patch, nop_applied, true, MAKEHOSVERSION(10,0,0), MAKEHOSVERSION(16,1,0) },
- { "noncasigchk_old2", "0x.94..0036.258052", 2, 0, tbz_cond, nop_patch, nop_applied, true, MAKEHOSVERSION(17,0,0), MAKEHOSVERSION(20,5,0) }, // 17.0.0 - 20.5.0
- { "noncasigchk_new", "0x.94..0036.........258052", 2, 0, tbz_cond, nop_patch, nop_applied, true, MAKEHOSVERSION(21,0,0), FW_VER_ANY }, // 21.0.0+
- { "nocntchk", "0x40f9...9408.0012.050071", 2, 0, bl_cond, ret0_patch, ret0_applied, true, MAKEHOSVERSION(10,0,0), MAKEHOSVERSION(18,1,0) },
- { "nocntchk2", "0x40f9...94..40b9..0012", 2, 0, bl_cond, ret0_patch, ret0_applied, true, MAKEHOSVERSION(19,0,0), FW_VER_ANY },
+ { "noacidsigchk_1.0.0-9.2.0", "0xC8FE4739", -24, 0, bl_cond, ret0_patch, ret0_applied, true, FW_VER_ANY, MAKEHOSVERSION(9,2,0) }, // moved to loader 10.0.0
+ { "noacidsigchk_1.0.0-9.2.0", "0x0210911F000072", -5, 0, bl_cond, ret0_patch, ret0_applied, true, FW_VER_ANY, MAKEHOSVERSION(9,2,0) }, // moved to loader 10.0.0
+ { "noncasigchk_10.0.0-16.1.0", "0x1E48391F.0071..0054", -17, 0, tbz_cond, nop_patch, nop_applied, true, MAKEHOSVERSION(10,0,0), MAKEHOSVERSION(16,1,0) },
+ { "noncasigchk_17.0.0+", "0x0694..00.42.0091", -18, 0, tbz_cond, nop_patch, nop_applied, true, MAKEHOSVERSION(17,0,0), FW_VER_ANY },
+ { "nocntchk_10.0.0-18.1.0", "0x00..0240F9....08.....00...00...0037", 6, 0, bl_cond, ret0_patch, ret0_applied, true, MAKEHOSVERSION(10,0,0), MAKEHOSVERSION(18,1,0) },
+ { "nocntchk_19.0.0-20.5.0", "0x00..0240F9....08.....00...00...0054", 6, 0, bl_cond, ret0_patch, ret0_applied, true, MAKEHOSVERSION(19,0,0), MAKEHOSVERSION(20,5,0) },
+ { "nocntchk_21.0.0+", "0x00..0240F9....E8.....00...00...0054", 6, 0, bl_cond, ret0_patch, ret0_applied, true, MAKEHOSVERSION(21,0,0), FW_VER_ANY },
};
constinit Patterns ldr_patterns[] = {
- { "noacidsigchk", "009401C0BE121F00", 6, 2, cmp_cond, cmp_patch, cmp_applied, true, FW_VER_ANY }, // 1F00016B - cmp w0, w1 patched to 1F00006B - cmp w0, w0
+ { "noacidsigchk_10.0.0+", "0x009401C0BE121F00", 6, 2, cmp_cond, cmp_patch, cmp_applied, true, FW_VER_ANY }, // 1F00016B - cmp w0, w1 patched to 1F00006B - cmp w0, w0
};
constinit Patterns erpt_patterns[] = {
- { "no_erpt", "0x...D1FD7B02A9FD830091F76305A9", 0, 0, sub_cond, erpt_patch, erpt_applied, false }, // FF4305D1 - sub sp, sp, #0x150 patched to E0031F2AC0035FD6 - mov w0, wzr, ret
+ { "no_erpt", "0x...D1FD7B02A9FD830091F76305A9", 0, 0, sub_cond, mov0_ret_patch, mov0_ret_applied, true, FW_VER_ANY }, // FF4305D1 - sub sp, sp, #0x150 patched to E0031F2AC0035FD6 - mov w0, wzr, ret
};
constinit Patterns es_patterns[] = {
- { "es1", "0x..00.....e0.0091..0094..4092...d1", 16, 0, and_cond, mov0_patch, mov0_applied, true, FW_VER_ANY, MAKEHOSVERSION(1,0,0) },
- { "es2", "0x..00.....e0.0091..0094..4092...a9", 16, 0, and_cond, mov0_patch, mov0_applied, true, MAKEHOSVERSION(2,0,0), MAKEHOSVERSION(8,1,1) },
- { "es3", "0x..00...0094a0..d1..ff97.......a9", 16, 0, mov2_cond, mov0_patch, mov0_applied, true, MAKEHOSVERSION(9,0,0), MAKEHOSVERSION(20,5,0) }, //9.0.0 - 20.5.0
- { "es4", "0x..00....97a0..d1...97e003132a...a9", 16, 0, mov2_cond, mov0_patch, mov0_applied, true, MAKEHOSVERSION(21,0,0), FW_VER_ANY }, //21.0.0+
+ { "es_1.0.0-8.1.1", "0x....E8.00...FF97.0300AA..00.....E0.0091..0094.7E4092.......A9", 36, 0, es_cond, mov0_patch, mov0_applied, true, MAKEHOSVERSION(1,0,0), MAKEHOSVERSION(8,1,1) },
+ { "es_9.0.0-11.0.1", "0x00...............00.....A0..D1...97.......A9", 30, 0, es_cond, mov0_patch, mov0_applied, true, MAKEHOSVERSION(9,0,0), MAKEHOSVERSION(11,0,1) },
+ { "es_12.0.0-18.1.0", "0x02.00...........00...00.....A0..D1...97.......A9", 32, 0, es_cond, mov0_patch, mov0_applied, true, MAKEHOSVERSION(12,0,0), MAKEHOSVERSION(18,1,0) },
+ { "es_19.0.0+", "0xA1.00...........00...00.....A0..D1...97.......A9", 32, 0, es_cond, mov0_patch, mov0_applied, true, MAKEHOSVERSION(19,0,0), FW_VER_ANY },
};
-constinit Patterns nifm_patterns[] = {
- { "ctest", "....................F40300AA....F30314AAE00314AA9F0201397F8E04F8", 16, -16, ctest_cond, ctest_patch, ctest_applied, true, FW_VER_ANY, MAKEHOSVERSION(18,1,0) }, // 1.0.0 - 18.1.0
- { "ctest2", "14...........91...........97...............14", 41, 0, stp_cond, ctest_patch, ctest_applied, true, MAKEHOSVERSION(19,0,0), MAKEHOSVERSION(20,5,0) }, //19.0.0 - 20.5.0
- { "ctest3", "14...........91...........97...............14", 49, 0, stp_cond, ctest_patch, ctest_applied, true, MAKEHOSVERSION(21,0,0), FW_VER_ANY }, //21.0.0
+constinit Patterns olsc_patterns[] = {
+ { "olsc_6.0.0-14.1.2", "0x00.73..F968024039..00...00", 42, 0, bl_cond, ret1_patch, ret1_applied, true, MAKEHOSVERSION(6,0,0), MAKEHOSVERSION(14,1,2) },
+ { "olsc_15.0.0-18.1.0", "0x00.73..F968024039..00...00", 38, 0, bl_cond, ret1_patch, ret1_applied, true, MAKEHOSVERSION(15,0,0), MAKEHOSVERSION(18,1,0) },
+ { "olsc_19.0.0+", "0x00.73..F968024039..00...00", 42, 0, bl_cond, ret1_patch, ret1_applied, true, MAKEHOSVERSION(19,0,0), FW_VER_ANY },
};
-constinit Patterns nim_patterns[] = {
- { "nim_old", "0x.0F00351F2003D5", 8, 0, adr_cond, mov2_patch, mov2_applied, true, MAKEHOSVERSION(17,0,0), MAKEHOSVERSION(20,5,0) },
- { "nim_new", "0x.0700351F2003D5", 8, 0, adr_cond, mov2_patch, mov2_applied, true, MAKEHOSVERSION(21,0,0), FW_VER_ANY },
+constinit Patterns nifm_patterns[] = {
+ { "ctest_1.0.0-19.0.1", "0x03.AAE003.AA...39..04F8....E0", -29, 0, ctest_cond, ctest_patch, ctest_applied, true, FW_VER_ANY, MAKEHOSVERSION(18,1,0) },
+ { "ctest_20.0.0+", "0x03.AA...AA.........0314AA..14AA", -17, 0, ctest_cond, ctest_patch, ctest_applied, true, MAKEHOSVERSION(20,0,0), FW_VER_ANY },
};
-constinit Patterns ssl_patterns[] = {
- { "disablecaverification1", "0x6A0080D2", 0, 0, mov3_cond, ssl1_patch, ssl1_applied, false, FW_VER_ANY },
- { "disablecaverification2", "0x2409437AA0000054", 4, 0, beq_cond, ret1_patch, ret1_applied, false, FW_VER_ANY },
- { "disablecaverification3", "0x88160012", 4, 0, str_cond, ssl2_patch, ssl2_applied, false, FW_VER_ANY },
+constinit Patterns nim_patterns[] = {
+ { "blankcal0crashfix_17.0.0+", "0x00351F2003D5...............97..0094..00.....61", 6, 0, adr_cond, mov2_patch, mov2_applied, true, MAKEHOSVERSION(17,0,0), FW_VER_ANY },
+ { "blockfirmwareupdates_1.0.0-5.1.0", "0x1139F30301AA81.40F9E0.1191", -30, 0, block_fw_updates_cond, mov0_ret_patch, mov0_ret_applied, true, MAKEHOSVERSION(1,0,0), MAKEHOSVERSION(5,1,0) },
+ { "blockfirmwareupdates_6.0.0-6.2.0", "0xF30301AA.4E40F9E0..91", -40, 0, block_fw_updates_cond, mov0_ret_patch, mov0_ret_applied, true, MAKEHOSVERSION(6,0,0), MAKEHOSVERSION(6,2,0) },
+ { "blockfirmwareupdates_7.0.0-11.0.1", "0xF30301AA014C40F9F40300AAE0..91", -36, 0, block_fw_updates_cond, mov0_ret_patch, mov0_ret_applied, true, MAKEHOSVERSION(7,0,0), MAKEHOSVERSION(11,0,1) },
+ { "blockfirmwareupdates_12.0.0+", "0x280841F9084C00F9E0031F.C0035FD6", 16, 0, block_fw_updates_cond, mov0_ret_patch, mov0_ret_applied, true, MAKEHOSVERSION(12,0,0), FW_VER_ANY },
};
// NOTE: add system titles that you want to be patched to this table.
@@ -329,9 +289,10 @@ constinit PatchEntry patches[] = {
{ "erpt", 0x010000000000002B, erpt_patterns, MAKEHOSVERSION(10,0,0) },
// es was added in fw 2
{ "es", 0x0100000000000033, es_patterns, MAKEHOSVERSION(2,0,0) },
+ // olsc was added in fw 6
+ { "olsc", 0x010000000000003E, olsc_patterns, MAKEHOSVERSION(6,0,0) },
{ "nifm", 0x010000000000000F, nifm_patterns },
{ "nim", 0x0100000000000025, nim_patterns },
- { "ssl", 0x0100000000000024, ssl_patterns },
};
struct EmummcPaths {
@@ -429,6 +390,8 @@ auto apply_patch(PatchEntry& patch) -> bool {
constexpr u64 overlap_size = 0x4f;
static u8 buffer[READ_BUFFER_SIZE + overlap_size];
+ std::memset(buffer, 0, sizeof(buffer));
+
// skip if version isn't valid
if (VERSION_SKIP &&
((patch.min_fw_ver && patch.min_fw_ver > FW_VERSION) ||
@@ -466,15 +429,6 @@ auto apply_patch(PatchEntry& patch) -> bool {
continue;
}
- // u32 overlap_size = 0;
- // for (const auto& pattern : patch.patterns) {
- // overlap_size = std::max(overlap_size, static_cast(pattern.byte_pattern.size));
- // }
- // u8* buffer = (u8*)aligned_alloc(alignof(u8*), READ_BUFFER_SIZE + overlap_size);
- // if (!buffer) {
- // svcCloseHandle(handle);
- // return false;
- // }
for (u64 sz = 0; sz < mem_info.size; sz += READ_BUFFER_SIZE - overlap_size) {
const auto actual_size = std::min(READ_BUFFER_SIZE, mem_info.size - sz);
if (R_FAILED(svcReadDebugProcessMemory(buffer + overlap_size, handle, mem_info.addr + sz, actual_size))) {
@@ -483,10 +437,12 @@ auto apply_patch(PatchEntry& patch) -> bool {
patcher(handle, std::span{buffer, actual_size + overlap_size}, mem_info.addr + sz - overlap_size, patch.patterns);
if (actual_size >= overlap_size) {
memcpy(buffer, buffer + actual_size, overlap_size);
+ std::memset(buffer + overlap_size, 0, READ_BUFFER_SIZE);
+ } else {
+ std::memset(buffer, 0, sizeof(buffer));
}
}
}
- // free(buffer);
}
svcCloseHandle(handle);
return true;
From 4ddb89ea65630eb3f896fd1d78366c1a0458f853 Mon Sep 17 00:00:00 2001
From: borntohonk <6264306+borntohonk@users.noreply.github.com>
Date: Sat, 27 Dec 2025 18:45:01 +0100
Subject: [PATCH 45/45] overlap buffer
---
sysmod/src/main.cpp | 22 ++++++++++++----------
1 file changed, 12 insertions(+), 10 deletions(-)
diff --git a/sysmod/src/main.cpp b/sysmod/src/main.cpp
index 22eba73..a542164 100644
--- a/sysmod/src/main.cpp
+++ b/sysmod/src/main.cpp
@@ -314,7 +314,7 @@ auto is_emummc() -> bool {
return (paths.unk[0] != '\0') || (paths.nintendo[0] != '\0');
}
-void patcher(Handle handle, std::span data, u64 addr, std::span patterns) {
+void patcher(Handle handle, const u8* data, size_t data_size, u64 addr, std::span patterns) {
for (auto& p : patterns) {
// skip if disabled (controller by config.ini)
if (p.result == PatchResult::DISABLED) {
@@ -336,8 +336,8 @@ void patcher(Handle handle, std::span data, u64 addr, std::span= data.size()) {
+ for (u32 i = 0; i < data_size; i++) {
+ if (i + p.byte_pattern.size >= data_size) {
break;
}
@@ -356,22 +356,22 @@ void patcher(Handle handle, std::span data, u64 addr, std::span bool {
if (R_FAILED(svcReadDebugProcessMemory(buffer + overlap_size, handle, mem_info.addr + sz, actual_size))) {
break;
} else {
- patcher(handle, std::span{buffer, actual_size + overlap_size}, mem_info.addr + sz - overlap_size, patch.patterns);
+ patcher(handle, buffer, actual_size + overlap_size, mem_info.addr + sz - overlap_size, patch.patterns);
if (actual_size >= overlap_size) {
- memcpy(buffer, buffer + actual_size, overlap_size);
+ memcpy(buffer, buffer + READ_BUFFER_SIZE, overlap_size);
std::memset(buffer + overlap_size, 0, READ_BUFFER_SIZE);
} else {
- std::memset(buffer, 0, sizeof(buffer));
+ const auto bytes_to_overlap = std::min(overlap_size, actual_size);
+ memcpy(buffer, buffer + READ_BUFFER_SIZE + (actual_size - bytes_to_overlap), bytes_to_overlap);
+ std::memset(buffer + bytes_to_overlap, 0, sizeof(buffer) - bytes_to_overlap);
}
}
}