mirror of
https://github.com/PretendoNetwork/rce_patches.git
synced 2025-04-02 11:02:12 -04:00
148 lines
No EOL
4.9 KiB
C++
148 lines
No EOL
4.9 KiB
C++
#include "patches.h"
|
|
|
|
// ==========================================================================================
|
|
|
|
DECL_FUNCTION(bool, enl_ParseIdentificationToken, void *identifiationInfo, sead_String *identificationToken)
|
|
{
|
|
// Fix for RCE (stack overflow if identification buffer was bigger than 16)
|
|
if (strnlen(identificationToken->mBuffer, 16) == 16)
|
|
{
|
|
identificationToken->mBuffer[15] = '\0';
|
|
return real_enl_ParseIdentificationToken(identifiationInfo, identificationToken);
|
|
}
|
|
|
|
return real_enl_ParseIdentificationToken(identifiationInfo, identificationToken);
|
|
}
|
|
|
|
enl_ContentTransporter *(*real_enl_TransportManager_getContentTransporter)(void *_this, unsigned char &id);
|
|
DECL_FUNCTION(void, enl_TransportManager_updateReceiveBuffer_, void *_this, signed char const &bufferId, uint8_t *data, uint32_t size)
|
|
{
|
|
|
|
// Check for end record in the data, if there is not, drop packet
|
|
bool hasEndRecord = false;
|
|
|
|
// Loop through all records and check if there's a bad record (size mismatch) until out of bounds or end record
|
|
uint8_t *pData = data;
|
|
while (pData < (data + size))
|
|
{
|
|
enl_RecordHeader *record = (enl_RecordHeader *)pData;
|
|
if (record->mContentLength == 0 && record->mContentTransporterID == 0xff)
|
|
{
|
|
hasEndRecord = true;
|
|
break;
|
|
}
|
|
|
|
enl_ContentTransporter *contentTransp = real_enl_TransportManager_getContentTransporter(_this, record->mContentTransporterID);
|
|
// Actual fix for the ENL nullptr deref crash (lmao)
|
|
if (!contentTransp)
|
|
return;
|
|
|
|
if (record->mContentLength > 0x440)
|
|
return;
|
|
|
|
pData += sizeof(enl_RecordHeader);
|
|
pData += record->mContentLength;
|
|
}
|
|
|
|
if (!hasEndRecord)
|
|
return;
|
|
|
|
return real_enl_TransportManager_updateReceiveBuffer_(_this, bufferId, data, size);
|
|
}
|
|
|
|
DECL_FUNCTION(void, enl_Buffer_set, enl_Buffer *_this, uint8_t const *data, size_t size)
|
|
{
|
|
// Fix for the RCE
|
|
if (!_this->mData || !size || size > _this->mCapacity)
|
|
return;
|
|
|
|
memcpy(_this->mData, data, size);
|
|
_this->mSize = size;
|
|
}
|
|
// ==========================================================================================
|
|
|
|
void MARIO_KART_8_ApplyPatch(EPatchType type)
|
|
{
|
|
auto turbo_rpx = FindRPL(*gRPLInfo, "Turbo.rpx");
|
|
if (!turbo_rpx)
|
|
{
|
|
WHBLogPrintf("rce_patches: Couldn't find Turbo.rpx ...");
|
|
return;
|
|
}
|
|
|
|
if (type == PATCH_ENL_ID_TOKEN_RCE)
|
|
{
|
|
// Address of 'enl::PiaUtil::ParseIdentificationToken'
|
|
uint32_t addr_func = turbo_rpx->textAddr + 0x8E3930;
|
|
function_replacement_data_t repl = REPLACE_FUNCTION_VIA_ADDRESS_FOR_PROCESS(
|
|
enl_ParseIdentificationToken,
|
|
OSEffectiveToPhysical(addr_func),
|
|
addr_func,
|
|
FP_TARGET_PROCESS_GAME_AND_MENU);
|
|
FunctionPatcherPatchFunction(&repl, nullptr);
|
|
|
|
WHBLogPrintf("rce_patches: Patched Mario Kart 8 (PATCH_ENL_ID_TOKEN_RCE)");
|
|
}
|
|
|
|
if (type == PATCH_ENL_BUFFER_RCE)
|
|
{
|
|
real_enl_TransportManager_getContentTransporter = (enl_ContentTransporter * (*)(void *, unsigned char &))(turbo_rpx->textAddr + 0x8D7678);
|
|
|
|
// Address of 'enl::TransportManager::updateReceiveBuffer_'
|
|
uint32_t addr_func = turbo_rpx->textAddr + 0x8D772C;
|
|
function_replacement_data_t repl = REPLACE_FUNCTION_VIA_ADDRESS_FOR_PROCESS(
|
|
enl_TransportManager_updateReceiveBuffer_,
|
|
OSEffectiveToPhysical(addr_func),
|
|
addr_func,
|
|
FP_TARGET_PROCESS_GAME_AND_MENU);
|
|
FunctionPatcherPatchFunction(&repl, nullptr);
|
|
|
|
addr_func = turbo_rpx->textAddr + 0x8CF228;
|
|
repl = REPLACE_FUNCTION_VIA_ADDRESS_FOR_PROCESS(
|
|
enl_Buffer_set,
|
|
OSEffectiveToPhysical(addr_func),
|
|
addr_func,
|
|
FP_TARGET_PROCESS_GAME_AND_MENU);
|
|
FunctionPatcherPatchFunction(&repl, nullptr);
|
|
|
|
WHBLogPrintf("rce_patches: Patched Mario Kart 8 (PATCH_ENL_BUFFER_RCE)");
|
|
}
|
|
}
|
|
|
|
// ==========================================================================================
|
|
|
|
void SPLATOON_ApplyPatch(EPatchType type)
|
|
{
|
|
|
|
auto gambit_rpx = FindRPL(*gRPLInfo, "Gambit.rpx");
|
|
if (!gambit_rpx)
|
|
{
|
|
WHBLogPrintf("rce_patches: Couldn't find Gambit.rpx ...");
|
|
return;
|
|
}
|
|
|
|
if (type == PATCH_ENL_BUFFER_RCE)
|
|
{
|
|
real_enl_TransportManager_getContentTransporter = (enl_ContentTransporter * (*)(void *, unsigned char &))(gambit_rpx->textAddr + 0xB4108C);
|
|
|
|
// Address of 'enl::TransportManager::updateReceiveBuffer_'
|
|
uint32_t addr_func = gambit_rpx->textAddr + 0xB41140;
|
|
function_replacement_data_t repl = REPLACE_FUNCTION_VIA_ADDRESS_FOR_PROCESS(
|
|
enl_TransportManager_updateReceiveBuffer_,
|
|
OSEffectiveToPhysical(addr_func),
|
|
addr_func,
|
|
FP_TARGET_PROCESS_GAME_AND_MENU);
|
|
FunctionPatcherPatchFunction(&repl, nullptr);
|
|
|
|
// Address of 'enl:Buffer::set'
|
|
addr_func = gambit_rpx->textAddr + 0xB4D178;
|
|
repl = REPLACE_FUNCTION_VIA_ADDRESS_FOR_PROCESS(
|
|
enl_Buffer_set,
|
|
OSEffectiveToPhysical(addr_func),
|
|
addr_func,
|
|
FP_TARGET_PROCESS_GAME_AND_MENU);
|
|
FunctionPatcherPatchFunction(&repl, nullptr);
|
|
|
|
WHBLogPrintf("rce_patches: Patched Splatoon (PATCH_ENL_BUFFER_RCE)");
|
|
}
|
|
} |