2022-05-08 18:51:05 +02:00
|
|
|
#include "FunctionAddressProvider.h"
|
|
|
|
#include "utils/logger.h"
|
|
|
|
#include <coreinit/dynload.h>
|
|
|
|
#include <function_patcher/fpatching_defines.h>
|
|
|
|
|
|
|
|
uint32_t FunctionAddressProvider::getEffectiveAddressOfFunction(function_replacement_library_type_t library, const char *functionName) {
|
|
|
|
uint32_t real_addr = 0;
|
|
|
|
OSDynLoad_Module rpl_handle = nullptr;
|
|
|
|
OSDynLoad_Error err = OS_DYNLOAD_OK;
|
|
|
|
|
2022-12-30 19:51:47 +01:00
|
|
|
for (auto &rplHandle : rpl_handles) {
|
|
|
|
if (rplHandle.library == library) {
|
|
|
|
if (rplHandle.handle == nullptr) {
|
2023-01-06 14:15:59 +01:00
|
|
|
DEBUG_FUNCTION_LINE_VERBOSE("Lets check if rpl is loaded: %s", rplHandle.rplname);
|
2022-12-30 19:51:47 +01:00
|
|
|
err = OSDynLoad_IsModuleLoaded((char *) rplHandle.rplname, &rplHandle.handle);
|
2022-05-08 18:51:05 +02:00
|
|
|
}
|
2022-12-30 19:51:47 +01:00
|
|
|
if (err != OS_DYNLOAD_OK || !rplHandle.handle) {
|
|
|
|
DEBUG_FUNCTION_LINE_VERBOSE("%s is not loaded yet", rplHandle.rplname, err, rplHandle.handle);
|
2022-05-08 18:51:05 +02:00
|
|
|
return 0;
|
|
|
|
}
|
2022-12-30 19:51:47 +01:00
|
|
|
rpl_handle = rplHandle.handle;
|
2022-05-08 18:51:05 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!rpl_handle) {
|
|
|
|
DEBUG_FUNCTION_LINE_ERR("Failed to find the RPL handle for %s", functionName);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2023-04-23 11:37:43 +02:00
|
|
|
OSDynLoad_FindExport(rpl_handle, OS_DYNLOAD_EXPORT_FUNC, functionName, reinterpret_cast<void **>(&real_addr));
|
2022-05-08 18:51:05 +02:00
|
|
|
|
|
|
|
if (!real_addr) {
|
|
|
|
DEBUG_FUNCTION_LINE_VERBOSE("OSDynLoad_FindExport failed for %s", functionName);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2022-08-06 22:41:01 +02:00
|
|
|
uint32_t realAddrData = *((volatile uint32_t *) real_addr);
|
|
|
|
|
|
|
|
if ((realAddrData & 0xFC000003) == 0x48000000) {
|
|
|
|
auto address_diff = (uint32_t) (realAddrData & 0x01FFFFFC);
|
|
|
|
if ((realAddrData & 0x02000000) == 0x02000000) {
|
|
|
|
address_diff = 0xFE000000 + address_diff;
|
2022-05-08 18:51:05 +02:00
|
|
|
}
|
|
|
|
real_addr += (int32_t) address_diff;
|
|
|
|
}
|
|
|
|
|
|
|
|
return real_addr;
|
|
|
|
}
|
|
|
|
|
|
|
|
void FunctionAddressProvider::resetHandles() {
|
2022-12-30 19:51:47 +01:00
|
|
|
for (auto &rplHandle : rpl_handles) {
|
|
|
|
if (rplHandle.handle != nullptr) {
|
|
|
|
DEBUG_FUNCTION_LINE_VERBOSE("Resetting handle for rpl: %s", rplHandle.rplname);
|
2022-05-08 18:51:05 +02:00
|
|
|
}
|
|
|
|
|
2022-12-30 19:51:47 +01:00
|
|
|
rplHandle.handle = nullptr;
|
2022-05-08 18:51:05 +02:00
|
|
|
}
|
|
|
|
}
|
2023-01-02 16:24:33 +01:00
|
|
|
|
|
|
|
function_replacement_library_type_t FunctionAddressProvider::getTypeForHandle(OSDynLoad_Module handle) {
|
|
|
|
for (auto &rplHandle : rpl_handles) {
|
|
|
|
if (rplHandle.handle == handle) {
|
|
|
|
return rplHandle.library;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return LIBRARY_OTHER;
|
|
|
|
}
|
|
|
|
|
2023-01-02 16:24:38 +01:00
|
|
|
bool FunctionAddressProvider::resetHandle(OSDynLoad_Module handle) {
|
|
|
|
for (auto &rplHandle : rpl_handles) {
|
|
|
|
if (rplHandle.handle == handle) {
|
|
|
|
rplHandle.handle = nullptr;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|