OpenPayload is an open-source reimplementation of the Wiimmfi payload for Mario Kart Wii.
The Wiimmfi payload is a set of patches Wiimmfi provides to fix various game bugs and protect Mario Kart Wii players from malicious attacks. It is implemented as a binary blob that relies on security through obscurity, meaning it can easily interfere with more complex mods.
The reasons behind OpenPayload are the following:
- An open implementation allows for potential improvements and additional vetting on the patches;
- Not applying the patches at runtime means the game can connect to the server faster than it normally would;
- Features can be integrated by mods or left out entirely.
OpenPayload's code relies on the CodeWarrior compiler and the Kamek linker for hook insertion, therefore it can be easily imported into existing Kamek projects (or ported to other Wii code loaders).
Compilation instructions or compiled outputs will not be provided, as OpenPayload is meant to give more wiggle room to complex distributions rather than disrupt Wiimmfi's functionality.
OpenPayload is largely untested at the moment. Connecting to the server and creating/joining/starting a friend room are confirmed to be working, but there may be bugs still lingering. Please report any issue.
OpenPayload is opinionated, meaning that some features are not reimplemented and some others are implemented differently, in order to follow proper programming practices and provide cleaner, less bloated code.
Major features that were not ported include:
- Auto Reconnect: While the feature allows the game to remain functional during server maintenance, such a scenario usually doesn't last long enough to justify the effort required to port the code. There are also concerns about potential introduced instabilities due to the extensive modifications that were made;
- Cheat Reporting: Since these are basically self-reports that generally do not lead to a ban (the reports themselves are not accessible to moderators), these hooks have been skipped. Once in-game reporting is properly implemented on both client and server side, porting will be considered;
- Custom Error Messages: Due to this feature being prone to breakage, it has been chosen to rely on an offline set of fixed error messages instead. OpenPayload also displays the error code when the "disc error" occurs;
- Frameskip: The amount of code and its unreadability proved too much to handle. A skill issue, one could argue;
- IOS Operation Protection: This measure is extremely easy to bypass, offers no additional protection and only serves to make IOS access more annoying for mods.
Some generic functions meant to showcase potential interoperation between mods and OpenPayload have been defined in ModSupport.hpp.
The message patches applied by the WSZST-based patcher have been converted to the JSON5 format used by wuj5 and cleaned up, adding some missing translations and removing various translation errors and broken escape sequences. They can be found in assets
.
OpenPayload currently does not support modifying the login region. To do so, use this Gecko code or apply an equivalent patch for the patching framework you're using.
The table below lists all the hooks used by the original Wiimmfi payload as of v96, their purpose, the reimplementation status and any changes that were made to the original code.
The legend is as follows:
- ✅: The code for this hook has been ported
- ☑️: The code for this hook has been ported, but the hook has been moved to a different address
⚠️ : The code for this hook is currently being ported- ⏭: The code for this hook will not be ported
- ❌: The code for this hook has not been ported yet
Hook Address(es) | Category | Purpose | Status | Code | Notes/Changes |
---|---|---|---|---|---|
0x800095C4 0x800095E4 0x800095F4 |
Frameskip | Main Frameskip Function | ⏭ | N/A | Frameskip will not be implemented |
0x800CE220 |
Security Fixes | Friend Status Data Buffer Overflow Fix | ✅ | dwc_friend.cpp | N/A |
0x800CE7A4 |
NATify Fixes | Update NATify | ✅ | dwc_friend.cpp Natify.cpp |
Changed disgusting runtime hook to a fixed hook |
0x800CECB0 0x800DEA18 |
Auto Reconnect | Fix Friend Status Issues | ⏭ | N/A | Auto Reconnect will not be implemented |
0x800CECBC 0x8065A0EC |
Auto Reconnect | DWC Stub Implementation | ⏭ | N/A | Auto Reconnect will not be implemented |
0x800D01E4 |
Auto Reconnect | Fix Error 61070 | ⏭ | N/A | Auto Reconnect will not be implemented |
0x800D0598 0x800D059C 0x800D05A0 |
Bug Fixes | Error 60000 Fix | ☑️ (Branch from 0x800D05A8 to 0x800D0610 ) |
dwc_login.cpp | Ensured the data type flag is properly cleared before setting it |
0x800D086C |
NATify Fixes | Start NATify | ✅ | dwc_login.cpp natneg.cpp Natify.cpp |
|
0x800D0DD4 0x800D0DE8 |
NATNEG Fixes | Override Connected Callback | ☑️ (Moved to 0x800D0FE8 ) |
dwc_main.cpp Natneg.cpp |
What does this patch effectively do? |
0x800D13F4 |
Auto Reconnect | Allow P2P While Offline | ⏭ | N/A | Auto Reconnect will not be implemented |
0x800D1DDC 0x800D1F04 0x800D1FDC 0x800D2058 |
Auto Reconnect | Don't Close P2P Connections When Disconnecting | ⏭ | N/A | Auto Reconnect will not be implemented |
0x800D26DC 0x800D3050 0x800D3078 0x800D31A0 0x800D31BC 0x800D3624 0x800D3C38 0x800D3EA0 0x800E5680 0x80657648 0x8065764C 0x80658714 0x8065A970 |
Auto Reconnect | N/A | ⏭ | N/A | Auto Reconnect will not be implemented |
0x800D2884 |
Port Binding | Use UPNP Port for NATNEG | ✅ | dwc_main.cpp | N/A |
0x800D28CC |
NATNEG Fixes | Override Connect Attempt Callback | ✅ | dwc_main.cpp Natneg.cpp |
What does this patch effectively do? |
0x800D31C4 0x80658F7C |
NATNEG Fixes | Reattempt NATNEG Multiple Times | ☑️ (Moved respectively to 0x800D3188 and 0x80657990 ) |
dwc_main.cpp RKNetController.cpp Natneg.cpp |
N/A |
0x800D3F1C 0x800E09A8 |
NATNEG Fixes / Telemetry | Send Connection Matrix to Host and Server | ✅ | dwc_main.cpp dwc_match.cpp ConnectionMatrix.cpp |
N/A |
0x800D8354 |
NATNEG Fixes | Improved Next NATNEG Target Choosing Algorithm | ☑️ (Branch from 0x800D80D0 to 0x800D8360 and replaced instruction at 0x800D8360 ) |
dwc_match.cpp Natneg.cpp |
Removed various pointless checks and checks related to Auto Reconnect |
0x800D94F0 0x800E5980 0x800E5B14 |
NATNEG Fixes | Parse Custom Match Commands | ✅ | dwc_match.cpp Natneg.cpp |
|
0x800D9754 |
NATNEG Fixes | Parse SYN Packets in Additional States | ✅ | dwc_match.cpp | N/A |
0x800DA7D0 0x800DA7D4 0x800DA7D8 |
NATNEG Fixes | Send Failed Connection Matrix to Host | ✅ | dwc_match.cpp MatchCommand.cpp |
N/A |
0x800DBE30 |
Auto Reconnect | Handle P2P Status Messages While Offline | ⏭ | N/A | Auto Reconnect will not be implemented |
0x800DC21C |
Telemetry | Report Host Disconnections | ☑️ (Changed to three hooks at 0x800DDF40 , 0x800DE1E4 and 0x800E6A14 ) |
dwc_match.cpp Reporting.cpp |
N/A |
0x800DC49C |
Auto Reconnect | Stop People From Joining During Reconnect | ⏭ | N/A | Auto Reconnect will not be implemented |
0x800DCA18 |
NATNEG Fixes | Store Reservations in Queue | ⏭ | N/A | Patch not applied by the payload |
0x800DCEC8 0x800DCF98 0x800E57FC |
NATNEG Fixes | Send Failed Connection Matrix to Host | ⏭ | N/A | Patch not applied by the payload |
0x800E1A58 |
NATNEG Fixes | Reduce SYN-ACK Timeout Time | ✅ | dwc_match.cpp | N/A |
0x800E1CA8 |
NATNEG Fixes | Send Extra Packets on SYN-ACK Timeout | ✅ | dwc_match.cpp Natneg.cpp |
N/A |
0x800E58B8 0x800E58BC 0x800E58C8 0x800E58CC 0x800E58D0 0x800E58D8 0x800E58EC |
Security Fixes | Match Command Buffer Overflow Fix (GT2) | ☑️ (Merged into one call at 0x800E5924 ) |
dwc_match.cpp | Ported from WiiLink24's WFC Patcher and condensed |
0x800E5A2C 0x800E5A3C 0x800E5A40 0x800E5A50 0x800E5A54 0x800E5A64 0x800E5A74 0x800E5A80 |
Security Fixes | Match Command Buffer Overflow Fix (QR2) | ☑️ (Merged into one call at 0x800E5AAC ) |
dwc_match.cpp | Ported from WiiLink24's WFC Patcher and condensed |
0x800E6778 |
NATNEG Fixes | Prevent Host Disconnection From Repeated NATNEG Failures | ✅ | dwc_match.cpp Natneg.cpp |
N/A |
0x800E7800 |
NATNEG Fixes | Suspend Bug Fix | ☑️ (Moved to 0x800E77F4 ) |
dwc_match.cpp | Ported from WiiLink24's WFC Patcher |
0x800ED4A0 0x800ED558 |
Auto Reconnect | Stub Some Errors | ⏭ | N/A | Auto Reconnect will not be implemented |
0x800ED784 0x800ED78C |
Payload Download | Payload Download Request | ⏭ | N/A | Porting unnecessary since the payload is not downloaded |
0x800EDEE8 |
Authentication | Main Authentication Function | dwc_auth_interface.cpp Auth.cpp |
Accurate Data Sent:
|
|
0x800EE098 |
Authentication | Report Product Code on Dolphin | ✅ | dwc_auth_interface.cpp Auth.cpp |
N/A |
0x800EE364 0x800EE36C |
Custom Error Messages | Store Custom Error Message | ⏭ | N/A | Replaced with offline error messages |
0x800EE74C |
Challenge Checking | Save Received Challenge | ✅ | dwc_auth_interface.cpp Challenge.cpp |
N/A |
0x800EE9F8 |
Authentication | Parse Custom Response | ☑️ (Moved to 0x800EEA08 ) |
dwc_auth_interface.cpp Auth.cpp |
|
0x800FCEDC |
Player Kicking | Parse Kick Requests | (Moved to 0x800FCEE8 and replaced instruction at 0x800FCEC8 ) |
gpi.cpp Kick.cpp |
|
0x801007D8 |
Authentication | Report Certificate and Signed Token | ✅ | gpiConnect.cpp Auth.cpp |
N/A |
0x8010E094 |
Port Binding | Retry on Different Port on Binding Failure | ✅ | gt2Socket.cpp | Avoid pointless use of static variables |
0x80111534 |
Challenge Checking | Send Saved Challenge | ✅ | qr2.cpp Challenge.cpp |
Hook rewritten to avoid overwriting existing parameters or overflowing the buffer |
0x8011AB28 0x8011AB30 |
NATify Fixes | Send NATify Result | ☑️ (Added extra write to 0x8011AB2C ) |
natneg.cpp Natify.cpp |
Replaced unsafe store |
0x8011B478 |
NATNEG Fixes | Reduce CONNECT_PING Retry Time | ✅ | natneg.cpp | N/A |
0x8011B4B0 |
NATNEG Fixes | Ignore Retry Time on NATNEG Success | ✅ | natneg.cpp | N/A |
0x801937E0 0x801938F8 |
"Security" Fixes | IOS Operation "Protection" | ⏭ | N/A | Porting skipped for the aforementioned reasons |
0x801D4F10 0x801D4F2C |
Payload Download | Payload Download CA Replacement | ⏭ | N/A | Porting unnecessary since the payload is not downloaded |
0x8023B0E0 |
Player Kicking | Reset Kick Flag | ☑️ (Moved to 0x80554728 ) |
N/A | N/A |
0x80279D58 0x80279DA4 0x80279DE4 0x8027A428 0x8027A4A8 0x8027AD68 0x8027B4D8 0x8027BEF0 0x8027D091 0x8027DCAB 0x8027DCC7 0x8027DCE3 0x8027DE33 0x8027DEB7 0x8027E0A0 0x8089A6B8 0x8089ABD0 0x8089AC25 0x8089AC85 0x8089AD12 |
Domain Replacements | N/A | ✅ | Domains.cpp | N/A |
0x8027A688 |
Auto Reconnect | Handle Login | ⏭ | N/A | Auto Reconnect will not be implemented |
0x80514D58 0x80514D7C |
Bug Fixes | Invalid Item Point Antifreeze | ☑️ (Overrides function at 0x80514D3C ) |
CourseMap.cpp | Entire function reimplemented to provide extra flexibility |
0x80518AFC 0x80518B20 |
Bug Fixes | Invalid Cannon Point Antifreeze | ☑️ (Overrides function at 0x80518AE0 ) |
CourseMap.cpp | Entire function reimplemented to provide extra flexibility |
0x80519560 |
Telemetry | Report Track SHA1 Hash | ☑️ (Overrides function at 0x80519508 ) |
DvdArchive.cpp Reporting.cpp |
|
0x8051B69C |
Frameskip | N/A | ⏭ | N/A | Frameskip will not be reimplemented |
0x80533660 |
Telemetry | Report Race Finish and Battle Results | ☑️ (Moved to 0x8053369C ) |
RaceManager.cpp Reporting.cpp |
|
0x805348CC |
Telemetry | Report Race Finish Time | ☑️ (Moved to 0x8053490C ) |
RaceManager.cpp Reporting.cpp |
The finish time will not be reported if the race is offline or the player is not local |
0x8053511c |
Bug Fixes | Ultra Shortcut Fix | ☑️ (Moved to 0x805350DC ) |
RaceManager.cpp | Rewritten in C++ to allow mods more control over the fix's application |
0x80535C78 |
Accurate Timing | Update Race Frame Counter | ☑️ (Added a extra hook at 0x80535C7C ) |
TimerManager.cpp Delay.cpp |
N/A |
0x8053F3F4 |
Player Kicking | Cancel Race Support | ☑️ (Branch from 0x8053F39C to 0x8053F444 ) |
RaceModeOnlineVs.cpp | Rewritten in C++ to allow mods to easily end the race on command |
0x8054DF88 |
Frameskip | Disable Model Drawing while Lagging | ⏭ | N/A | Pointless patch as the hooked function is never called by the game |
0x805543A4 |
Telemetry | Report Course Subfile SHA1 Hashes | ✅ | RaceScene.cpp Reporting.cpp |
The hashes are not computed if the race is offline |
0x80562AD0 |
Frameskip | Disable Model Drawing while Lagging | ⏭ | N/A | Frameskip will not be implemented |
0x805845D8 |
Bug Fixes | Invalid Item Point Antifreeze | ✅ | KartMove.cpp | N/A |
0x80589ACC |
Bug Fixes | Halfpipe Fix | ✅ | KartNetReceiver.cpp |
|
0x80591B70 |
Telemetry and "Anticheat" | Report Common.szs Subfile SHA1 Hashes and "Detect" Gecko Codes | ✅ | KartParam.cpp Reporting.cpp |
|
0x805CDDC8 |
Custom Messages | Apply Message Replacements | ⏭ | N/A | Features implemented separately due to high chances of clashing with existing patches:
|
0x805CE55C |
Frameskip | Mess with Text Rendering Code | ⏭ | N/A | Frameskip should not mess with BMG escape sequences |
0x805D2EF8 0x805D2F00 |
Bug Fixes | Invalid Friend Code Antifreeze | ✅ | FriendList.cpp | N/A |
0x805D8CF4 0x805D9044 0x806437CC 0x80643CB8 0x80643CCC 0x80644404 0x8064AAAC |
Auto Reconnect | Voting Screen Text Update | ⏭ | N/A | Auto Reconnect will not be implemented |
0x805DCE34 |
Telemetry | Report Room Start | ✅ | FriendRoomMessageSelectPage.cpp Reporting.cpp |
Removed pointless snprintf call |
0x80600D10 |
Data Sharing Consent | Revoke Custom Data Sharing Consent Flag | ✅ | OptionMessagePage.cpp | N/A |
0x8064ECB4 0x8064F074 0x8064F60C 0x8064F610 0x8064F618 0x8064F61C 0x8064F620 0x8064F644 |
Auto Reconnect | Handle Exiting Race while Offline | ⏭ | N/A | Auto Reconnect will not be implemented |
0x80654400 |
Bug Fixes | Ignore Reported Lag Frames | ✅ | RKNetPacketCreator.cpp | N/A |
0x806579B0 |
Various | Main Wiimmfi Network Loop | ✅ | N/A | Implemented:
|
0x80657A6C |
Auto Reconnect | Fix Main Thread | ⏭ | N/A | Auto Reconnect will not be implemented |
0x80658610 |
Security Fixes | RCE Fix | RKNetController.cpp Security.cpp |
Ported from WiiLink24, providing the following enhancements:
|
|
0x806591F4 0x80659248 |
Telemetry | Obtain VS/BT Regions | ⏭ | N/A | Removed disgusting runtime hooks and replaced them with a sane solution |
0x8065DF44 |
Security Fixes | ITEM Packet Data Validation | N/A | Integrated into RCE Fix (not implemented yet) | |
0x8065FF5C |
Bug Fixes | Reset Room Stall Timer | ✅ | RKNetSelectHandler.cpp RoomStall.cpp |
N/A |
0x80660330 |
Bug Fixes | Room Stall Prevention | ✅ | RKNetSelectHandler.cpp RoomStall.cpp |
N/A |
0x80760A88 |
Bug Fixes | Thwomp Antifreeze | ✅ | ObjDossun.cpp | N/A |
0x8079BF88 |
Security Fixes | EVENT Packet Data Validation | N/A | Integrated into RCE Fix (not implemented yet) | |
0x807A1914 |
Bug Fixes | Stationary Item Collision Momentum Fix | ✅ | ItemObj.cpp | N/A |
0x807BC940 |
"Anticheat" | Store Item for Cheat Detection | ⏭ | N/A | Not ported due to the measure basically amounting to self-reporting, which is too fragile and easily bypassed |
0x808BFF8C |
Authentication | Display Console Assignment Message | ✅ | WifiMenuPage.cpp | Replaced disgusting runtime hook with fixed hook |
0x808D4100 |
Frameskip | Display Debug Data | ⏭ | N/A | This should not be in the regular payload |
0x808D410C |
Frameskip | N/A | ⏭ | N/A | Hook does literally nothing |
The table below lists all the new hooks introduced by OpenPayload and their purpose:
Hook Address(es) | Category | Purpose | Code | Notes/Changes |
---|---|---|---|---|
0x8011BC38 |
NATNEG Fixes | Skip Unnecessary Delay | natneg.cpp | Ported from WiiLink24 WFC |
0x80554728 |
Various | Reset Values Before Race Start | N/A | N/A |
0x808BFB74 |
Custom Error Messages | Display Custom Error Message | WifiDisconnectPage.cpp | Virtual function override |