mirror of
https://github.com/wiiu-env/WiiUPluginLoaderBackend.git
synced 2024-11-05 04:25:08 +01:00
Add support for patching functions at a physical address
This commit is contained in:
parent
614f75364b
commit
6b6038a004
@ -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
|
||||
|
@ -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. */
|
||||
|
@ -138,7 +138,17 @@ bool DynamicLinkingHelper::fillRelocations(std::vector<dyn_linking_relocation_en
|
||||
isData = 1;
|
||||
//DEBUG_FUNCTION_LINE("isData\n");
|
||||
}
|
||||
OSDynLoad_FindExport(importEntry->handle, 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);
|
||||
|
@ -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;
|
||||
|
@ -399,8 +399,8 @@ bool PluginLoader::loadAndLinkElf(PluginData * pluginData, Elf *elf, void * star
|
||||
|
||||
for(size_t j=0; j<entry_t_list.size(); j++) {
|
||||
wups_loader_entry_t * cur_function = entry_t_list[j];
|
||||
DEBUG_FUNCTION_LINE("Saving function \"%s\" of plugin \"%s\". Library: %08X, target: %08X, call_addr: %08X\n",cur_function->_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<PluginData *> 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++;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user