feat: Add applet patches and update tooling/compile instructions

This commit is contained in:
Ash Logan 2024-12-21 17:45:55 +11:00
commit 11cde803ff
10 changed files with 162 additions and 52 deletions

View file

@ -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"

View file

@ -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)

View file

@ -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,6 +135,11 @@ $(OFILES_SRC) : $(HFILES_BIN)
@echo $(notdir $<)
@$(bin2o)
%.pem.o %_pem.h : %.pem
#-------------------------------------------------------------------------------
@echo $(notdir $<)
@$(bin2o)
-include $(DEPENDS)
#-------------------------------------------------------------------------------

View file

@ -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`.

View file

@ -16,16 +16,7 @@
#include <stdint.h>
#include <stdlib.h>
#include <wups.h>
#include <nsysnet/nssl.h>
#include <coreinit/cache.h>
#include <coreinit/dynload.h>
#include <coreinit/mcp.h>
#include <coreinit/memory.h>
#include <coreinit/memorymap.h>
#include <coreinit/memexpheap.h>
#include <coreinit/launch.h>
#include <sysapp/launch.h>
#include "wut_extra.h"
#include <utils/logger.h>
#include "patcher/ingame.h"
@ -42,7 +33,7 @@ WUPS_PLUGIN_LICENSE("ISC");
#include <kernel/kernel.h>
#include <mocha/mocha.h>
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);

View file

@ -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);
}

View file

@ -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);
}
}

View file

@ -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

View file

@ -1,27 +1,27 @@
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#include <string.h>
#include <whb/log.h>
#include <whb/log_udp.h>
#include <whb/log_cafe.h>
#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

View file

@ -1,21 +0,0 @@
#pragma once
#include <assert.h>
#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