Skip to content

Commit

Permalink
Merge pull request #9 from borntohonk/master
Browse files Browse the repository at this point in the history
Contains BL cond fix, buffer change, ca_verification patches, workflow change

Combination of some PR and addition of SSL patches.
  • Loading branch information
impeeza authored Dec 4, 2024
2 parents 3de2853 + e86f471 commit 32c7757
Show file tree
Hide file tree
Showing 7 changed files with 114 additions and 95 deletions.
59 changes: 43 additions & 16 deletions .github/workflows/build-jobs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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
14 changes: 0 additions & 14 deletions .github/workflows/build.yml

This file was deleted.

38 changes: 0 additions & 38 deletions .github/workflows/release.yml

This file was deleted.

2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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.5

ifneq ($(strip $(shell git symbolic-ref --short HEAD 2>/dev/null)),)
export GIT_BRANCH := $(shell git symbolic-ref --short HEAD)
Expand Down
14 changes: 5 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
@@ -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.

---

Expand Down Expand Up @@ -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.
Expand Down
10 changes: 8 additions & 2 deletions overlay/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"));

Expand All @@ -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;
}
Expand All @@ -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};
Expand All @@ -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 {
Expand Down
72 changes: 57 additions & 15 deletions sysmod/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -169,6 +170,10 @@ constexpr auto mov2_cond(u32 inst) -> bool {
}
}

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;
}
Expand All @@ -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
}
Expand All @@ -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; }
Expand All @@ -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 {
Expand Down Expand Up @@ -243,22 +260,29 @@ 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", "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[] = {
Expand All @@ -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, 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 },
};

// NOTE: add system titles that you want to be patched to this table.
Expand All @@ -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 {
Expand Down Expand Up @@ -380,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 &&
Expand Down Expand Up @@ -419,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<u32>(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;
Expand Down

0 comments on commit 32c7757

Please sign in to comment.