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;
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,23 +274,29 @@ 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);
}
@ -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

View File

@ -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. */

View File

@ -138,8 +138,18 @@ bool DynamicLinkingHelper::fillRelocations(std::vector<dyn_linking_relocation_en
isData = 1;
//DEBUG_FUNCTION_LINE("isData\n");
}
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);
return false;

View File

@ -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;

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++) {
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++;
}