Skip to content

Commit

Permalink
[MKW] Remove the 100cc engine class from Worldwide Versus Races
Browse files Browse the repository at this point in the history
Closes issue #12.
  • Loading branch information
MikeIsAStar authored and MikeIsAStar committed Dec 26, 2023
1 parent 3c0a834 commit c44ee03
Show file tree
Hide file tree
Showing 5 changed files with 174 additions and 13 deletions.
90 changes: 90 additions & 0 deletions payload/import/mkwNet.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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
29 changes: 29 additions & 0 deletions payload/import/mkwUtil.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#pragma once

#include <wwfcCommon.h>

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
1 change: 1 addition & 0 deletions payload/wwfc.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "game/RMC.h"

#include "wwfcAntiFreeze.cpp"
#include "wwfcFeature.cpp"
#include "wwfcLibC.cpp"
#include "wwfcLogin.cpp"
#include "wwfcMii.cpp"
Expand Down
49 changes: 49 additions & 0 deletions payload/wwfcFeature.cpp
Original file line number Diff line number Diff line change
@@ -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
18 changes: 5 additions & 13 deletions payload/wwfcSecurity.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
)};

Expand Down

0 comments on commit c44ee03

Please sign in to comment.