From 6b6038a004ef9eeacd9b6f99179967ad0606026c Mon Sep 17 00:00:00 2001 From: Maschell Date: Sat, 16 Nov 2019 15:01:01 +0100 Subject: [PATCH] Add support for patching functions at a physical address --- src/patcher/function_patcher.cpp | 60 ++++++++++++++++++++--------- src/patcher/function_patcher.h | 2 + src/plugin/DynamicLinkingHelper.cpp | 12 +++++- src/plugin/FunctionData.h | 13 ++++++- src/plugin/PluginLoader.cpp | 6 ++- 5 files changed, 71 insertions(+), 22 deletions(-) diff --git a/src/patcher/function_patcher.cpp b/src/patcher/function_patcher.cpp index af1091d..864d10a 100644 --- a/src/patcher/function_patcher.cpp +++ b/src/patcher/function_patcher.cpp @@ -119,21 +119,33 @@ void new_PatchInvidualMethodHooks(replacement_data_plugin_t * plugin_data) { volatile uint32_t *space = function_data->replace_data; DEBUG_FUNCTION_LINE("Patching %s ...\n",function_data->function_name); - if(function_data->functionType == STATIC_FUNCTION && function_data->alreadyPatched == 1) { - if(new_isDynamicFunction((uint32_t)OSEffectiveToPhysical(function_data->realAddr))) { - DEBUG_FUNCTION_LINE("INFO: The function %s is a dynamic function.\n", function_data->function_name); - function_data->functionType = DYNAMIC_FUNCTION; - } else { + + if(function_data->library == WUPS_LOADER_LIBRARY_OTHER) { + DEBUG_FUNCTION_LINE("Oh, using straight PA/VA\n"); + if(function_data->alreadyPatched == 1) { DEBUG_FUNCTION_LINE("Skipping %s, its already patched\n", function_data->function_name); continue; } + } else { + if(function_data->functionType == STATIC_FUNCTION && function_data->alreadyPatched == 1) { + if(new_isDynamicFunction((uint32_t)OSEffectiveToPhysical(function_data->realAddr))) { + DEBUG_FUNCTION_LINE("INFO: The function %s is a dynamic function.\n", function_data->function_name); + function_data->functionType = DYNAMIC_FUNCTION; + } else { + DEBUG_FUNCTION_LINE("Skipping %s, its already patched\n", function_data->function_name); + continue; + } + } } - uint32_t physical = 0; + uint32_t physical = function_data->physicalAddr; uint32_t repl_addr = (uint32_t)function_data->replaceAddr; uint32_t call_addr = (uint32_t)function_data->replaceCall; - uint32_t real_addr = new_GetAddressOfFunction(function_data->function_name,function_data->library); + uint32_t real_addr = function_data->virtualAddr; + if(function_data->library != WUPS_LOADER_LIBRARY_OTHER) { + real_addr = new_GetAddressOfFunction(function_data->function_name,function_data->library); + } if(!real_addr) { log_printf("\n"); @@ -145,7 +157,10 @@ void new_PatchInvidualMethodHooks(replacement_data_plugin_t * plugin_data) { DEBUG_FUNCTION_LINE("%s is located at %08X!\n", function_data->function_name,real_addr); } - physical = (uint32_t)OSEffectiveToPhysical(real_addr); + if(function_data->library != WUPS_LOADER_LIBRARY_OTHER) { + physical = (uint32_t)OSEffectiveToPhysical(real_addr); + } + if(!physical) { log_printf("Error. Something is wrong with the physical address\n"); continue; @@ -259,26 +274,32 @@ void new_RestoreInvidualInstructions(replacement_data_plugin_t * plugin_data) { continue; } - uint32_t real_addr = new_GetAddressOfFunction(function_data->function_name,function_data->library); - + uint32_t real_addr = function_data->virtualAddr; + if(function_data->library != WUPS_LOADER_LIBRARY_OTHER) { + real_addr = new_GetAddressOfFunction(function_data->function_name,function_data->library); + } if(!real_addr) { log_printf("OSDynLoad_FindExport failed for %s\n", function_data->function_name); continue; } - - uint32_t physical = (uint32_t)OSEffectiveToPhysical(real_addr); + uint32_t physical = function_data->physicalAddr; + if(function_data->library != WUPS_LOADER_LIBRARY_OTHER) { + physical = (uint32_t)OSEffectiveToPhysical(real_addr); + } if(!physical) { log_printf("Something is wrong with the physical address\n"); continue; } - - if(new_isDynamicFunction(physical)) { + if((function_data->library != WUPS_LOADER_LIBRARY_OTHER) && new_isDynamicFunction(physical)) { log_printf("Its a dynamic function. We don't need to restore it!\n",function_data->function_name); } else { - physical = (uint32_t)OSEffectiveToPhysical(function_data->realAddr); //When its an static function, we need to use the old location + if(function_data->library != WUPS_LOADER_LIBRARY_OTHER) { + physical = (uint32_t)OSEffectiveToPhysical(function_data->realAddr); //When its an static function, we need to use the old location + } + if(DEBUG_LOG_DYN) { DEBUG_FUNCTION_LINE("Restoring %08X to %08X\n",(uint32_t)function_data->restoreInstruction,physical); - } + } uint32_t targetAddr = (uint32_t)&(function_data->restoreInstruction); if(targetAddr < 0x00800000 || targetAddr >= 0x01000000) { targetAddr = (uint32_t) OSEffectiveToPhysical(targetAddr); @@ -292,8 +313,11 @@ void new_RestoreInvidualInstructions(replacement_data_plugin_t * plugin_data) { if(DEBUG_LOG_DYN) { DEBUG_FUNCTION_LINE("ICInvalidateRange %08X\n",(void*)function_data->realAddr); } - ICInvalidateRange((void*)function_data->realAddr, 4); - DCFlushRange((void*)function_data->realAddr, 4); + + if(function_data->library != WUPS_LOADER_LIBRARY_OTHER) { + ICInvalidateRange((void*)function_data->realAddr, 4); + DCFlushRange((void*)function_data->realAddr, 4); + } log_printf("done\n"); } function_data->alreadyPatched = 0; // In case a diff --git a/src/patcher/function_patcher.h b/src/patcher/function_patcher.h index 522be4f..2e137a2 100644 --- a/src/patcher/function_patcher.h +++ b/src/patcher/function_patcher.h @@ -40,6 +40,8 @@ struct rpl_handling { #define MAXIMUM_FUNCTION_NAME_LENGTH 61 struct replacement_data_function_t { + uint32_t physicalAddr; /* [needs to be filled] */ + uint32_t virtualAddr; /* [needs to be filled] */ uint32_t replaceAddr; /* [needs to be filled] Address of our replacement function */ uint32_t replaceCall; /* [needs to be filled] Address to access the real_function */ wups_loader_library_type_t library; /* [needs to be filled] rpl where the function we want to replace is. */ diff --git a/src/plugin/DynamicLinkingHelper.cpp b/src/plugin/DynamicLinkingHelper.cpp index 207e13c..3186ea4 100644 --- a/src/plugin/DynamicLinkingHelper.cpp +++ b/src/plugin/DynamicLinkingHelper.cpp @@ -138,7 +138,17 @@ bool DynamicLinkingHelper::fillRelocations(std::vectorhandle, isData, functionEntry->functionName, &functionEntry->address); + + std::string wrap_str = "__rplwrap_"; + std::string functionNameStr = functionEntry->functionName; + + OSDynLoad_FindExport(importEntry->handle, isData, functionEntry->functionName, &functionEntry->address); + + if(functionNameStr.size() < wrap_str.size()) { + + } else if (std::equal(wrap_str.begin(), wrap_str.end(), functionNameStr.begin())) { + OSDynLoad_FindExport(importEntry->handle, isData, functionNameStr.substr(wrap_str.size()).c_str(), &functionEntry->address); + } if(!functionEntry->address) { DEBUG_FUNCTION_LINE("OSDynLoad_FindExport failed for %s on import %s\n", functionEntry->functionName,importEntry->importName); diff --git a/src/plugin/FunctionData.h b/src/plugin/FunctionData.h index 0fc2f1c..d2a3721 100644 --- a/src/plugin/FunctionData.h +++ b/src/plugin/FunctionData.h @@ -24,7 +24,9 @@ class FunctionData { public: - FunctionData(const char * name, wups_loader_library_type_t library, void * target, void * call_addr) { + FunctionData(void * paddress, void * vaddress, const char * name, wups_loader_library_type_t library, void * target, void * call_addr) { + this->paddress = paddress; + this->vaddress = vaddress; this->name = name; this->library = library; this->replaceAddr = target; @@ -43,6 +45,13 @@ public: return this->library; } + void * getPhysicalAddress() { + return paddress; + } + void * getVirtualAddress() { + return vaddress; + } + void * getReplaceAddress() { return replaceAddr; } @@ -52,6 +61,8 @@ public: } private: + void * paddress = NULL; + void * vaddress = NULL; std::string name; wups_loader_library_type_t library; void * replaceAddr = NULL; diff --git a/src/plugin/PluginLoader.cpp b/src/plugin/PluginLoader.cpp index 2215e29..2f89aa2 100644 --- a/src/plugin/PluginLoader.cpp +++ b/src/plugin/PluginLoader.cpp @@ -399,8 +399,8 @@ bool PluginLoader::loadAndLinkElf(PluginData * pluginData, Elf *elf, void * star for(size_t j=0; j_function.name,pluginData->getPluginInformation()->getName().c_str(),cur_function->_function.library,cur_function->_function.target, (void *) cur_function->_function.call_addr); - FunctionData * function_data = new FunctionData(cur_function->_function.name,cur_function->_function.library, (void *) cur_function->_function.target, (void *) cur_function->_function.call_addr); + DEBUG_FUNCTION_LINE("Saving function \"%s\" of plugin \"%s\". PA:%08X VA:%08X Library: %08X, target: %08X, call_addr: %08X\n",cur_function->_function.name,pluginData->getPluginInformation()->getName().c_str(),cur_function->_function.physical_address,cur_function->_function.virtual_address, cur_function->_function.library,cur_function->_function.target, (void *) cur_function->_function.call_addr); + FunctionData * function_data = new FunctionData((void *) cur_function->_function.physical_address,(void *) cur_function->_function.virtual_address, cur_function->_function.name, cur_function->_function.library, (void *) cur_function->_function.target, (void *) cur_function->_function.call_addr); pluginData->addFunctionData(function_data); } @@ -492,6 +492,8 @@ void PluginLoader::copyPluginDataIntoGlobalStruct(std::vector plug function_data->library = cur_function->getLibrary(); function_data->replaceAddr = (uint32_t) cur_function->getReplaceAddress(); function_data->replaceCall = (uint32_t) cur_function->getReplaceCall(); + function_data->physicalAddr = (uint32_t) cur_function->getPhysicalAddress(); + function_data->virtualAddr = (uint32_t) cur_function->getVirtualAddress(); plugin_data->number_used_functions++; }