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 |
|---|---|---|---|---|---|
0x800095C40x800095E40x800095F4 |
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 |
0x800CECB00x800DEA18 |
Auto Reconnect | Fix Friend Status Issues | ⏭ | N/A | Auto Reconnect will not be implemented |
0x800CECBC0x8065A0EC |
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 |
0x800D05980x800D059C0x800D05A0 |
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 |
|
0x800D0DD40x800D0DE8 |
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 |
0x800D1DDC0x800D1F040x800D1FDC0x800D2058 |
Auto Reconnect | Don't Close P2P Connections When Disconnecting | ⏭ | N/A | Auto Reconnect will not be implemented |
0x800D26DC0x800D30500x800D30780x800D31A00x800D31BC0x800D36240x800D3C380x800D3EA00x800E56800x806576480x8065764C0x806587140x8065A970 |
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? |
0x800D31C40x80658F7C |
NATNEG Fixes | Reattempt NATNEG Multiple Times | ☑️ (Moved respectively to 0x800D3188 and 0x80657990) |
dwc_main.cpp RKNetController.cpp Natneg.cpp |
N/A |
0x800D3F1C0x800E09A8 |
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 |
0x800D94F00x800E59800x800E5B14 |
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 |
0x800DA7D00x800DA7D40x800DA7D8 |
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 |
0x800DCEC80x800DCF980x800E57FC |
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 |
0x800E58B80x800E58BC0x800E58C80x800E58CC0x800E58D00x800E58D80x800E58EC |
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 |
0x800E5A2C0x800E5A3C0x800E5A400x800E5A500x800E5A540x800E5A640x800E5A740x800E5A80 |
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 |
0x800ED4A00x800ED558 |
Auto Reconnect | Stub Some Errors | ⏭ | N/A | Auto Reconnect will not be implemented |
0x800ED7840x800ED78C |
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 |
0x800EE3640x800EE36C |
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 |
0x8011AB280x8011AB30 |
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 |
0x801937E00x801938F8 |
"Security" Fixes | IOS Operation "Protection" | ⏭ | N/A | Porting skipped for the aforementioned reasons |
0x801D4F100x801D4F2C |
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 |
0x80279D580x80279DA40x80279DE40x8027A4280x8027A4A80x8027AD680x8027B4D80x8027BEF00x8027D0910x8027DCAB0x8027DCC70x8027DCE30x8027DE330x8027DEB70x8027E0A00x8089A6B80x8089ABD00x8089AC250x8089AC850x8089AD12 |
Domain Replacements | N/A | ✅ | Domains.cpp | N/A |
0x8027A688 |
Auto Reconnect | Handle Login | ⏭ | N/A | Auto Reconnect will not be implemented |
0x80514D580x80514D7C |
Bug Fixes | Invalid Item Point Antifreeze | ☑️ (Overrides function at 0x80514D3C) |
CourseMap.cpp | Entire function reimplemented to provide extra flexibility |
0x80518AFC0x80518B20 |
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 |
0x805D2EF80x805D2F00 |
Bug Fixes | Invalid Friend Code Antifreeze | ✅ | FriendList.cpp | N/A |
0x805D8CF40x805D90440x806437CC0x80643CB80x80643CCC0x806444040x8064AAAC |
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 |
0x8064ECB40x8064F0740x8064F60C0x8064F6100x8064F6180x8064F61C0x8064F6200x8064F644 |
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:
|
|
0x806591F40x80659248 |
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 |