diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3af1753..17d3147 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -6,13 +6,13 @@ jobs: build-wups: runs-on: ubuntu-22.04 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: build toolchain container run: docker build . -t builder - uses: ammaraskar/gcc-problem-matcher@master - name: build WUPS plugin run: docker run --rm -v ${PWD}:/app -w /app builder - - uses: actions/upload-artifact@master + - uses: actions/upload-artifact@v4 with: - name: plugin + name: meowth path: "*.wps" diff --git a/Dockerfile b/Dockerfile index 9dcb816..637c1db 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,8 +1,8 @@ -FROM wiiuenv/devkitppc:20220806 +FROM ghcr.io/wiiu-env/devkitppc:20241128 -COPY --from=wiiuenv/libkernel:20220724 /artifacts $DEVKITPRO -COPY --from=wiiuenv/libmocha:20220903 /artifacts $DEVKITPRO -COPY --from=wiiuenv/wiiupluginsystem:20220826 /artifacts $DEVKITPRO +COPY --from=ghcr.io/wiiu-env/libkernel:20230621 /artifacts $DEVKITPRO +COPY --from=ghcr.io/wiiu-env/libmocha:20240603 /artifacts $DEVKITPRO +COPY --from=ghcr.io/wiiu-env/wiiupluginsystem:20240505 /artifacts $DEVKITPRO WORKDIR /app CMD make -f Makefile -j$(nproc) diff --git a/Makefile b/Makefile index ad0101c..e576edb 100644 --- a/Makefile +++ b/Makefile @@ -28,11 +28,15 @@ INCLUDES := src #------------------------------------------------------------------------------- # options for code generation #------------------------------------------------------------------------------- -CFLAGS := -g -Wall -O2 -ffunction-sections \ +CFLAGS := -Wall -O2 -ffunction-sections -fdata-sections \ $(MACHDEP) CFLAGS += $(INCLUDE) -D__WIIU__ -D__WUT__ -D__WUPS__ +ifeq ($(DEBUG),1) + CFLAGS += -DDEBUG -g +endif + CXXFLAGS := $(CFLAGS) -std=c++20 ASFLAGS := -g $(ARCH) @@ -105,7 +109,7 @@ $(BUILD): #------------------------------------------------------------------------------- clean: @echo clean ... - @rm -fr $(BUILD)/* $(TARGET).wps $(TARGET).elf + @rm -fr $(BUILD) $(TARGET).wps $(TARGET).elf #------------------------------------------------------------------------------- else @@ -131,8 +135,13 @@ $(OFILES_SRC) : $(HFILES_BIN) @echo $(notdir $<) @$(bin2o) +%.pem.o %_pem.h : %.pem +#------------------------------------------------------------------------------- + @echo $(notdir $<) + @$(bin2o) + -include $(DEPENDS) #------------------------------------------------------------------------------- endif -#------------------------------------------------------------------------------- +#------------------------------------------------------------------------------- \ No newline at end of file diff --git a/README.md b/README.md index cae0a81..5893e8f 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,24 @@ ![Meowth](meowth.png?raw=true) -Since NSSL is such hot garbage, a lot of games shipped their own static version of OpenSSL. Meowth is here to disable the SSL verification in such titles. +Since NSSL is such hot garbage, a lot of games shipped their own static version of OpenSSL. +Meowth disables the SSL verification in such titles for development purposes. Based on [Inkay](https://github.com/PretendoNetwork/Inkay). + +## Compiling - Docker +Meowth's dependencies and build tooling can be handled as a container, which is generally recommended for WUPS +development. +Using `docker` or `podman`: +```shell +docker build -t meowth . +docker run --rm -v $(pwd):/app meowth make # replace "make" with any other command (make clean, etc.) +``` + +## Compiling - System +Meowth has the following dependencies: +- [WiiUPluginSystem](https://github.com/wiiu-env/WiiUPluginSystem) +- [libmocha](https://github.com/wiiu-env/libmocha) +- [libkernel](https://github.com/wiiu-env/libkernel/) + +Each of these should be `make install`-able, and then Meowth can be compiled with `make`. \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 67875d0..59a068d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -16,16 +16,7 @@ #include #include #include -#include -#include -#include #include -#include -#include -#include -#include -#include -#include "wut_extra.h" #include #include "patcher/ingame.h" @@ -42,7 +33,7 @@ WUPS_PLUGIN_LICENSE("ISC"); #include #include -static bool is555(MCP_SystemVersion version) { +static bool is555(MCPSystemVersion version) { return (version.major == 5) && (version.minor == 5) && (version.patch >= 5); } @@ -58,12 +49,12 @@ INITIALIZE_PLUGIN() { } //get os version - MCP_SystemVersion os_version; + MCPSystemVersion os_version; int mcp = MCP_Open(); int ret = MCP_GetSystemVersion(mcp, &os_version); if (ret < 0) { DEBUG_FUNCTION_LINE("getting system version failed (%d/%d)!", mcp, ret); - os_version = (MCP_SystemVersion) { + os_version = (MCPSystemVersion) { .major = 5, .minor = 5, .patch = 5, .region = 'E' }; } @@ -91,4 +82,43 @@ ON_APPLICATION_START() { RunPatcher(); } -ON_APPLICATION_ENDS() {} +// Try to hook the webkit applets fairly early - wish there was a better way to do this... + +DECL_FUNCTION(int, FSOpenFile_miiverse, FSClient *client, FSCmdBlock *block, const char *path, const char *mode, uint32_t *handle, int errorMask) { + const char *oma = "vol/content/preload.oma"; + + if (strcmp(oma, path) == 0) + { + WHBLogUdpInit(); + RunPatcher(); + } + + return real_FSOpenFile_miiverse(client, block, path, mode, handle, errorMask); +} +WUPS_MUST_REPLACE_FOR_PROCESS(FSOpenFile_miiverse, WUPS_LOADER_LIBRARY_COREINIT, FSOpenFile, WUPS_FP_TARGET_PROCESS_MIIVERSE); + +DECL_FUNCTION(int, FSOpenFile_tvii, FSClient *client, FSCmdBlock *block, const char *path, const char *mode, uint32_t *handle, int errorMask) { + const char *oma = "/vol/content/skin/Skin.dat"; + + if (strcmp(oma, path) == 0) + { + WHBLogUdpInit(); + RunPatcher(); + } + + return real_FSOpenFile_tvii(client, block, path, mode, handle, errorMask); +} +WUPS_MUST_REPLACE_FOR_PROCESS(FSOpenFile_tvii, WUPS_LOADER_LIBRARY_COREINIT, FSOpenFile, WUPS_FP_TARGET_PROCESS_TVII); + +DECL_FUNCTION(int, FSOpenFile_eshop, FSClient *client, FSCmdBlock *block, const char *path, const char *mode, uint32_t *handle, int errorMask) { + const char *oma = "vol/content/preload.oma"; + + if (strcmp(oma, path) == 0) + { + WHBLogUdpInit(); + RunPatcher(); + } + + return real_FSOpenFile_eshop(client, block, path, mode, handle, errorMask); +} +WUPS_MUST_REPLACE_FOR_PROCESS(FSOpenFile_eshop, WUPS_LOADER_LIBRARY_COREINIT, FSOpenFile, WUPS_FP_TARGET_PROCESS_ESHOP); diff --git a/src/patcher/ingame.cpp b/src/patcher/ingame.cpp index c64ef12..2ca7f2e 100644 --- a/src/patcher/ingame.cpp +++ b/src/patcher/ingame.cpp @@ -21,6 +21,7 @@ #include "patches/youtube.h" #include "patches/just_dance.h" #include "patches/watch_dogs.h" +#include "patches/webkit_applets.h" void RunPatcher() { auto orplinfo = TryGetRPLInfo(); @@ -57,4 +58,5 @@ void RunPatcher() { Patch_youtube(titleVer, titleId, rpls); Patch_just_dance(titleVer, titleId, rpls); Patch_watch_dogs(titleVer, titleId, rpls); + Patch_webkit_applets(titleVer, titleId, rpls); } diff --git a/src/patcher/patches/webkit_applets.cpp b/src/patcher/patches/webkit_applets.cpp new file mode 100644 index 0000000..d2b379e --- /dev/null +++ b/src/patcher/patches/webkit_applets.cpp @@ -0,0 +1,60 @@ +// +// Created by ash on 23/07/23. +// + +#include "webkit_applets.h" +#include "utils/logger.h" +#include "patcher/patcher.h" + +void Patch_webkit_applets(uint32_t titleVer, uint64_t titleId, const rplinfo& rpls) +{ + if ((titleId == 0x00050010'1004B000 && titleVer == 65) || + (titleId == 0x00050010'1004B100 && titleVer == 65) || + (titleId == 0x00050010'1004B200 && titleVer == 65)) + { + // libopenssl is identical between all regions + auto rpx = FindRPL(rpls, "libopenssl.rpl"); + if (!rpx) return; + + DEBUG_FUNCTION_LINE("Detected NNID Settings v%d - patching...", titleVer); + // OpenSSL ssl_verify_cert_chain + PatchInstruction((void*)(rpx->textAddr + 0x0005c138), 0x40820020, 0x60000000); + PatchInstruction((void*)(rpx->textAddr + 0x0005c150), 0x38600000, 0x38600001); + } + else if ((titleId == 0x00050030'1001600A && titleVer == 113) || + (titleId == 0x00050030'1001610A && titleVer == 113) || + (titleId == 0x00050030'1001620A && titleVer == 113)) + { + auto rpx = FindRPL(rpls, "libopenssl.rpl"); + if (!rpx) return; + + DEBUG_FUNCTION_LINE("Detected Miiverse Applet v%d - patching...", titleVer); + // OpenSSL ssl_verify_cert_chain + PatchInstruction((void*)(rpx->textAddr + 0x00043c80), 0x40820020, 0x60000000); + PatchInstruction((void*)(rpx->textAddr + 0x00043c98), 0x38600000, 0x38600001); + } + else if ((titleId == 0x00050030'1001400A && titleVer == 131) || + (titleId == 0x00050030'1001410A && titleVer == 131) || + (titleId == 0x00050030'1001420A && titleVer == 131)) + { + auto rpx = FindRPL(rpls, "libopenssl.rpl"); + if (!rpx) return; + + DEBUG_FUNCTION_LINE("Detected Nintendo eShop v%d - patching...", titleVer); + // OpenSSL ssl_verify_cert_chain + PatchInstruction((void*)(rpx->textAddr + 0x00043c80), 0x40820020, 0x60000000); + PatchInstruction((void*)(rpx->textAddr + 0x00043c98), 0x38600000, 0x38600001); + } + else if ((titleId == 0x00050030'1001300A && titleVer == 81) || + (titleId == 0x00050030'1001310A && titleVer == 81) || + (titleId == 0x00050030'1001320A && titleVer == 81)) + { + auto rpx = FindRPL(rpls, "libopenssl.rpl"); + if (!rpx) return; + + DEBUG_FUNCTION_LINE("Detected Nintendo TVii v%d - patching...", titleVer); + // OpenSSL ssl_verify_cert_chain + PatchInstruction((void*)(rpx->textAddr + 0x00042ee4), 0x40820020, 0x60000000); + PatchInstruction((void*)(rpx->textAddr + 0x00042efc), 0x38600000, 0x38600001); + } +} diff --git a/src/patcher/patches/webkit_applets.h b/src/patcher/patches/webkit_applets.h new file mode 100644 index 0000000..b26ca0d --- /dev/null +++ b/src/patcher/patches/webkit_applets.h @@ -0,0 +1,12 @@ +// +// Created by ash on 23/07/23. +// + +#ifndef MEOWTH_ACCOUNT_SETTINGS_H +#define MEOWTH_ACCOUNT_SETTINGS_H + +#include "patcher/rplinfo.h" + +void Patch_webkit_applets(uint32_t titleVer, uint64_t titleId, const rplinfo& rpls); + +#endif //MEOWTH_ACCOUNT_SETTINGS_H diff --git a/src/utils/logger.h b/src/utils/logger.h index 0b6bc1b..0c8a807 100644 --- a/src/utils/logger.h +++ b/src/utils/logger.h @@ -1,27 +1,27 @@ #pragma once -#ifdef __cplusplus -extern "C" { -#endif - #include #include #include #include +#ifdef __cplusplus +extern "C" { +#endif + #define __FILENAME_X__ (strrchr(__FILE__, '\\') ? strrchr(__FILE__, '\\') + 1 : __FILE__) #define __FILENAME__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILENAME_X__) #define OSFATAL_FUNCTION_LINE(FMT, ARGS...)do { \ - OSFatal_printf("[%s]%s@L%04d: " FMT "",__FILENAME__,__FUNCTION__, __LINE__, ## ARGS); \ + OSFatal_printf("[%s]%s@L%04d: " FMT "","Meowth",__FUNCTION__, __LINE__, ## ARGS); \ } while (0) #define DEBUG_FUNCTION_LINE(FMT, ARGS...)do { \ - WHBLogPrintf("[%23s]%30s@L%04d: " FMT "",__FILENAME__,__FUNCTION__, __LINE__, ## ARGS); \ + WHBLogPrintf("[%23s]%30s@L%04d: " FMT "","Meowth",__FUNCTION__, __LINE__, ## ARGS); \ } while (0); #define DEBUG_FUNCTION_LINE_WRITE(FMT, ARGS...)do { \ - WHBLogWritef("[%23s]%30s@L%04d: " FMT "",__FILENAME__,__FUNCTION__, __LINE__, ## ARGS); \ + WHBLogWritef("[%23s]%30s@L%04d: " FMT "","Meowth",__FUNCTION__, __LINE__, ## ARGS); \ } while (0); #ifdef __cplusplus diff --git a/src/wut_extra.h b/src/wut_extra.h deleted file mode 100644 index 1cffa35..0000000 --- a/src/wut_extra.h +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -//remove all this if wut adds it and it causes errors -typedef struct { - uint32_t major; - uint32_t minor; - uint32_t patch; - char region; -} MCP_SystemVersion; -static_assert(sizeof(MCP_SystemVersion) == 0x10); -int MCP_GetSystemVersion(int handle, MCP_SystemVersion* version); - -#ifdef __cplusplus -} -#endif