From 67de80eea0d3cad7cbd6c82e4d63d41856d80a45 Mon Sep 17 00:00:00 2001 From: Rambo6Glaz Date: Sun, 25 Dec 2022 21:09:06 +0100 Subject: [PATCH] Fixed ENLBufferPwn fix + new bug fix --- README.md | 4 +++- source/patches.cpp | 38 ++++++++++++++++++++++++++++++++++++-- source/patches.h | 8 ++++++++ 3 files changed, 47 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index f671f95..3eceba3 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,8 @@ - Mario Kart 8 (All regions, v64) - [ENLBufferPwn](https://github.com/PabloMK7/ENLBufferPwn) fix - Identification token parsing RCE fix (exploit found by Kinnay) + - ENL nullptr deref fix + OOB read - Splatoon (All regions, v272) - - [ENLBufferPwn](https://github.com/PabloMK7/ENLBufferPwn) fix \ No newline at end of file + - [ENLBufferPwn](https://github.com/PabloMK7/ENLBufferPwn) fix + - ENL nullptr deref fix + OOB read \ No newline at end of file diff --git a/source/patches.cpp b/source/patches.cpp index c2dc814..17a9e13 100644 --- a/source/patches.cpp +++ b/source/patches.cpp @@ -18,30 +18,47 @@ enl_ContentTransporter *(*real_enl_TransportManager_getContentTransporter)(void 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; - // Fix for RCE (if size mismatch, do not handle packet.) - if (record->mContentLength > contentTransp->vtable->getSendBufferSize(contentTransp)) + 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) @@ -80,6 +97,14 @@ void MARIO_KART_8_ApplyPatch(EPatchType type) 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)"); } } @@ -109,6 +134,15 @@ void SPLATOON_ApplyPatch(EPatchType type) 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)"); } } \ No newline at end of file diff --git a/source/patches.h b/source/patches.h index bfabdf7..371b156 100644 --- a/source/patches.h +++ b/source/patches.h @@ -48,6 +48,14 @@ struct __attribute__((__packed__)) enl_RecordHeader uint16_t mContentLength; }; +struct enl_Buffer +{ + uint8_t *mData; + size_t mCapacity; + size_t mSize; + bool isAllocated; +}; + struct enl_ContentTransporter { struct ContentTransporterVtbl