From c44ee03415a9440e02de4995b9b738aaad2a96ac Mon Sep 17 00:00:00 2001 From: MikeIsAStar <99037623+MikeIsAStar@users.noreply.github.com> Date: Tue, 26 Dec 2023 13:15:00 -0500 Subject: [PATCH] [MKW] Remove the 100cc engine class from Worldwide Versus Races Closes issue #12. --- payload/import/mkwNet.hpp | 90 ++++++++++++++++++++++++++++++++++++++ payload/import/mkwUtil.hpp | 29 ++++++++++++ payload/wwfc.cpp | 1 + payload/wwfcFeature.cpp | 49 +++++++++++++++++++++ payload/wwfcSecurity.cpp | 18 +++----- 5 files changed, 174 insertions(+), 13 deletions(-) create mode 100644 payload/import/mkwUtil.hpp create mode 100644 payload/wwfcFeature.cpp diff --git a/payload/import/mkwNet.hpp b/payload/import/mkwNet.hpp index 23bf913..648acde 100644 --- a/payload/import/mkwNet.hpp +++ b/payload/import/mkwNet.hpp @@ -27,6 +27,52 @@ struct RACEPacket { static_assert(sizeof(RACEPacket) == 0x10); +class SELECTHandler +{ +public: + struct SELECTPacket { + enum EngineClass : u8 { + eNotDecided = 0, + e100cc = 1, + e150cc = 2, + eMirrorMode = 3, + }; + + /* 0x00 */ u8 _00[0x37 - 0x00]; + /* 0x37 */ EngineClass engineClass; + }; + + static_assert(sizeof(SELECTPacket) == 0x38); + + void decideEngineClass() + { + LONGCALL void decideEngineClass(SELECTHandler * selectHandler) + AT(RMCXD_PORT(0x80661A5C, 0x80659B20, 0x806610C8, 0x8064FD74)); + + decideEngineClass(s_instance); + } + + SELECTPacket* sendPacket() + { + return &m_sendPacket; + } + + static SELECTHandler* Instance() + { + return s_instance; + } + +private: + /* 0x000 */ u8 _000[0x008 - 0x000]; + /* 0x008 */ SELECTPacket m_sendPacket; + /* 0x040 */ u8 _040[0x3F8 - 0x040]; + + static SELECTHandler* s_instance + AT(RMCXD_PORT(0x809C2100, 0x809BD930, 0x809C1160, 0x809B0740)); +}; + +static_assert(sizeof(SELECTHandler) == 0x3F8); + struct USERPacket { /* 0x00 */ u32 miiGroupBitflags; /* 0x04 */ u16 miiGroupCount; @@ -48,6 +94,50 @@ struct USERPacket { static_assert(sizeof(USERPacket) == 0xC0); +class RKNetController +{ +public: + enum MatchType { + NotPlaying = 0, + WorldwideVersusRace = 1, + ContinentalVersusRace = 2, + WorldwideBattle = 3, + ContinentalBattle = 4, + Room = 5, + }; + + void + processRACEPacket(u32 playerAid, RACEPacket* racePacket, u32 packetSize) + { + LONGCALL void processRACEPacket( + RKNetController * rkNetController, u32 playerAid, + RACEPacket * racePacket, u32 packetSize + ) AT(RMCXD_PORT(0x80659A84, 0x806555FC, 0x806590F0, 0x80647D9C)); + + processRACEPacket(s_instance, playerAid, racePacket, packetSize); + } + + MatchType matchType() + { + return m_matchType; + } + + static RKNetController* Instance() + { + return s_instance; + } + +private: + /* 0x0000 */ u8 _0000[0x00E8 - 0x0000]; + /* 0x00E8 */ MatchType m_matchType; + /* 0x00EC */ u8 _00EC[0x29C8 - 0x00EC]; + + static RKNetController* s_instance + AT(RMCXD_PORT(0x809C20D8, 0x809BD918, 0x809C1138, 0x809B0718)); +}; + +static_assert(sizeof(RKNetController) == 0x29C8); + #endif } // namespace mkw::Net diff --git a/payload/import/mkwUtil.hpp b/payload/import/mkwUtil.hpp new file mode 100644 index 0000000..eab73cb --- /dev/null +++ b/payload/import/mkwUtil.hpp @@ -0,0 +1,29 @@ +#pragma once + +#include + +namespace mkw::Util +{ + +#if RMC + +class Random +{ +public: + Random* dt(Random* random, s32 type) + { + LONGCALL Random* dt(Random * random, s32 type) + AT(RMCXD_PORT(0x80555538, 0x8054F518, 0x80554EB8, 0x80543590)); + + return dt(random, type); + } + +private: + u8 _00[0x18 - 0x00]; +}; + +static_assert(sizeof(Random) == 0x18); + +#endif + +} // namespace mkw::Util diff --git a/payload/wwfc.cpp b/payload/wwfc.cpp index 0e047c2..0384631 100644 --- a/payload/wwfc.cpp +++ b/payload/wwfc.cpp @@ -1,6 +1,7 @@ #include "game/RMC.h" #include "wwfcAntiFreeze.cpp" +#include "wwfcFeature.cpp" #include "wwfcLibC.cpp" #include "wwfcLogin.cpp" #include "wwfcMii.cpp" diff --git a/payload/wwfcFeature.cpp b/payload/wwfcFeature.cpp new file mode 100644 index 0000000..19f8b28 --- /dev/null +++ b/payload/wwfcFeature.cpp @@ -0,0 +1,49 @@ +#include "import/mkwNet.hpp" +#include "import/mkwUtil.hpp" + +namespace wwfc::Feature +{ + +#if RMC + +static void DecideEngineClass(mkw::Net::SELECTHandler* selectHandler) +{ + using namespace mkw::Net; + + SELECTHandler::SELECTPacket* sendPacket = selectHandler->sendPacket(); + + if (__builtin_ppc_mftb() & 1) { + sendPacket->engineClass = + SELECTHandler::SELECTPacket::EngineClass::e150cc; + } else { + sendPacket->engineClass = + SELECTHandler::SELECTPacket::EngineClass::eMirrorMode; + } +} + +// Remove the 100cc engine class from Worldwide Versus Races +WWFC_DEFINE_PATCH = { + Patch::CallWithCTR( // + WWFC_PATCH_LEVEL_FEATURE, // + RMCXD_PORT(0x806613F8, 0x806594BC, 0x80660A64, 0x8064F710), // + [](mkw::Util::Random* random) -> void { + random->dt(random, -1); + + using namespace mkw::Net; + + RKNetController::MatchType matchType = + RKNetController::Instance()->matchType(); + SELECTHandler* selectHandler = SELECTHandler::Instance(); + + if (matchType == RKNetController::MatchType::WorldwideVersusRace) { + DecideEngineClass(selectHandler); + } else { + selectHandler->decideEngineClass(); + } + } + ), +}; + +#endif + +} // namespace wwfc::Feature diff --git a/payload/wwfcSecurity.cpp b/payload/wwfcSecurity.cpp index a865c46..c2679e3 100644 --- a/payload/wwfcSecurity.cpp +++ b/payload/wwfcSecurity.cpp @@ -222,29 +222,21 @@ static bool IsValidRACEPacket(mkw::Net::RACEPacket* packet, u32 packetSize) // by Star, who reported the exploit and then released it. // CVE-ID: CVE-2023-35856 // https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2023-35856 - WWFC_DEFINE_PATCH = {Patch::BranchWithCTR( // WWFC_PATCH_LEVEL_CRITICAL, // RMCXD_PORT(0x80658604, 0x8065417C, 0x80657C70, 0x8064691C), // - [](void* rkNetController, mkw::Net::RACEPacket* packet, u32 packetSize, - u32 _, u8 playerAid) -> void { - if (!IsValidRACEPacket(packet, packetSize)) { + [](mkw::Net::RKNetController* rkNetController, + mkw::Net::RACEPacket* racePacket, u32 packetSize, u32 _, + u8 playerAid) -> void { + if (!IsValidRACEPacket(racePacket, packetSize)) { LONGCALL int DWC_CloseConnectionHard(u8 playerAid) AT(RMCXD_PORT(0x800D2000, 0x800D1F60, 0x800D1F20, 0x800D2060)); - DWC_CloseConnectionHard(playerAid); return; } - LONGCALL void RKNetController_ProcessRACEPacket( - void* rkNetController, u8 playerAid, mkw::Net::RACEPacket* packet, - u32 packetSize - ) AT(RMCXD_PORT(0x80659A84, 0x806555FC, 0x806590F0, 0x80647D9C)); - - RKNetController_ProcessRACEPacket( - rkNetController, playerAid, packet, packetSize - ); + rkNetController->processRACEPacket(playerAid, racePacket, packetSize); } )};