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
+Here's a quick run down of what's being patched:
-- fs
-- es
-- ldr
+- **fs**
+- **es**
+- **ldr**
+- **nifm**
-fs and es need new patches after every new fw version.
+**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.
-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.
+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.
---
-## How does it work?
+## FAQ:
-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.
+### If I am using sigpatches already, is there any point in using this?
-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 :)
+Yes, in 3 situations.
----
+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.
-## Does this mean i should stop downloading / using sigpatches?
+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**.
-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.
+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.
----
+### Does this mean that I should stop downloading / using sigpatches?
-## If i am using sigpatches already, is there any point in using this as well?
-
-Yes, in 2 niche cases.
-
-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.
-
-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
-
-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 @@ public:
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 @@ public:
} 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 @@ public:
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