mirror of
https://github.com/PretendoNetwork/rce_patches.git
synced 2024-05-18 21:01:02 -04:00
Format code
This commit is contained in:
parent
67de80eea0
commit
ae503e18e5
67
.clang-format
Normal file
67
.clang-format
Normal file
|
@ -0,0 +1,67 @@
|
|||
# Generated from CLion C/C++ Code Style settings
|
||||
BasedOnStyle: LLVM
|
||||
AccessModifierOffset: -4
|
||||
AlignAfterOpenBracket: Align
|
||||
AlignConsecutiveAssignments: Consecutive
|
||||
AlignConsecutiveMacros: AcrossEmptyLinesAndComments
|
||||
AlignOperands: Align
|
||||
AllowAllArgumentsOnNextLine: false
|
||||
AllowAllConstructorInitializersOnNextLine: false
|
||||
AllowAllParametersOfDeclarationOnNextLine: false
|
||||
AllowShortBlocksOnASingleLine: Always
|
||||
AllowShortCaseLabelsOnASingleLine: false
|
||||
AllowShortFunctionsOnASingleLine: All
|
||||
AllowShortIfStatementsOnASingleLine: Always
|
||||
AllowShortLambdasOnASingleLine: All
|
||||
AllowShortLoopsOnASingleLine: true
|
||||
AlwaysBreakAfterReturnType: None
|
||||
AlwaysBreakTemplateDeclarations: Yes
|
||||
BreakBeforeBraces: Custom
|
||||
BraceWrapping:
|
||||
AfterCaseLabel: false
|
||||
AfterClass: false
|
||||
AfterControlStatement: Never
|
||||
AfterEnum: false
|
||||
AfterFunction: false
|
||||
AfterNamespace: false
|
||||
AfterUnion: false
|
||||
BeforeCatch: false
|
||||
BeforeElse: false
|
||||
IndentBraces: false
|
||||
SplitEmptyFunction: false
|
||||
SplitEmptyRecord: true
|
||||
BreakBeforeBinaryOperators: None
|
||||
BreakBeforeTernaryOperators: true
|
||||
BreakConstructorInitializers: BeforeColon
|
||||
BreakInheritanceList: BeforeColon
|
||||
ColumnLimit: 0
|
||||
CompactNamespaces: false
|
||||
ContinuationIndentWidth: 8
|
||||
IndentCaseLabels: true
|
||||
IndentPPDirectives: None
|
||||
IndentWidth: 4
|
||||
KeepEmptyLinesAtTheStartOfBlocks: true
|
||||
MaxEmptyLinesToKeep: 2
|
||||
NamespaceIndentation: All
|
||||
ObjCSpaceAfterProperty: false
|
||||
ObjCSpaceBeforeProtocolList: true
|
||||
PointerAlignment: Right
|
||||
ReflowComments: false
|
||||
SpaceAfterCStyleCast: true
|
||||
SpaceAfterLogicalNot: false
|
||||
SpaceAfterTemplateKeyword: false
|
||||
SpaceBeforeAssignmentOperators: true
|
||||
SpaceBeforeCpp11BracedList: false
|
||||
SpaceBeforeCtorInitializerColon: true
|
||||
SpaceBeforeInheritanceColon: true
|
||||
SpaceBeforeParens: ControlStatements
|
||||
SpaceBeforeRangeBasedForLoopColon: true
|
||||
SpaceInEmptyParentheses: false
|
||||
SpacesBeforeTrailingComments: 1
|
||||
SpacesInAngles: false
|
||||
SpacesInCStyleCastParentheses: false
|
||||
SpacesInContainerLiterals: false
|
||||
SpacesInParentheses: false
|
||||
SpacesInSquareBrackets: false
|
||||
TabWidth: 4
|
||||
UseTab: Never
|
|
@ -1,5 +1,5 @@
|
|||
#include <wups.h>
|
||||
#include <string.h>
|
||||
#include <wups.h>
|
||||
|
||||
#include "patches.h"
|
||||
|
||||
|
@ -11,54 +11,46 @@ WUPS_PLUGIN_LICENSE("");
|
|||
|
||||
std::optional<rplinfo> gRPLInfo;
|
||||
|
||||
ON_APPLICATION_START()
|
||||
{
|
||||
ON_APPLICATION_START() {
|
||||
|
||||
// If this is not a supported title, no need to do anything
|
||||
uint64_t titleId = OSGetTitleID();
|
||||
GamePatches *gamePatch = nullptr;
|
||||
for (auto &patch : sGamePatchList)
|
||||
{
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
if (patch.mRegionalTIDs[i] == titleId)
|
||||
{
|
||||
gamePatch = &patch;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// If this is not a supported title, no need to do anything
|
||||
uint64_t titleId = OSGetTitleID();
|
||||
GamePatches *gamePatch = nullptr;
|
||||
for (auto &patch : sGamePatchList) {
|
||||
for (int i = 0; i < 3; i++) {
|
||||
if (patch.mRegionalTIDs[i] == titleId) {
|
||||
gamePatch = &patch;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!gamePatch)
|
||||
return;
|
||||
if (!gamePatch)
|
||||
return;
|
||||
|
||||
// Init logging
|
||||
if (!WHBLogModuleInit())
|
||||
{
|
||||
WHBLogCafeInit();
|
||||
WHBLogUdpInit();
|
||||
}
|
||||
// Init logging
|
||||
if (!WHBLogModuleInit()) {
|
||||
WHBLogCafeInit();
|
||||
WHBLogUdpInit();
|
||||
}
|
||||
|
||||
WHBLogPrintf("rce_patches: applying patches for %s...", gamePatch->mTitleName);
|
||||
WHBLogPrintf("rce_patches: applying patches for %s...", gamePatch->mTitleName);
|
||||
|
||||
// Patch the dynload functions so GetRPLInfo works
|
||||
if (!PatchDynLoadFunctions())
|
||||
{
|
||||
WHBLogPrintf("rce_patches: Failed to patch dynload functions");
|
||||
return;
|
||||
}
|
||||
// Patch the dynload functions so GetRPLInfo works
|
||||
if (!PatchDynLoadFunctions()) {
|
||||
WHBLogPrintf("rce_patches: Failed to patch dynload functions");
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the RPLInfo
|
||||
gRPLInfo = TryGetRPLInfo();
|
||||
if (!gRPLInfo)
|
||||
{
|
||||
WHBLogPrintf("rce_patches: Failed to get RPL info");
|
||||
return;
|
||||
}
|
||||
// Get the RPLInfo
|
||||
gRPLInfo = TryGetRPLInfo();
|
||||
if (!gRPLInfo) {
|
||||
WHBLogPrintf("rce_patches: Failed to get RPL info");
|
||||
return;
|
||||
}
|
||||
|
||||
// For each patch type, call apply patch func (terrible design lol)
|
||||
for (auto &patch : gamePatch->mPatchTypes)
|
||||
{
|
||||
gamePatch->mPatchFunc(patch);
|
||||
}
|
||||
// For each patch type, call apply patch func (terrible design lol)
|
||||
for (auto &patch : gamePatch->mPatchTypes) {
|
||||
gamePatch->mPatchFunc(patch);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,16 +2,16 @@
|
|||
|
||||
#include "utils/logger.h"
|
||||
|
||||
#include <kernel/kernel.h>
|
||||
#include <coreinit/memorymap.h>
|
||||
#include <kernel/kernel.h>
|
||||
|
||||
bool replace_string(uint32_t start, uint32_t size, const char* original_val, size_t original_val_sz, const char* new_val, size_t new_val_sz) {
|
||||
bool replace_string(uint32_t start, uint32_t size, const char *original_val, size_t original_val_sz, const char *new_val, size_t new_val_sz) {
|
||||
for (uint32_t addr = start; addr < start + size - original_val_sz; addr++) {
|
||||
int ret = memcmp(original_val, (void*)addr, original_val_sz);
|
||||
int ret = memcmp(original_val, (void *) addr, original_val_sz);
|
||||
if (ret == 0) {
|
||||
DEBUG_FUNCTION_LINE("found str @%08x: %s", addr, (const char*)addr);
|
||||
KernelCopyData(OSEffectiveToPhysical(addr), OSEffectiveToPhysical((uint32_t)new_val), new_val_sz);
|
||||
DEBUG_FUNCTION_LINE("new str @%08x: %s", addr, (const char*)addr);
|
||||
DEBUG_FUNCTION_LINE("found str @%08x: %s", addr, (const char *) addr);
|
||||
KernelCopyData(OSEffectiveToPhysical(addr), OSEffectiveToPhysical((uint32_t) new_val), new_val_sz);
|
||||
DEBUG_FUNCTION_LINE("new str @%08x: %s", addr, (const char *) addr);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,4 +3,4 @@
|
|||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
|
||||
bool replace_string(uint32_t start, uint32_t size, const char* original_val, size_t original_val_sz, const char* new_val, size_t new_val_sz);
|
||||
bool replace_string(uint32_t start, uint32_t size, const char *original_val, size_t original_val_sz, const char *new_val, size_t new_val_sz);
|
||||
|
|
|
@ -20,59 +20,52 @@
|
|||
#include <coreinit/cache.h>
|
||||
#include <coreinit/memorymap.h>
|
||||
|
||||
std::optional<std::vector<OSDynLoad_NotifyData>> TryGetRPLInfo()
|
||||
{
|
||||
int num_rpls = OSDynLoad_GetNumberOfRPLs();
|
||||
if (num_rpls == 0)
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
std::optional<std::vector<OSDynLoad_NotifyData>> TryGetRPLInfo() {
|
||||
int num_rpls = OSDynLoad_GetNumberOfRPLs();
|
||||
if (num_rpls == 0) {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
DEBUG_FUNCTION_LINE("num_rpls: %d", num_rpls);
|
||||
DEBUG_FUNCTION_LINE("num_rpls: %d", num_rpls);
|
||||
|
||||
std::vector<OSDynLoad_NotifyData> rpls;
|
||||
rpls.resize(num_rpls);
|
||||
std::vector<OSDynLoad_NotifyData> rpls;
|
||||
rpls.resize(num_rpls);
|
||||
|
||||
bool ret = OSDynLoad_GetRPLInfo(0, num_rpls, rpls.data());
|
||||
if (!ret)
|
||||
{
|
||||
return std::nullopt;
|
||||
}
|
||||
bool ret = OSDynLoad_GetRPLInfo(0, num_rpls, rpls.data());
|
||||
if (!ret) {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
return rpls;
|
||||
return rpls;
|
||||
}
|
||||
|
||||
bool PatchInstruction(void *instr, uint32_t original, uint32_t replacement)
|
||||
{
|
||||
uint32_t current = *(uint32_t *)instr;
|
||||
DEBUG_FUNCTION_LINE("current instr %08x", current);
|
||||
if (current != original)
|
||||
return current == replacement;
|
||||
bool PatchInstruction(void *instr, uint32_t original, uint32_t replacement) {
|
||||
uint32_t current = *(uint32_t *) instr;
|
||||
DEBUG_FUNCTION_LINE("current instr %08x", current);
|
||||
if (current != original)
|
||||
return current == replacement;
|
||||
|
||||
KernelCopyData(OSEffectiveToPhysical((uint32_t)instr), OSEffectiveToPhysical((uint32_t)&replacement), sizeof(replacement));
|
||||
// Only works on AROMA! WUPS 0.1's KernelCopyData is uncached, needs DCInvalidate here instead
|
||||
DCFlushRange(instr, 4);
|
||||
ICInvalidateRange(instr, 4);
|
||||
KernelCopyData(OSEffectiveToPhysical((uint32_t) instr), OSEffectiveToPhysical((uint32_t) &replacement), sizeof(replacement));
|
||||
// Only works on AROMA! WUPS 0.1's KernelCopyData is uncached, needs DCInvalidate here instead
|
||||
DCFlushRange(instr, 4);
|
||||
ICInvalidateRange(instr, 4);
|
||||
|
||||
current = *(uint32_t *)instr;
|
||||
DEBUG_FUNCTION_LINE("patched instr %08x", current);
|
||||
current = *(uint32_t *) instr;
|
||||
DEBUG_FUNCTION_LINE("patched instr %08x", current);
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PatchDynLoadFunctions()
|
||||
{
|
||||
uint32_t *patch1 = ((uint32_t *)&OSDynLoad_GetNumberOfRPLs) + 6;
|
||||
uint32_t *patch2 = ((uint32_t *)&OSDynLoad_GetRPLInfo) + 22;
|
||||
bool PatchDynLoadFunctions() {
|
||||
uint32_t *patch1 = ((uint32_t *) &OSDynLoad_GetNumberOfRPLs) + 6;
|
||||
uint32_t *patch2 = ((uint32_t *) &OSDynLoad_GetRPLInfo) + 22;
|
||||
|
||||
if (!PatchInstruction(patch1, 0x41820038 /* beq +38 */, 0x60000000 /*nop*/))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!PatchInstruction(patch2, 0x41820100 /* beq +100 */, 0x60000000 /*nop*/))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (!PatchInstruction(patch1, 0x41820038 /* beq +38 */, 0x60000000 /*nop*/)) {
|
||||
return false;
|
||||
}
|
||||
if (!PatchInstruction(patch2, 0x41820100 /* beq +100 */, 0x60000000 /*nop*/)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -12,10 +12,10 @@
|
|||
*/
|
||||
#pragma once
|
||||
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <coreinit/dynload.h>
|
||||
|
||||
|
@ -24,11 +24,9 @@ using rplinfo = std::vector<OSDynLoad_NotifyData>;
|
|||
std::optional<rplinfo> TryGetRPLInfo();
|
||||
bool PatchDynLoadFunctions();
|
||||
|
||||
constexpr inline std::optional<OSDynLoad_NotifyData> FindRPL(const rplinfo &rpls, const std::string &name)
|
||||
{
|
||||
auto res = std::find_if(rpls.cbegin(), rpls.cend(), [&](const OSDynLoad_NotifyData &data)
|
||||
{ return std::string(data.name).ends_with(name); });
|
||||
if (res == rpls.cend())
|
||||
return std::nullopt;
|
||||
return *res;
|
||||
constexpr inline std::optional<OSDynLoad_NotifyData> FindRPL(const rplinfo &rpls, const std::string &name) {
|
||||
auto res = std::find_if(rpls.cbegin(), rpls.cend(), [&](const OSDynLoad_NotifyData &data) { return std::string(data.name).ends_with(name); });
|
||||
if (res == rpls.cend())
|
||||
return std::nullopt;
|
||||
return *res;
|
||||
}
|
||||
|
|
|
@ -2,147 +2,134 @@
|
|||
|
||||
// ==========================================================================================
|
||||
|
||||
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);
|
||||
}
|
||||
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);
|
||||
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)
|
||||
{
|
||||
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;
|
||||
// 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;
|
||||
}
|
||||
// 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;
|
||||
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;
|
||||
if (record->mContentLength > 0x440)
|
||||
return;
|
||||
|
||||
pData += sizeof(enl_RecordHeader);
|
||||
pData += record->mContentLength;
|
||||
}
|
||||
pData += sizeof(enl_RecordHeader);
|
||||
pData += record->mContentLength;
|
||||
}
|
||||
|
||||
if (!hasEndRecord)
|
||||
return;
|
||||
if (!hasEndRecord)
|
||||
return;
|
||||
|
||||
return real_enl_TransportManager_updateReceiveBuffer_(_this, bufferId, data, size);
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
}
|
||||
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);
|
||||
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)");
|
||||
}
|
||||
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);
|
||||
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);
|
||||
// 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);
|
||||
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)");
|
||||
}
|
||||
WHBLogPrintf("rce_patches: Patched Mario Kart 8 (PATCH_ENL_BUFFER_RCE)");
|
||||
}
|
||||
}
|
||||
|
||||
// ==========================================================================================
|
||||
|
||||
void SPLATOON_ApplyPatch(EPatchType type)
|
||||
{
|
||||
void SPLATOON_ApplyPatch(EPatchType type) {
|
||||
|
||||
auto gambit_rpx = FindRPL(*gRPLInfo, "Gambit.rpx");
|
||||
if (!gambit_rpx)
|
||||
{
|
||||
WHBLogPrintf("rce_patches: Couldn't find Gambit.rpx ...");
|
||||
return;
|
||||
}
|
||||
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);
|
||||
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::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);
|
||||
// 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)");
|
||||
}
|
||||
WHBLogPrintf("rce_patches: Patched Splatoon (PATCH_ENL_BUFFER_RCE)");
|
||||
}
|
||||
}
|
105
source/patches.h
105
source/patches.h
|
@ -1,18 +1,18 @@
|
|||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
#include <cstring>
|
||||
#include <vector>
|
||||
|
||||
#include <whb/log.h>
|
||||
#include <whb/log_module.h>
|
||||
#include <whb/log_cafe.h>
|
||||
#include <whb/log_module.h>
|
||||
#include <whb/log_udp.h>
|
||||
|
||||
#include <coreinit/title.h>
|
||||
|
||||
#include <patcher/rplinfo.h>
|
||||
#include <patcher/patcher.h>
|
||||
#include <patcher/rplinfo.h>
|
||||
|
||||
#include <kernel/kernel.h>
|
||||
|
||||
|
@ -22,79 +22,72 @@
|
|||
#undef DECL_FUNCTION
|
||||
#include <function_patcher/function_patching.h>
|
||||
|
||||
enum EPatchType
|
||||
{
|
||||
PATCH_ENL_BUFFER_RCE,
|
||||
PATCH_ENL_ID_TOKEN_RCE,
|
||||
enum EPatchType {
|
||||
PATCH_ENL_BUFFER_RCE,
|
||||
PATCH_ENL_ID_TOKEN_RCE,
|
||||
};
|
||||
|
||||
struct GamePatches
|
||||
{
|
||||
const char *mTitleName;
|
||||
uint64_t mRegionalTIDs[3];
|
||||
std::vector<EPatchType> mPatchTypes;
|
||||
void (*mPatchFunc)(EPatchType type);
|
||||
struct GamePatches {
|
||||
const char *mTitleName;
|
||||
uint64_t mRegionalTIDs[3];
|
||||
std::vector<EPatchType> mPatchTypes;
|
||||
void (*mPatchFunc)(EPatchType type);
|
||||
};
|
||||
|
||||
struct sead_String
|
||||
{
|
||||
char *mBuffer;
|
||||
uint32_t vtable;
|
||||
struct sead_String {
|
||||
char *mBuffer;
|
||||
uint32_t vtable;
|
||||
};
|
||||
|
||||
struct __attribute__((__packed__)) enl_RecordHeader
|
||||
{
|
||||
uint8_t mContentTransporterID;
|
||||
uint16_t mContentLength;
|
||||
struct __attribute__((__packed__)) enl_RecordHeader {
|
||||
uint8_t mContentTransporterID;
|
||||
uint16_t mContentLength;
|
||||
};
|
||||
|
||||
struct enl_Buffer
|
||||
{
|
||||
uint8_t *mData;
|
||||
size_t mCapacity;
|
||||
size_t mSize;
|
||||
bool isAllocated;
|
||||
struct enl_Buffer {
|
||||
uint8_t *mData;
|
||||
size_t mCapacity;
|
||||
size_t mSize;
|
||||
bool isAllocated;
|
||||
};
|
||||
|
||||
struct enl_ContentTransporter
|
||||
{
|
||||
struct ContentTransporterVtbl
|
||||
{
|
||||
int a;
|
||||
int b;
|
||||
int f08;
|
||||
void (*init)(enl_ContentTransporter *_this);
|
||||
int _f10;
|
||||
void *(*getSendBuffer)(enl_ContentTransporter *_this);
|
||||
int _f18;
|
||||
int (*getSendBufferSize)(enl_ContentTransporter *_this);
|
||||
int _f20;
|
||||
bool (*isNeedSend)(enl_ContentTransporter *_thiss);
|
||||
int _f28;
|
||||
unsigned char (*getContentID)(enl_ContentTransporter *_this);
|
||||
// ...
|
||||
};
|
||||
ContentTransporterVtbl *vtable;
|
||||
struct enl_ContentTransporter {
|
||||
struct ContentTransporterVtbl {
|
||||
int a;
|
||||
int b;
|
||||
int f08;
|
||||
void (*init)(enl_ContentTransporter *_this);
|
||||
int _f10;
|
||||
void *(*getSendBuffer)(enl_ContentTransporter *_this);
|
||||
int _f18;
|
||||
int (*getSendBufferSize)(enl_ContentTransporter *_this);
|
||||
int _f20;
|
||||
bool (*isNeedSend)(enl_ContentTransporter *_thiss);
|
||||
int _f28;
|
||||
unsigned char (*getContentID)(enl_ContentTransporter *_this);
|
||||
// ...
|
||||
};
|
||||
ContentTransporterVtbl *vtable;
|
||||
};
|
||||
|
||||
// ==========================================================================================
|
||||
|
||||
#define MARIO_KART_8_TID_J 0x000500001010EB00
|
||||
#define MARIO_KART_8_TID_U 0x000500001010EC00
|
||||
#define MARIO_KART_8_TID_E 0x000500001010ED00
|
||||
#define MARIO_KART_8_TID_J 0x000500001010EB00
|
||||
#define MARIO_KART_8_TID_U 0x000500001010EC00
|
||||
#define MARIO_KART_8_TID_E 0x000500001010ED00
|
||||
|
||||
#define MARIO_KART_8_TID MARIO_KART_8_TID_J, MARIO_KART_8_TID_U, MARIO_KART_8_TID_E
|
||||
#define MARIO_KART_8_TID MARIO_KART_8_TID_J, MARIO_KART_8_TID_U, MARIO_KART_8_TID_E
|
||||
#define MARIO_KART_8_PATCHES PATCH_ENL_BUFFER_RCE, PATCH_ENL_ID_TOKEN_RCE
|
||||
|
||||
void MARIO_KART_8_ApplyPatch(EPatchType type);
|
||||
|
||||
// ==========================================================================================
|
||||
|
||||
#define SPLATOON_TID_J 0x0005000010162B00
|
||||
#define SPLATOON_TID_U 0x0005000010176900
|
||||
#define SPLATOON_TID_E 0x0005000010176A00
|
||||
#define SPLATOON_TID_J 0x0005000010162B00
|
||||
#define SPLATOON_TID_U 0x0005000010176900
|
||||
#define SPLATOON_TID_E 0x0005000010176A00
|
||||
|
||||
#define SPLATOON_TID SPLATOON_TID_J, SPLATOON_TID_U, SPLATOON_TID_E
|
||||
#define SPLATOON_TID SPLATOON_TID_J, SPLATOON_TID_U, SPLATOON_TID_E
|
||||
#define SPLATOON_PATCHES PATCH_ENL_BUFFER_RCE
|
||||
|
||||
void SPLATOON_ApplyPatch(EPatchType type);
|
||||
|
@ -103,6 +96,6 @@ void SPLATOON_ApplyPatch(EPatchType type);
|
|||
|
||||
extern std::optional<rplinfo> gRPLInfo;
|
||||
static std::vector<GamePatches> sGamePatchList = {
|
||||
{"Mario Kart 8 ", {MARIO_KART_8_TID}, {MARIO_KART_8_PATCHES}, MARIO_KART_8_ApplyPatch},
|
||||
{"Splatoon", {SPLATOON_TID}, {SPLATOON_PATCHES}, SPLATOON_ApplyPatch},
|
||||
{"Mario Kart 8 ", {MARIO_KART_8_TID}, {MARIO_KART_8_PATCHES}, MARIO_KART_8_ApplyPatch},
|
||||
{"Splatoon", {SPLATOON_TID}, {SPLATOON_PATCHES}, SPLATOON_ApplyPatch},
|
||||
};
|
Loading…
Reference in a new issue