Add support for patching functions at a physical address

This commit is contained in:
Maschell 2019-11-16 15:01:01 +01:00
parent 614f75364b
commit 6b6038a004
5 changed files with 71 additions and 22 deletions

View File

@ -119,21 +119,33 @@ void new_PatchInvidualMethodHooks(replacement_data_plugin_t * plugin_data) {
volatile uint32_t *space = function_data->replace_data; volatile uint32_t *space = function_data->replace_data;
DEBUG_FUNCTION_LINE("Patching %s ...\n",function_data->function_name); 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))) { if(function_data->library == WUPS_LOADER_LIBRARY_OTHER) {
DEBUG_FUNCTION_LINE("INFO: The function %s is a dynamic function.\n", function_data->function_name); DEBUG_FUNCTION_LINE("Oh, using straight PA/VA\n");
function_data->functionType = DYNAMIC_FUNCTION; if(function_data->alreadyPatched == 1) {
} else {
DEBUG_FUNCTION_LINE("Skipping %s, its already patched\n", function_data->function_name); DEBUG_FUNCTION_LINE("Skipping %s, its already patched\n", function_data->function_name);
continue; 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 repl_addr = (uint32_t)function_data->replaceAddr;
uint32_t call_addr = (uint32_t)function_data->replaceCall; 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) { if(!real_addr) {
log_printf("\n"); 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); 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) { if(!physical) {
log_printf("Error. Something is wrong with the physical address\n"); log_printf("Error. Something is wrong with the physical address\n");
continue; continue;
@ -259,26 +274,32 @@ void new_RestoreInvidualInstructions(replacement_data_plugin_t * plugin_data) {
continue; 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) { if(!real_addr) {
log_printf("OSDynLoad_FindExport failed for %s\n", function_data->function_name); log_printf("OSDynLoad_FindExport failed for %s\n", function_data->function_name);
continue; continue;
} }
uint32_t physical = function_data->physicalAddr;
uint32_t physical = (uint32_t)OSEffectiveToPhysical(real_addr); if(function_data->library != WUPS_LOADER_LIBRARY_OTHER) {
physical = (uint32_t)OSEffectiveToPhysical(real_addr);
}
if(!physical) { if(!physical) {
log_printf("Something is wrong with the physical address\n"); log_printf("Something is wrong with the physical address\n");
continue; continue;
} }
if((function_data->library != WUPS_LOADER_LIBRARY_OTHER) && new_isDynamicFunction(physical)) {
if(new_isDynamicFunction(physical)) {
log_printf("Its a dynamic function. We don't need to restore it!\n",function_data->function_name); log_printf("Its a dynamic function. We don't need to restore it!\n",function_data->function_name);
} else { } 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) { if(DEBUG_LOG_DYN) {
DEBUG_FUNCTION_LINE("Restoring %08X to %08X\n",(uint32_t)function_data->restoreInstruction,physical); DEBUG_FUNCTION_LINE("Restoring %08X to %08X\n",(uint32_t)function_data->restoreInstruction,physical);
} }
uint32_t targetAddr = (uint32_t)&(function_data->restoreInstruction); uint32_t targetAddr = (uint32_t)&(function_data->restoreInstruction);
if(targetAddr < 0x00800000 || targetAddr >= 0x01000000) { if(targetAddr < 0x00800000 || targetAddr >= 0x01000000) {
targetAddr = (uint32_t) OSEffectiveToPhysical(targetAddr); targetAddr = (uint32_t) OSEffectiveToPhysical(targetAddr);
@ -292,8 +313,11 @@ void new_RestoreInvidualInstructions(replacement_data_plugin_t * plugin_data) {
if(DEBUG_LOG_DYN) { if(DEBUG_LOG_DYN) {
DEBUG_FUNCTION_LINE("ICInvalidateRange %08X\n",(void*)function_data->realAddr); 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"); log_printf("done\n");
} }
function_data->alreadyPatched = 0; // In case a function_data->alreadyPatched = 0; // In case a

View File

@ -40,6 +40,8 @@ struct rpl_handling {
#define MAXIMUM_FUNCTION_NAME_LENGTH 61 #define MAXIMUM_FUNCTION_NAME_LENGTH 61
struct replacement_data_function_t { 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 replaceAddr; /* [needs to be filled] Address of our replacement function */
uint32_t replaceCall; /* [needs to be filled] Address to access the real_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. */ wups_loader_library_type_t library; /* [needs to be filled] rpl where the function we want to replace is. */

View File

@ -138,7 +138,17 @@ bool DynamicLinkingHelper::fillRelocations(std::vector<dyn_linking_relocation_en
isData = 1; isData = 1;
//DEBUG_FUNCTION_LINE("isData\n"); //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) { if(!functionEntry->address) {
DEBUG_FUNCTION_LINE("OSDynLoad_FindExport failed for %s on import %s\n", functionEntry->functionName,importEntry->importName); DEBUG_FUNCTION_LINE("OSDynLoad_FindExport failed for %s on import %s\n", functionEntry->functionName,importEntry->importName);

View File

@ -24,7 +24,9 @@
class FunctionData { class FunctionData {
public: 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->name = name;
this->library = library; this->library = library;
this->replaceAddr = target; this->replaceAddr = target;
@ -43,6 +45,13 @@ public:
return this->library; return this->library;
} }
void * getPhysicalAddress() {
return paddress;
}
void * getVirtualAddress() {
return vaddress;
}
void * getReplaceAddress() { void * getReplaceAddress() {
return replaceAddr; return replaceAddr;
} }
@ -52,6 +61,8 @@ public:
} }
private: private:
void * paddress = NULL;
void * vaddress = NULL;
std::string name; std::string name;
wups_loader_library_type_t library; wups_loader_library_type_t library;
void * replaceAddr = NULL; void * replaceAddr = NULL;

View File

@ -399,8 +399,8 @@ bool PluginLoader::loadAndLinkElf(PluginData * pluginData, Elf *elf, void * star
for(size_t j=0; j<entry_t_list.size(); j++) { for(size_t j=0; j<entry_t_list.size(); j++) {
wups_loader_entry_t * cur_function = entry_t_list[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); 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(cur_function->_function.name,cur_function->_function.library, (void *) 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); pluginData->addFunctionData(function_data);
} }
@ -492,6 +492,8 @@ void PluginLoader::copyPluginDataIntoGlobalStruct(std::vector<PluginData *> plug
function_data->library = cur_function->getLibrary(); function_data->library = cur_function->getLibrary();
function_data->replaceAddr = (uint32_t) cur_function->getReplaceAddress(); function_data->replaceAddr = (uint32_t) cur_function->getReplaceAddress();
function_data->replaceCall = (uint32_t) cur_function->getReplaceCall(); 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++; plugin_data->number_used_functions++;
} }