Even more formatting

This commit is contained in:
Maschell 2020-05-03 12:30:15 +02:00
parent 4bf4a0eeea
commit 0c0680be77
41 changed files with 1036 additions and 984 deletions

View File

@ -7,12 +7,13 @@
class PluginManagement {
public:
static void doRelocations(const std::vector<PluginContainer>& plugins, relocation_trampolin_entry_t *trampData, uint32_t tramp_size);
static void memsetBSS(const std::vector<PluginContainer>& plugins);
static void doRelocations(const std::vector<PluginContainer> &plugins, relocation_trampolin_entry_t *trampData, uint32_t tramp_size);
static void memsetBSS(const std::vector<PluginContainer> &plugins);
static void callInitHooks(plugin_information_t *pluginInformation);
static void PatchFunctionsAndCallHooks(plugin_information_t* gPluginInformation);
static void PatchFunctionsAndCallHooks(plugin_information_t *gPluginInformation);
static bool doRelocation(const std::vector<RelocationData> &relocData, relocation_trampolin_entry_t *tramp_data, uint32_t tramp_length, uint32_t trampolinID);
};

View File

@ -33,19 +33,19 @@ extern "C" {
#define DYN_LINK_TRAMPOLIN_LIST_LENGTH DYN_LINK_FUNCTION_LIST_LENGTH
typedef struct _dyn_linking_function_t {
char functionName[DYN_LINK_FUNCTION_NAME_LENGTH+1];
void * address;
char functionName[DYN_LINK_FUNCTION_NAME_LENGTH + 1];
void *address;
} dyn_linking_function_t;
typedef struct _dyn_linking_import_t {
char importName[DYN_LINK_IMPORT_NAME_LENGTH+1];
char importName[DYN_LINK_IMPORT_NAME_LENGTH + 1];
bool isData = false;
} dyn_linking_import_t;
typedef struct _dyn_linking_relocation_entry_t {
dyn_linking_function_t* functionEntry = NULL;
dyn_linking_import_t* importEntry = NULL;
void * destination = NULL;
dyn_linking_function_t *functionEntry = NULL;
dyn_linking_import_t *importEntry = NULL;
void *destination = NULL;
char type;
size_t offset;
int32_t addend;

View File

@ -1,4 +1,5 @@
#pragma once
#include <stdint.h>
#include <wups.h>

View File

@ -74,7 +74,7 @@ void CallHookEx(plugin_information_t *pluginInformation, wups_loader_hook_type_t
((void (*)(void)) ((uint32_t *) func_ptr))();
} else if (hook_type == WUPS_LOADER_HOOK_APPLICATION_END) {
((void (*)(void)) ((uint32_t *) func_ptr))();
}else if (hook_type == WUPS_LOADER_HOOK_INIT_WUT_MALLOC) {
} else if (hook_type == WUPS_LOADER_HOOK_INIT_WUT_MALLOC) {
((void (*)(void)) ((uint32_t *) func_ptr))();
} else if (hook_type == WUPS_LOADER_HOOK_FINI_WUT_MALLOC) {
((void (*)(void)) ((uint32_t *) func_ptr))();

View File

@ -1,7 +1,10 @@
#pragma once
#include <wups.h>
#include "common/plugin_defines.h"
void CallHook(plugin_information_t * pluginInformation, wups_loader_hook_type_t hook_type);
void CallHookEx(plugin_information_t * pluginInformation, wups_loader_hook_type_t hook_type, int32_t plugin_index_needed);
bool HasHookCallHook(plugin_information_t * pluginInformation, wups_loader_hook_type_t hook_type);
void CallHook(plugin_information_t *pluginInformation, wups_loader_hook_type_t hook_type);
void CallHookEx(plugin_information_t *pluginInformation, wups_loader_hook_type_t hook_type, int32_t plugin_index_needed);
bool HasHookCallHook(plugin_information_t *pluginInformation, wups_loader_hook_type_t hook_type);

View File

@ -7,39 +7,39 @@ extern void SCKernelCopyData(uint32_t dst, uint32_t src, uint32_t len);
void KernelWrite(uint32_t addr, const void *data, uint32_t length) {
uint32_t dst = (uint32_t) OSEffectiveToPhysical(addr);
uint32_t src = (uint32_t) OSEffectiveToPhysical((uint32_t)data);
uint32_t src = (uint32_t) OSEffectiveToPhysical((uint32_t) data);
KernelCopyData(dst, src, length);
DCFlushRange((void *)addr, length);
ICInvalidateRange((void *)addr, length);
DCFlushRange((void *) addr, length);
ICInvalidateRange((void *) addr, length);
}
void KernelWriteU32(uint32_t addr, uint32_t value) {
uint32_t dst = (uint32_t) OSEffectiveToPhysical(addr);
uint32_t src = (uint32_t) OSEffectiveToPhysical((uint32_t)&value);
uint32_t src = (uint32_t) OSEffectiveToPhysical((uint32_t) &value);
KernelCopyData(dst, src, 4);
DCFlushRange((void *)addr, 4);
ICInvalidateRange((void *)addr, 4);
DCFlushRange((void *) addr, 4);
ICInvalidateRange((void *) addr, 4);
}
/* Write a 32-bit word with kernel permissions */
void __attribute__ ((noinline)) kern_write(void * addr, uint32_t value) {
void __attribute__ ((noinline)) kern_write(void *addr, uint32_t value) {
asm volatile (
"li 3,1\n"
"li 4,0\n"
"mr 5,%1\n"
"li 6,0\n"
"li 7,0\n"
"lis 8,1\n"
"mr 9,%0\n"
"mr %1,1\n"
"li 0,0x3500\n"
"sc\n"
"nop\n"
"mr 1,%1\n"
:
: "r"(addr), "r"(value)
: "memory", "ctr", "lr", "0", "3", "4", "5", "6", "7", "8", "9", "10",
"11", "12"
"li 3,1\n"
"li 4,0\n"
"mr 5,%1\n"
"li 6,0\n"
"li 7,0\n"
"lis 8,1\n"
"mr 9,%0\n"
"mr %1,1\n"
"li 0,0x3500\n"
"sc\n"
"nop\n"
"mr 1,%1\n"
:
: "r"(addr), "r"(value)
: "memory", "ctr", "lr", "0", "3", "4", "5", "6", "7", "8", "9", "10",
"11", "12"
);
}
@ -47,23 +47,23 @@ void __attribute__ ((noinline)) kern_write(void * addr, uint32_t value) {
uint32_t __attribute__ ((noinline)) kern_read(const void *addr) {
uint32_t result;
asm volatile (
"li 3,1\n"
"li 4,0\n"
"li 5,0\n"
"li 6,0\n"
"li 7,0\n"
"lis 8,1\n"
"mr 9,%1\n"
"li 0,0x3400\n"
"mr %0,1\n"
"sc\n"
"nop\n"
"mr 1,%0\n"
"mr %0,3\n"
: "=r"(result)
: "b"(addr)
: "memory", "ctr", "lr", "0", "3", "4", "5", "6", "7", "8", "9", "10",
"11", "12"
"li 3,1\n"
"li 4,0\n"
"li 5,0\n"
"li 6,0\n"
"li 7,0\n"
"lis 8,1\n"
"mr 9,%1\n"
"li 0,0x3400\n"
"mr %0,1\n"
"sc\n"
"nop\n"
"mr 1,%0\n"
"mr %0,3\n"
: "=r"(result)
: "b"(addr)
: "memory", "ctr", "lr", "0", "3", "4", "5", "6", "7", "8", "9", "10",
"11", "12"
);
return result;
@ -80,12 +80,12 @@ void PatchSyscall(int index, uint32_t addr) {
void kernelInitialize() {
static uint8_t ucSyscallsSetupRequired = 1;
if(!ucSyscallsSetupRequired)
if (!ucSyscallsSetupRequired)
return;
ucSyscallsSetupRequired = 0;
PatchSyscall(0x25, (uint32_t)SCKernelCopyData);
PatchSyscall(0x25, (uint32_t) SCKernelCopyData);
}

View File

@ -9,18 +9,22 @@ extern "C" {
extern void KernelCopyData(uint32_t dst, uint32_t src, uint32_t len);
void kern_write(void * addr, uint32_t value);
void kern_write(void *addr, uint32_t value);
uint32_t kern_read(const void *addr);
void SC0x0A_KernelWriteSRs(sr_table_t * table);
void SC0x36_KernelReadSRs(sr_table_t * table);
void SC0x0A_KernelWriteSRs(sr_table_t *table);
void SC0x36_KernelReadSRs(sr_table_t *table);
void KernelReadPTE(uint32_t addr, int32_t length);
void KernelWritePTE(uint32_t addr, int32_t length);
void KernelWrite(uint32_t addr, const void *data, uint32_t length);
void KernelWriteU32(uint32_t addr, uint32_t value);
void kernelInitialize();
#ifdef __cplusplus

View File

@ -84,7 +84,7 @@ int test() {
container.setMetaInformation(metaInfo.value());
container.setPluginData(pluginData);
plugins.push_back(container);
}else{
} else {
DEBUG_FUNCTION_LINE("Failed to get meta information");
}
}

View File

@ -36,101 +36,101 @@
#define DEBUG_LOG_DYN 0
rpl_handling rpl_handles[] __attribute__((section(".data"))) = {
{WUPS_LOADER_LIBRARY_AVM, "avm.rpl", 0},
{WUPS_LOADER_LIBRARY_CAMERA, "camera.rpl", 0},
{WUPS_LOADER_LIBRARY_COREINIT, "coreinit.rpl", 0},
{WUPS_LOADER_LIBRARY_DC, "dc.rpl", 0},
{WUPS_LOADER_LIBRARY_DMAE, "dmae.rpl", 0},
{WUPS_LOADER_LIBRARY_DRMAPP, "drmapp.rpl", 0},
{WUPS_LOADER_LIBRARY_ERREULA, "erreula.rpl", 0},
{WUPS_LOADER_LIBRARY_GX2, "gx2.rpl", 0},
{WUPS_LOADER_LIBRARY_H264, "h264.rpl", 0},
{WUPS_LOADER_LIBRARY_LZMA920, "lzma920.rpl", 0},
{WUPS_LOADER_LIBRARY_MIC, "mic.rpl", 0},
{WUPS_LOADER_LIBRARY_NFC, "nfc.rpl", 0},
{WUPS_LOADER_LIBRARY_NIO_PROF, "nio_prof.rpl", 0},
{WUPS_LOADER_LIBRARY_NLIBCURL, "nlibcurl.rpl", 0},
{WUPS_LOADER_LIBRARY_NLIBNSS, "nlibnss.rpl", 0},
{WUPS_LOADER_LIBRARY_NLIBNSS2, "nlibnss2.rpl", 0},
{WUPS_LOADER_LIBRARY_NN_AC, "nn_ac.rpl", 0},
{WUPS_LOADER_LIBRARY_NN_ACP, "nn_acp.rpl", 0},
{WUPS_LOADER_LIBRARY_NN_ACT, "nn_act.rpl", 0},
{WUPS_LOADER_LIBRARY_NN_AOC, "nn_aoc.rpl", 0},
{WUPS_LOADER_LIBRARY_NN_BOSS, "nn_boss.rpl", 0},
{WUPS_LOADER_LIBRARY_NN_CCR, "nn_ccr.rpl", 0},
{WUPS_LOADER_LIBRARY_NN_CMPT, "nn_cmpt.rpl", 0},
{WUPS_LOADER_LIBRARY_NN_DLP, "nn_dlp.rpl", 0},
{WUPS_LOADER_LIBRARY_NN_EC, "nn_ec.rpl", 0},
{WUPS_LOADER_LIBRARY_NN_FP, "nn_fp.rpl", 0},
{WUPS_LOADER_LIBRARY_NN_HAI, "nn_hai.rpl", 0},
{WUPS_LOADER_LIBRARY_NN_HPAD, "nn_hpad.rpl", 0},
{WUPS_LOADER_LIBRARY_NN_IDBE, "nn_idbe.rpl", 0},
{WUPS_LOADER_LIBRARY_NN_NDM, "nn_ndm.rpl", 0},
{WUPS_LOADER_LIBRARY_NN_NETS2, "nn_nets2.rpl", 0},
{WUPS_LOADER_LIBRARY_NN_NFP, "nn_nfp.rpl", 0},
{WUPS_LOADER_LIBRARY_NN_NIM, "nn_nim.rpl", 0},
{WUPS_LOADER_LIBRARY_NN_OLV, "nn_olv.rpl", 0},
{WUPS_LOADER_LIBRARY_NN_PDM, "nn_pdm.rpl", 0},
{WUPS_LOADER_LIBRARY_NN_SAVE, "nn_save.rpl", 0},
{WUPS_LOADER_LIBRARY_NN_SL, "nn_sl.rpl", 0},
{WUPS_LOADER_LIBRARY_NN_SPM, "nn_spm.rpl", 0},
{WUPS_LOADER_LIBRARY_NN_TEMP, "nn_temp.rpl", 0},
{WUPS_LOADER_LIBRARY_NN_UDS, "nn_uds.rpl", 0},
{WUPS_LOADER_LIBRARY_NN_VCTL, "nn_vctl.rpl", 0},
{WUPS_LOADER_LIBRARY_NSYSCCR, "nsysccr.rpl", 0},
{WUPS_LOADER_LIBRARY_NSYSHID, "nsyshid.rpl", 0},
{WUPS_LOADER_LIBRARY_NSYSKBD, "nsyskbd.rpl", 0},
{WUPS_LOADER_LIBRARY_NSYSNET, "nsysnet.rpl", 0},
{WUPS_LOADER_LIBRARY_NSYSUHS, "nsysuhs.rpl", 0},
{WUPS_LOADER_LIBRARY_NSYSUVD, "nsysuvd.rpl", 0},
{WUPS_LOADER_LIBRARY_NTAG, "ntag.rpl", 0},
{WUPS_LOADER_LIBRARY_PADSCORE, "padscore.rpl", 0},
{WUPS_LOADER_LIBRARY_PROC_UI, "proc_ui.rpl", 0},
{WUPS_LOADER_LIBRARY_SNDCORE2, "sndcore2.rpl", 0},
{WUPS_LOADER_LIBRARY_SNDUSER2, "snduser2.rpl", 0},
{WUPS_LOADER_LIBRARY_SND_CORE, "snd_core.rpl", 0},
{WUPS_LOADER_LIBRARY_SND_USER, "snd_user.rpl", 0},
{WUPS_LOADER_LIBRARY_SWKBD, "swkbd.rpl", 0},
{WUPS_LOADER_LIBRARY_SYSAPP, "sysapp.rpl", 0},
{WUPS_LOADER_LIBRARY_TCL, "tcl.rpl", 0},
{WUPS_LOADER_LIBRARY_TVE, "tve.rpl", 0},
{WUPS_LOADER_LIBRARY_UAC, "uac.rpl", 0},
{WUPS_LOADER_LIBRARY_UAC_RPL, "uac_rpl.rpl", 0},
{WUPS_LOADER_LIBRARY_USB_MIC, "usb_mic.rpl", 0},
{WUPS_LOADER_LIBRARY_UVC, "uvc.rpl", 0},
{WUPS_LOADER_LIBRARY_UVD, "uvd.rpl", 0},
{WUPS_LOADER_LIBRARY_VPAD, "vpad.rpl", 0},
{WUPS_LOADER_LIBRARY_VPADBASE, "vpadbase.rpl", 0},
{WUPS_LOADER_LIBRARY_ZLIB125, "zlib125.rpl", 0}
{WUPS_LOADER_LIBRARY_AVM, "avm.rpl", 0},
{WUPS_LOADER_LIBRARY_CAMERA, "camera.rpl", 0},
{WUPS_LOADER_LIBRARY_COREINIT, "coreinit.rpl", 0},
{WUPS_LOADER_LIBRARY_DC, "dc.rpl", 0},
{WUPS_LOADER_LIBRARY_DMAE, "dmae.rpl", 0},
{WUPS_LOADER_LIBRARY_DRMAPP, "drmapp.rpl", 0},
{WUPS_LOADER_LIBRARY_ERREULA, "erreula.rpl", 0},
{WUPS_LOADER_LIBRARY_GX2, "gx2.rpl", 0},
{WUPS_LOADER_LIBRARY_H264, "h264.rpl", 0},
{WUPS_LOADER_LIBRARY_LZMA920, "lzma920.rpl", 0},
{WUPS_LOADER_LIBRARY_MIC, "mic.rpl", 0},
{WUPS_LOADER_LIBRARY_NFC, "nfc.rpl", 0},
{WUPS_LOADER_LIBRARY_NIO_PROF, "nio_prof.rpl", 0},
{WUPS_LOADER_LIBRARY_NLIBCURL, "nlibcurl.rpl", 0},
{WUPS_LOADER_LIBRARY_NLIBNSS, "nlibnss.rpl", 0},
{WUPS_LOADER_LIBRARY_NLIBNSS2, "nlibnss2.rpl", 0},
{WUPS_LOADER_LIBRARY_NN_AC, "nn_ac.rpl", 0},
{WUPS_LOADER_LIBRARY_NN_ACP, "nn_acp.rpl", 0},
{WUPS_LOADER_LIBRARY_NN_ACT, "nn_act.rpl", 0},
{WUPS_LOADER_LIBRARY_NN_AOC, "nn_aoc.rpl", 0},
{WUPS_LOADER_LIBRARY_NN_BOSS, "nn_boss.rpl", 0},
{WUPS_LOADER_LIBRARY_NN_CCR, "nn_ccr.rpl", 0},
{WUPS_LOADER_LIBRARY_NN_CMPT, "nn_cmpt.rpl", 0},
{WUPS_LOADER_LIBRARY_NN_DLP, "nn_dlp.rpl", 0},
{WUPS_LOADER_LIBRARY_NN_EC, "nn_ec.rpl", 0},
{WUPS_LOADER_LIBRARY_NN_FP, "nn_fp.rpl", 0},
{WUPS_LOADER_LIBRARY_NN_HAI, "nn_hai.rpl", 0},
{WUPS_LOADER_LIBRARY_NN_HPAD, "nn_hpad.rpl", 0},
{WUPS_LOADER_LIBRARY_NN_IDBE, "nn_idbe.rpl", 0},
{WUPS_LOADER_LIBRARY_NN_NDM, "nn_ndm.rpl", 0},
{WUPS_LOADER_LIBRARY_NN_NETS2, "nn_nets2.rpl", 0},
{WUPS_LOADER_LIBRARY_NN_NFP, "nn_nfp.rpl", 0},
{WUPS_LOADER_LIBRARY_NN_NIM, "nn_nim.rpl", 0},
{WUPS_LOADER_LIBRARY_NN_OLV, "nn_olv.rpl", 0},
{WUPS_LOADER_LIBRARY_NN_PDM, "nn_pdm.rpl", 0},
{WUPS_LOADER_LIBRARY_NN_SAVE, "nn_save.rpl", 0},
{WUPS_LOADER_LIBRARY_NN_SL, "nn_sl.rpl", 0},
{WUPS_LOADER_LIBRARY_NN_SPM, "nn_spm.rpl", 0},
{WUPS_LOADER_LIBRARY_NN_TEMP, "nn_temp.rpl", 0},
{WUPS_LOADER_LIBRARY_NN_UDS, "nn_uds.rpl", 0},
{WUPS_LOADER_LIBRARY_NN_VCTL, "nn_vctl.rpl", 0},
{WUPS_LOADER_LIBRARY_NSYSCCR, "nsysccr.rpl", 0},
{WUPS_LOADER_LIBRARY_NSYSHID, "nsyshid.rpl", 0},
{WUPS_LOADER_LIBRARY_NSYSKBD, "nsyskbd.rpl", 0},
{WUPS_LOADER_LIBRARY_NSYSNET, "nsysnet.rpl", 0},
{WUPS_LOADER_LIBRARY_NSYSUHS, "nsysuhs.rpl", 0},
{WUPS_LOADER_LIBRARY_NSYSUVD, "nsysuvd.rpl", 0},
{WUPS_LOADER_LIBRARY_NTAG, "ntag.rpl", 0},
{WUPS_LOADER_LIBRARY_PADSCORE, "padscore.rpl", 0},
{WUPS_LOADER_LIBRARY_PROC_UI, "proc_ui.rpl", 0},
{WUPS_LOADER_LIBRARY_SNDCORE2, "sndcore2.rpl", 0},
{WUPS_LOADER_LIBRARY_SNDUSER2, "snduser2.rpl", 0},
{WUPS_LOADER_LIBRARY_SND_CORE, "snd_core.rpl", 0},
{WUPS_LOADER_LIBRARY_SND_USER, "snd_user.rpl", 0},
{WUPS_LOADER_LIBRARY_SWKBD, "swkbd.rpl", 0},
{WUPS_LOADER_LIBRARY_SYSAPP, "sysapp.rpl", 0},
{WUPS_LOADER_LIBRARY_TCL, "tcl.rpl", 0},
{WUPS_LOADER_LIBRARY_TVE, "tve.rpl", 0},
{WUPS_LOADER_LIBRARY_UAC, "uac.rpl", 0},
{WUPS_LOADER_LIBRARY_UAC_RPL, "uac_rpl.rpl", 0},
{WUPS_LOADER_LIBRARY_USB_MIC, "usb_mic.rpl", 0},
{WUPS_LOADER_LIBRARY_UVC, "uvc.rpl", 0},
{WUPS_LOADER_LIBRARY_UVD, "uvd.rpl", 0},
{WUPS_LOADER_LIBRARY_VPAD, "vpad.rpl", 0},
{WUPS_LOADER_LIBRARY_VPADBASE, "vpadbase.rpl", 0},
{WUPS_LOADER_LIBRARY_ZLIB125, "zlib125.rpl", 0}
};
void new_PatchInvidualMethodHooks(plugin_info_t * plugin_data) {
void new_PatchInvidualMethodHooks(plugin_info_t *plugin_data) {
new_resetLibs();
DEBUG_FUNCTION_LINE("Patching %d given functions",plugin_data->number_used_functions);
DEBUG_FUNCTION_LINE("Patching %d given functions", plugin_data->number_used_functions);
int32_t method_hooks_count = plugin_data->number_used_functions;
uint32_t skip_instr = 1;
uint32_t my_instr_len = 6;
uint32_t instr_len = my_instr_len + skip_instr + 6;
uint32_t flush_len = 4*instr_len;
for(int32_t i = 0; i < method_hooks_count; i++) {
replacement_data_function_t * function_data = &plugin_data->functions[i];
uint32_t flush_len = 4 * instr_len;
for (int32_t i = 0; i < method_hooks_count; i++) {
replacement_data_function_t *function_data = &plugin_data->functions[i];
/* Patch branches to it. */
volatile uint32_t *space = function_data->replace_data;
DEBUG_FUNCTION_LINE("Patching %s ...",function_data->function_name);
DEBUG_FUNCTION_LINE("Patching %s ...", function_data->function_name);
if(function_data->library == WUPS_LOADER_LIBRARY_OTHER) {
if (function_data->library == WUPS_LOADER_LIBRARY_OTHER) {
DEBUG_FUNCTION_LINE("Oh, using straight PA/VA");
if(function_data->alreadyPatched == 1) {
if (function_data->alreadyPatched == 1) {
DEBUG_FUNCTION_LINE("Skipping %s, its already patched", 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))) {
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.", function_data->function_name);
function_data->functionType = DYNAMIC_FUNCTION;
} else {
@ -141,63 +141,63 @@ void new_PatchInvidualMethodHooks(plugin_info_t * plugin_data) {
}
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 repl_addr = (uint32_t) function_data->replaceAddr;
uint32_t call_addr = (uint32_t) function_data->replaceCall;
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 (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");
DEBUG_FUNCTION_LINE("OSDynLoad_FindExport failed for %s\n", function_data->function_name);
continue;
}
if(DEBUG_LOG_DYN) {
DEBUG_FUNCTION_LINE("%s is located at %08X!\n", function_data->function_name,real_addr);
if (DEBUG_LOG_DYN) {
DEBUG_FUNCTION_LINE("%s is located at %08X!\n", function_data->function_name, real_addr);
}
if(function_data->library != WUPS_LOADER_LIBRARY_OTHER) {
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");
continue;
}
if(DEBUG_LOG_DYN) {
DEBUG_FUNCTION_LINE("%s physical is located at %08X!\n", function_data->function_name,physical);
if (DEBUG_LOG_DYN) {
DEBUG_FUNCTION_LINE("%s physical is located at %08X!\n", function_data->function_name, physical);
}
*(volatile uint32_t *)(call_addr) = (uint32_t)(space);
*(volatile uint32_t *) (call_addr) = (uint32_t) (space);
uint32_t targetAddr = (uint32_t)space;
if(targetAddr < 0x00800000 || targetAddr >= 0x01000000) {
uint32_t targetAddr = (uint32_t) space;
if (targetAddr < 0x00800000 || targetAddr >= 0x01000000) {
targetAddr = (uint32_t) OSEffectiveToPhysical(targetAddr);
}else{
} else {
targetAddr = targetAddr + 0x30800000 - 0x00800000;
}
KernelCopyData(targetAddr, physical, 4);
ICInvalidateRange((void*)(space), 4);
DCFlushRange((void*)(space), 4);
ICInvalidateRange((void *) (space), 4);
DCFlushRange((void *) (space), 4);
space++;
//Only works if skip_instr == 1
if(skip_instr == 1) {
if (skip_instr == 1) {
// fill the restore instruction section
function_data->realAddr = real_addr;
function_data->restoreInstruction = space[-1];
if(DEBUG_LOG_DYN) {
if (DEBUG_LOG_DYN) {
DEBUG_FUNCTION_LINE("function_data->realAddr = %08X!\n", function_data->realAddr);
}
if(DEBUG_LOG_DYN) {
DEBUG_FUNCTION_LINE("function_data->restoreInstruction = %08X!\n",function_data->restoreInstruction) ;
if (DEBUG_LOG_DYN) {
DEBUG_FUNCTION_LINE("function_data->restoreInstruction = %08X!\n", function_data->restoreInstruction);
}
} else {
log_printf("Error. Can't save %s for restoring!\n", function_data->function_name);
@ -215,7 +215,7 @@ void new_PatchInvidualMethodHooks(plugin_info_t * plugin_data) {
space++;
*space = 0x3C600000 | (((real_addr + (skip_instr * 4)) >> 16) & 0x0000FFFF); // lis r3, real_addr@h
space++;
*space = 0x60630000 | ((real_addr + (skip_instr * 4)) & 0x0000ffff); // ori r3, r3, real_addr@l
*space = 0x60630000 | ((real_addr + (skip_instr * 4)) & 0x0000ffff); // ori r3, r3, real_addr@l
space++;
*space = 0x7C6903A6; // mtctr r3
space++;
@ -230,7 +230,7 @@ void new_PatchInvidualMethodHooks(plugin_info_t * plugin_data) {
space++;
*space = 0x3C600000 | (((repl_addr) >> 16) & 0x0000FFFF); // lis r3, repl_addr@h
space++;
*space = 0x60630000 | ((repl_addr) & 0x0000ffff); // ori r3, r3, repl_addr@l
*space = 0x60630000 | ((repl_addr) & 0x0000ffff); // ori r3, r3, repl_addr@l
space++;
*space = 0x7C6903A6; // mtctr r3
space++;
@ -238,17 +238,17 @@ void new_PatchInvidualMethodHooks(plugin_info_t * plugin_data) {
space++;
*space = 0x4E800420; // bctr
space++;
DCFlushRange((void*)(((uint32_t) space) - flush_len),flush_len);
ICInvalidateRange((void*)(((uint32_t) space) - flush_len),flush_len);
DCFlushRange((void *) (((uint32_t) space) - flush_len), flush_len);
ICInvalidateRange((void *) (((uint32_t) space) - flush_len), flush_len);
//setting jump back
uint32_t replace_instr = 0x48000002 | (repl_addr_test & 0x03fffffc);
ICInvalidateRange(&replace_instr, 4);
DCFlushRange(&replace_instr, 4);
KernelCopyData(physical, (uint32_t)OSEffectiveToPhysical((uint32_t)&replace_instr), 4);
ICInvalidateRange((void*)(real_addr), 4);
DCFlushRange((void*)(real_addr), 4);
KernelCopyData(physical, (uint32_t) OSEffectiveToPhysical((uint32_t) &replace_instr), 4);
ICInvalidateRange((void *) (real_addr), 4);
DCFlushRange((void *) (real_addr), 4);
function_data->alreadyPatched = 1;
DEBUG_FUNCTION_LINE("done with patching %s!\n", function_data->function_name);
@ -260,64 +260,64 @@ void new_PatchInvidualMethodHooks(plugin_info_t * plugin_data) {
/* ****************************************************************** */
/* RESTORE ORIGINAL INSTRUCTIONS */
/* ****************************************************************** */
void new_RestoreInvidualInstructions(plugin_info_t * plugin_data) {
void new_RestoreInvidualInstructions(plugin_info_t *plugin_data) {
new_resetLibs();
DEBUG_FUNCTION_LINE("Restoring given functions!");
int32_t method_hooks_count = plugin_data->number_used_functions;
for(int32_t i = 0; i < method_hooks_count; i++) {
replacement_data_function_t * function_data = &plugin_data->functions[i];
for (int32_t i = 0; i < method_hooks_count; i++) {
replacement_data_function_t *function_data = &plugin_data->functions[i];
DEBUG_FUNCTION_LINE("Restoring %s... ",function_data->function_name);
if(function_data->restoreInstruction == 0 || function_data->realAddr == 0) {
DEBUG_FUNCTION_LINE("Restoring %s... ", function_data->function_name);
if (function_data->restoreInstruction == 0 || function_data->realAddr == 0) {
WHBLogPrintf("I dont have the information for the restore =( skip");
continue;
}
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 (function_data->library != WUPS_LOADER_LIBRARY_OTHER) {
real_addr = new_GetAddressOfFunction(function_data->function_name, function_data->library);
}
if(!real_addr) {
if (!real_addr) {
WHBLogPrintf("OSDynLoad_FindExport failed for %s", function_data->function_name);
continue;
}
uint32_t physical = function_data->physicalAddr;
if(function_data->library != WUPS_LOADER_LIBRARY_OTHER) {
physical = (uint32_t)OSEffectiveToPhysical(real_addr);
if (function_data->library != WUPS_LOADER_LIBRARY_OTHER) {
physical = (uint32_t) OSEffectiveToPhysical(real_addr);
}
if(!physical) {
if (!physical) {
WHBLogPrintf("Something is wrong with the physical address");
continue;
}
if((function_data->library != WUPS_LOADER_LIBRARY_OTHER) && new_isDynamicFunction(physical)) {
WHBLogPrintf("Its a dynamic function. We don't need to restore it!",function_data->function_name);
if ((function_data->library != WUPS_LOADER_LIBRARY_OTHER) && new_isDynamicFunction(physical)) {
WHBLogPrintf("Its a dynamic function. We don't need to restore it!", function_data->function_name);
} else {
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 (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",(uint32_t)function_data->restoreInstruction,physical);
if (DEBUG_LOG_DYN) {
DEBUG_FUNCTION_LINE("Restoring %08X to %08X", (uint32_t) function_data->restoreInstruction, physical);
}
uint32_t targetAddr = (uint32_t)&(function_data->restoreInstruction);
if(targetAddr < 0x00800000 || targetAddr >= 0x01000000) {
uint32_t targetAddr = (uint32_t) &(function_data->restoreInstruction);
if (targetAddr < 0x00800000 || targetAddr >= 0x01000000) {
targetAddr = (uint32_t) OSEffectiveToPhysical(targetAddr);
} else {
targetAddr = targetAddr + 0x30800000 - 0x00800000;
}
DEBUG_FUNCTION_LINE("Copy %d bytes from %08X to %08x", 4,targetAddr, physical);
DEBUG_FUNCTION_LINE("Copy %d bytes from %08X to %08x", 4, targetAddr, physical);
KernelCopyData(physical,targetAddr, 4);
if(DEBUG_LOG_DYN) {
DEBUG_FUNCTION_LINE("ICInvalidateRange %08X",(void*)function_data->realAddr);
KernelCopyData(physical, targetAddr, 4);
if (DEBUG_LOG_DYN) {
DEBUG_FUNCTION_LINE("ICInvalidateRange %08X", (void *) function_data->realAddr);
}
if(function_data->library != WUPS_LOADER_LIBRARY_OTHER) {
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);
}
WHBLogPrintf("done");
}
@ -328,27 +328,27 @@ void new_RestoreInvidualInstructions(plugin_info_t * plugin_data) {
}
int32_t new_isDynamicFunction(uint32_t physicalAddress) {
if((physicalAddress & 0x80000000) == 0x80000000) {
if ((physicalAddress & 0x80000000) == 0x80000000) {
return 1;
}
return 0;
}
uint32_t new_GetAddressOfFunction(const char * functionName,wups_loader_library_type_t library) {
uint32_t new_GetAddressOfFunction(const char *functionName, wups_loader_library_type_t library) {
uint32_t real_addr = 0;
OSDynLoad_Module rpl_handle = 0;
int32_t rpl_handles_size = sizeof rpl_handles / sizeof rpl_handles[0];
for(int32_t i = 0; i< rpl_handles_size; i++) {
if(rpl_handles[i].library == library) {
if(rpl_handles[i].handle == 0) {
DEBUG_FUNCTION_LINE("Lets acquire handle for rpl: %s\n",rpl_handles[i].rplname);
OSDynLoad_Acquire((char*) rpl_handles[i].rplname, &rpl_handles[i].handle);
for (int32_t i = 0; i < rpl_handles_size; i++) {
if (rpl_handles[i].library == library) {
if (rpl_handles[i].handle == 0) {
DEBUG_FUNCTION_LINE("Lets acquire handle for rpl: %s\n", rpl_handles[i].rplname);
OSDynLoad_Acquire((char *) rpl_handles[i].rplname, &rpl_handles[i].handle);
}
if(rpl_handles[i].handle == 0) {
log_printf("%s failed to acquire\n",rpl_handles[i].rplname);
if (rpl_handles[i].handle == 0) {
log_printf("%s failed to acquire\n", rpl_handles[i].rplname);
return 0;
}
rpl_handle = rpl_handles[i].handle;
@ -356,25 +356,25 @@ uint32_t new_GetAddressOfFunction(const char * functionName,wups_loader_library_
}
}
if(!rpl_handle) {
if (!rpl_handle) {
DEBUG_FUNCTION_LINE("Failed to find the RPL handle for %s\n", functionName);
return 0;
}
OSDynLoad_FindExport(rpl_handle, 0, functionName, reinterpret_cast<void **>(&real_addr));
if(!real_addr) {
if (!real_addr) {
DEBUG_FUNCTION_LINE("OSDynLoad_FindExport failed for %s\n", functionName);
return 0;
}
if((library == WUPS_LOADER_LIBRARY_NN_ACP) && (uint32_t)(*(volatile uint32_t*)(real_addr) & 0x48000002) == 0x48000000) {
uint32_t address_diff = (uint32_t)(*(volatile uint32_t*)(real_addr) & 0x03FFFFFC);
if((address_diff & 0x03000000) == 0x03000000) {
address_diff |= 0xFC000000;
if ((library == WUPS_LOADER_LIBRARY_NN_ACP) && (uint32_t) (*(volatile uint32_t *) (real_addr) & 0x48000002) == 0x48000000) {
uint32_t address_diff = (uint32_t) (*(volatile uint32_t *) (real_addr) & 0x03FFFFFC);
if ((address_diff & 0x03000000) == 0x03000000) {
address_diff |= 0xFC000000;
}
real_addr += (int32_t)address_diff;
if((uint32_t)(*(volatile uint32_t*)(real_addr) & 0x48000002) == 0x48000000) {
real_addr += (int32_t) address_diff;
if ((uint32_t) (*(volatile uint32_t *) (real_addr) & 0x48000002) == 0x48000000) {
return 0;
}
}
@ -385,9 +385,9 @@ uint32_t new_GetAddressOfFunction(const char * functionName,wups_loader_library_
void new_resetLibs() {
int32_t rpl_handles_size = sizeof rpl_handles / sizeof rpl_handles[0];
for(int32_t i = 0; i< rpl_handles_size; i++) {
if(rpl_handles[i].handle != 0) {
DEBUG_FUNCTION_LINE("Resetting handle for rpl: %s\n",rpl_handles[i].rplname);
for (int32_t i = 0; i < rpl_handles_size; i++) {
if (rpl_handles[i].handle != 0) {
DEBUG_FUNCTION_LINE("Resetting handle for rpl: %s\n", rpl_handles[i].rplname);
}
rpl_handles[i].handle = 0;
// Release handle?

View File

@ -39,9 +39,9 @@ struct rpl_handling {
};
void new_PatchInvidualMethodHooks(plugin_info_t * plugin_data);
void new_RestoreInvidualInstructions(plugin_info_t * plugin_data);
uint32_t new_GetAddressOfFunction(const char * functionName,wups_loader_library_type_t library);
void new_PatchInvidualMethodHooks(plugin_info_t *plugin_data);
void new_RestoreInvidualInstructions(plugin_info_t *plugin_data);
uint32_t new_GetAddressOfFunction(const char *functionName, wups_loader_library_type_t library);
int32_t new_isDynamicFunction(uint32_t physicalAddress);
void new_resetLibs();

View File

@ -8,7 +8,7 @@
#include <coreinit/core.h>
#include "hooks.h"
extern plugin_information_t * gPluginInformation;
extern plugin_information_t *gPluginInformation;
DECL(void, GX2WaitForVsync, void) {
CallHook(gPluginInformation, WUPS_LOADER_HOOK_VSYNC);
@ -28,18 +28,18 @@ void checkMagic(VPADStatus *buffer) {
// Check for rotation every only 5 frames.
angleX_frameCounter++;
if(angleX_frameCounter >= 5) {
if (angleX_frameCounter >= 5) {
// Get how much the gamepad rotated within the last 5 frames.
float diff_angle = -(buffer->angle.x - angleX_last);
// We want the gamepad to make (on average) at least 0.16% (1/6) of a full rotation per 5 frames (for 6 times in a row).
float target_diff = (0.16f);
// Calculate if rotated enough in this step (including the delta from the last step).
float total_diff = (diff_angle + angleX_delta) - target_diff;
if(total_diff > 0.0f) {
if (total_diff > 0.0f) {
// The rotation in this step was enough.
angleX_counter++;
// When the gamepad rotated ~0.16% for 6 times in a row we made a full rotation!
if(angleX_counter > 5) {
if (angleX_counter > 5) {
//ConfigUtils::openConfigMenu();
// reset stuff.
angleX_counter = 0;
@ -60,27 +60,28 @@ void checkMagic(VPADStatus *buffer) {
DECL(int32_t, VPADRead, int32_t chan, VPADStatus *buffer, uint32_t buffer_size, int32_t *error) {
int32_t result = real_VPADRead(chan, buffer, buffer_size, error);
if(result > 0 && (buffer[0].hold == (VPAD_BUTTON_PLUS | VPAD_BUTTON_R | VPAD_BUTTON_L)) && vpadPressCooldown == 0 && OSIsHomeButtonMenuEnabled()) {
if (result > 0 && (buffer[0].hold == (VPAD_BUTTON_PLUS | VPAD_BUTTON_R | VPAD_BUTTON_L)) && vpadPressCooldown == 0 && OSIsHomeButtonMenuEnabled()) {
//if(MemoryMapping::isMemoryMapped()) {
//MemoryMapping::readTestValuesFromMemory();
//MemoryMapping::readTestValuesFromMemory();
//} else {
// DEBUG_FUNCTION_LINE("Memory was not mapped. To test the memory please exit the plugin loader by pressing MINUS\n");
//}
vpadPressCooldown = 0x3C;
}
if(result > 0 && (buffer[0].hold == (VPAD_BUTTON_L | VPAD_BUTTON_DOWN | VPAD_BUTTON_MINUS)) && vpadPressCooldown == 0 && OSIsHomeButtonMenuEnabled()) {
if (result > 0 && (buffer[0].hold == (VPAD_BUTTON_L | VPAD_BUTTON_DOWN | VPAD_BUTTON_MINUS)) && vpadPressCooldown == 0 && OSIsHomeButtonMenuEnabled()) {
//ConfigUtils::openConfigMenu();
vpadPressCooldown = 0x3C;
} else if(result > 0 && OSIsHomeButtonMenuEnabled()) {
} else if (result > 0 && OSIsHomeButtonMenuEnabled()) {
checkMagic(buffer);
}
if(vpadPressCooldown > 0) {
if (vpadPressCooldown > 0) {
vpadPressCooldown--;
}
return result;
}
/*
void setupContextState() {
g_vid_ownContextState = (GX2ContextState*)memalign(
@ -248,7 +249,7 @@ DECL_FUNCTION(void, GX2CopyColorBufferToScanBuffer, GX2ColorBuffer* cbuf, int32_
static uint32_t lastData0 = 0;
DECL(uint32_t, OSReceiveMessage, OSMessageQueue *queue, OSMessage *message, uint32_t flags) {
if(flags == 0x15154848) {
if (flags == 0x15154848) {
CallHook(gPluginInformation, WUPS_LOADER_HOOK_ACQUIRED_FOREGROUND);
CallHook(gPluginInformation, WUPS_LOADER_HOOK_APPLICATION_END);
CallHook(gPluginInformation, WUPS_LOADER_HOOK_FINI_WUT_DEVOPTAB);
@ -256,13 +257,13 @@ DECL(uint32_t, OSReceiveMessage, OSMessageQueue *queue, OSMessage *message, uint
//DCFlushRange(&gInBackground,4);
return false;
}
int32_t res = real_OSReceiveMessage(queue, message, flags);
if(queue == OSGetSystemMessageQueue()) {
if(message != NULL) {
if(lastData0 != message->args[0]) {
if(message->args[0] == 0xFACEF000) {
int32_t res = real_OSReceiveMessage(queue, message, flags);
if (queue == OSGetSystemMessageQueue()) {
if (message != NULL) {
if (lastData0 != message->args[0]) {
if (message->args[0] == 0xFACEF000) {
CallHook(gPluginInformation, WUPS_LOADER_HOOK_ACQUIRED_FOREGROUND);
} else if(message->args[0] == 0xD1E0D1E0) {
} else if (message->args[0] == 0xD1E0D1E0) {
CallHook(gPluginInformation, WUPS_LOADER_HOOK_APPLICATION_END);
//CallHook(gPluginInformation, WUPS_LOADER_HOOK_FINI_WUT_DEVOPTAB);
//gInBackground = false;
@ -277,25 +278,25 @@ DECL(uint32_t, OSReceiveMessage, OSMessageQueue *queue, OSMessage *message, uint
}
DECL(void, OSReleaseForeground) {
if(OSGetCoreId() == 1) {
if (OSGetCoreId() == 1) {
CallHook(gPluginInformation, WUPS_LOADER_HOOK_RELEASE_FOREGROUND);
}
real_OSReleaseForeground();
}
hooks_magic_t method_hooks_hooks_static[] __attribute__((section(".data"))) = {
//MAKE_MAGIC(GX2SetTVBuffer, LIB_GX2, STATIC_FUNCTION),
//MAKE_MAGIC(GX2SetDRCBuffer, LIB_GX2, STATIC_FUNCTION),
//MAKE_MAGIC(GX2WaitForVsync, LIB_GX2, STATIC_FUNCTION),
//MAKE_MAGIC(GX2CopyColorBufferToScanBuffer, LIB_GX2, STATIC_FUNCTION),
//MAKE_MAGIC(GX2SetContextState, LIB_GX2, STATIC_FUNCTION),
MAKE_MAGIC(VPADRead, LIB_VPAD, STATIC_FUNCTION),
//MAKE_MAGIC(OSIsAddressValid, LIB_CORE_INIT, STATIC_FUNCTION),
//MAKE_MAGIC(__OSPhysicalToEffectiveUncached, LIB_CORE_INIT, STATIC_FUNCTION),
//MAKE_MAGIC(__OSPhysicalToEffectiveCached, LIB_CORE_INIT, STATIC_FUNCTION),
//MAKE_MAGIC(OSEffectiveToPhysical, LIB_CORE_INIT, STATIC_FUNCTION),
MAKE_MAGIC(OSReceiveMessage, LIB_CORE_INIT, STATIC_FUNCTION),
MAKE_MAGIC(OSReleaseForeground, LIB_CORE_INIT, STATIC_FUNCTION)
//MAKE_MAGIC(GX2SetTVBuffer, LIB_GX2, STATIC_FUNCTION),
//MAKE_MAGIC(GX2SetDRCBuffer, LIB_GX2, STATIC_FUNCTION),
//MAKE_MAGIC(GX2WaitForVsync, LIB_GX2, STATIC_FUNCTION),
//MAKE_MAGIC(GX2CopyColorBufferToScanBuffer, LIB_GX2, STATIC_FUNCTION),
//MAKE_MAGIC(GX2SetContextState, LIB_GX2, STATIC_FUNCTION),
MAKE_MAGIC(VPADRead, LIB_VPAD, STATIC_FUNCTION),
//MAKE_MAGIC(OSIsAddressValid, LIB_CORE_INIT, STATIC_FUNCTION),
//MAKE_MAGIC(__OSPhysicalToEffectiveUncached, LIB_CORE_INIT, STATIC_FUNCTION),
//MAKE_MAGIC(__OSPhysicalToEffectiveCached, LIB_CORE_INIT, STATIC_FUNCTION),
//MAKE_MAGIC(OSEffectiveToPhysical, LIB_CORE_INIT, STATIC_FUNCTION),
MAKE_MAGIC(OSReceiveMessage, LIB_CORE_INIT, STATIC_FUNCTION),
MAKE_MAGIC(OSReleaseForeground, LIB_CORE_INIT, STATIC_FUNCTION)
};
uint32_t method_hooks_size_hooks_static __attribute__((section(".data"))) = sizeof(method_hooks_hooks_static) / sizeof(hooks_magic_t);

View File

@ -6,26 +6,26 @@
#include "utils/logger.h"
#include "common/plugin_defines.h"
dyn_linking_function_t * DynamicLinkingHelper::getOrAddFunctionEntryByName(dyn_linking_relocation_data_t * data, const char* functionName) {
if(data == NULL) {
dyn_linking_function_t *DynamicLinkingHelper::getOrAddFunctionEntryByName(dyn_linking_relocation_data_t *data, const char *functionName) {
if (data == NULL) {
return NULL;
}
if(functionName == NULL) {
if (functionName == NULL) {
return NULL;
}
dyn_linking_function_t * result = NULL;
for(int32_t i = 0; i < DYN_LINK_FUNCTION_LIST_LENGTH; i++) {
dyn_linking_function_t * curEntry = &(data->functions[i]);
if(strlen(curEntry->functionName) == 0) {
if(strlen(functionName) > DYN_LINK_FUNCTION_NAME_LENGTH) {
dyn_linking_function_t *result = NULL;
for (int32_t i = 0; i < DYN_LINK_FUNCTION_LIST_LENGTH; i++) {
dyn_linking_function_t *curEntry = &(data->functions[i]);
if (strlen(curEntry->functionName) == 0) {
if (strlen(functionName) > DYN_LINK_FUNCTION_NAME_LENGTH) {
DEBUG_FUNCTION_LINE("Failed to add function name, it's too long.\n");
return NULL;
}
strncpy(curEntry->functionName,functionName,DYN_LINK_FUNCTION_NAME_LENGTH);
strncpy(curEntry->functionName, functionName, DYN_LINK_FUNCTION_NAME_LENGTH);
result = curEntry;
break;
}
if(strncmp(curEntry->functionName,functionName,DYN_LINK_FUNCTION_NAME_LENGTH) == 0) {
if (strncmp(curEntry->functionName, functionName, DYN_LINK_FUNCTION_NAME_LENGTH) == 0) {
result = curEntry;
break;
}
@ -33,68 +33,71 @@ dyn_linking_function_t * DynamicLinkingHelper::getOrAddFunctionEntryByName(dyn_l
return result;
}
dyn_linking_import_t * DynamicLinkingHelper::getOrAddFunctionImportByName(dyn_linking_relocation_data_t * data, const char* importName) {
dyn_linking_import_t *DynamicLinkingHelper::getOrAddFunctionImportByName(dyn_linking_relocation_data_t *data, const char *importName) {
return getOrAddImport(data, importName, false);
}
dyn_linking_import_t * DynamicLinkingHelper::getOrAddDataImportByName(dyn_linking_relocation_data_t * data, const char* importName) {
dyn_linking_import_t *DynamicLinkingHelper::getOrAddDataImportByName(dyn_linking_relocation_data_t *data, const char *importName) {
return getOrAddImport(data, importName, true);
}
dyn_linking_import_t * DynamicLinkingHelper::getOrAddImport(dyn_linking_relocation_data_t * data, const char* importName, bool isData) {
if(importName == NULL || data == NULL) {
dyn_linking_import_t *DynamicLinkingHelper::getOrAddImport(dyn_linking_relocation_data_t *data, const char *importName, bool isData) {
if (importName == NULL || data == NULL) {
return NULL;
}
dyn_linking_import_t * result = NULL;
for(int32_t i = 0; i < DYN_LINK_IMPORT_LIST_LENGTH; i++) {
dyn_linking_import_t * curEntry = &(data->imports[i]);
if(strlen(curEntry->importName) == 0) {
if(strlen(importName) > DYN_LINK_IMPORT_NAME_LENGTH) {
dyn_linking_import_t *result = NULL;
for (int32_t i = 0; i < DYN_LINK_IMPORT_LIST_LENGTH; i++) {
dyn_linking_import_t *curEntry = &(data->imports[i]);
if (strlen(curEntry->importName) == 0) {
if (strlen(importName) > DYN_LINK_IMPORT_NAME_LENGTH) {
DEBUG_FUNCTION_LINE("Failed to add Import, it's too long.\n");
return NULL;
}
strncpy(curEntry->importName,importName,DYN_LINK_IMPORT_NAME_LENGTH);
strncpy(curEntry->importName, importName, DYN_LINK_IMPORT_NAME_LENGTH);
curEntry->isData = isData;
result = curEntry;
break;
}
if(strncmp(curEntry->importName,importName,DYN_LINK_IMPORT_NAME_LENGTH) == 0 && (curEntry->isData == isData)) {
if (strncmp(curEntry->importName, importName, DYN_LINK_IMPORT_NAME_LENGTH) == 0 && (curEntry->isData == isData)) {
return curEntry;
}
}
return result;
}
bool DynamicLinkingHelper::addReloationEntry(dyn_linking_relocation_data_t * linking_data, dyn_linking_relocation_entry_t * linking_entries, uint32_t linking_entry_length, const RelocationData& relocationData) {
return addReloationEntry(linking_data, linking_entries, linking_entry_length, relocationData.getType(), relocationData.getOffset(), relocationData.getAddend(), relocationData.getDestination(), relocationData.getName(), relocationData.getImportRPLInformation());
bool DynamicLinkingHelper::addReloationEntry(dyn_linking_relocation_data_t *linking_data, dyn_linking_relocation_entry_t *linking_entries, uint32_t linking_entry_length, const RelocationData &relocationData) {
return addReloationEntry(linking_data, linking_entries, linking_entry_length, relocationData.getType(), relocationData.getOffset(), relocationData.getAddend(), relocationData.getDestination(), relocationData.getName(),
relocationData.getImportRPLInformation());
}
bool DynamicLinkingHelper::addReloationEntry(dyn_linking_relocation_data_t * linking_data, dyn_linking_relocation_entry_t * linking_entries, uint32_t linking_entry_length, char type, size_t offset, int32_t addend, const void *destination, const std::string& name, const ImportRPLInformation& rplInfo) {
dyn_linking_import_t * importInfoGbl = DynamicLinkingHelper::getOrAddImport(linking_data, rplInfo.getName().c_str(),rplInfo.isData());
if(importInfoGbl == NULL) {
DEBUG_FUNCTION_LINE("Getting import info failed. Probably maximum of %d rpl files to import reached.\n",DYN_LINK_IMPORT_LIST_LENGTH);
bool DynamicLinkingHelper::addReloationEntry(dyn_linking_relocation_data_t *linking_data, dyn_linking_relocation_entry_t *linking_entries, uint32_t linking_entry_length, char type, size_t offset, int32_t addend, const void *destination,
const std::string &name, const ImportRPLInformation &rplInfo) {
dyn_linking_import_t *importInfoGbl = DynamicLinkingHelper::getOrAddImport(linking_data, rplInfo.getName().c_str(), rplInfo.isData());
if (importInfoGbl == NULL) {
DEBUG_FUNCTION_LINE("Getting import info failed. Probably maximum of %d rpl files to import reached.\n", DYN_LINK_IMPORT_LIST_LENGTH);
return false;
}
dyn_linking_function_t * functionInfo = DynamicLinkingHelper::getOrAddFunctionEntryByName(linking_data, name.c_str());
if(functionInfo == NULL) {
DEBUG_FUNCTION_LINE("Getting import info failed. Probably maximum of %d function to be relocated reached.\n",DYN_LINK_FUNCTION_LIST_LENGTH);
dyn_linking_function_t *functionInfo = DynamicLinkingHelper::getOrAddFunctionEntryByName(linking_data, name.c_str());
if (functionInfo == NULL) {
DEBUG_FUNCTION_LINE("Getting import info failed. Probably maximum of %d function to be relocated reached.\n", DYN_LINK_FUNCTION_LIST_LENGTH);
return false;
}
return addReloationEntry(linking_entries, linking_entry_length, type, offset, addend, destination, functionInfo, importInfoGbl);
}
bool DynamicLinkingHelper::addReloationEntry(dyn_linking_relocation_entry_t * linking_entries, uint32_t linking_entry_length, char type, size_t offset, int32_t addend, const void *destination, dyn_linking_function_t * functionName, dyn_linking_import_t * importInfo) {
for(uint32_t i = 0; i < linking_entry_length; i++) {
dyn_linking_relocation_entry_t * curEntry = &(linking_entries[i]);
if(curEntry->functionEntry != NULL) {
bool DynamicLinkingHelper::addReloationEntry(dyn_linking_relocation_entry_t *linking_entries, uint32_t linking_entry_length, char type, size_t offset, int32_t addend, const void *destination, dyn_linking_function_t *functionName,
dyn_linking_import_t *importInfo) {
for (uint32_t i = 0; i < linking_entry_length; i++) {
dyn_linking_relocation_entry_t *curEntry = &(linking_entries[i]);
if (curEntry->functionEntry != NULL) {
continue;
}
curEntry->type = type;
curEntry->offset = offset;
curEntry->addend = addend;
curEntry->destination = (void*) destination;
curEntry->destination = (void *) destination;
curEntry->functionEntry = functionName;
curEntry->importEntry = importInfo;
return true;

View File

@ -1,4 +1,5 @@
#pragma once
#include "common/dynamic_linking_defines.h"
#include "utils/logger.h"
#include <string>
@ -13,7 +14,7 @@ public:
\param functionName Name of the function
\return Returns a pointer to the entry which contains the functionName. Null on error or if the list full.
**/
static dyn_linking_function_t * getOrAddFunctionEntryByName(dyn_linking_relocation_data_t * data, const char * functionName);
static dyn_linking_function_t *getOrAddFunctionEntryByName(dyn_linking_relocation_data_t *data, const char *functionName);
/**
Gets the function import entry for a given function name. If the import is not present in the list, it will be added.
@ -22,7 +23,7 @@ public:
\param importName Name of the function
\return Returns a pointer to the function import entry which contains the importName. Null on error or if the list full.
**/
static dyn_linking_import_t * getOrAddFunctionImportByName(dyn_linking_relocation_data_t * data, const char * importName);
static dyn_linking_import_t *getOrAddFunctionImportByName(dyn_linking_relocation_data_t *data, const char *importName);
/**
@ -32,7 +33,7 @@ public:
\param importName Name of the data
\return Returns a pointer to the data import entry which contains the importName. Null on error or if the list full.
**/
static dyn_linking_import_t * getOrAddDataImportByName(dyn_linking_relocation_data_t * data, const char * importName);
static dyn_linking_import_t *getOrAddDataImportByName(dyn_linking_relocation_data_t *data, const char *importName);
/**
@ -44,13 +45,17 @@ public:
\return Returns a pointer to the data import entry which contains the importName. Null on error or if the list full.
**/
static dyn_linking_import_t * getOrAddImport(dyn_linking_relocation_data_t * data, const char * importName, bool isData);
static dyn_linking_import_t *getOrAddImport(dyn_linking_relocation_data_t *data, const char *importName, bool isData);
static bool addReloationEntry(dyn_linking_relocation_data_t * linking_data, dyn_linking_relocation_entry_t * linking_entries, uint32_t linking_entry_length, const RelocationData& relocationData);
static bool addReloationEntry(dyn_linking_relocation_data_t *linking_data, dyn_linking_relocation_entry_t *linking_entries, uint32_t linking_entry_length, const RelocationData &relocationData);
static bool addReloationEntry(dyn_linking_relocation_data_t * linking_data, dyn_linking_relocation_entry_t * linking_entries, uint32_t linking_entry_length, char type, size_t offset, int32_t addend, const void *destination, const std::string& name, const ImportRPLInformation& rplInfo);
static bool
addReloationEntry(dyn_linking_relocation_data_t *linking_data, dyn_linking_relocation_entry_t *linking_entries, uint32_t linking_entry_length, char type, size_t offset, int32_t addend, const void *destination, const std::string &name,
const ImportRPLInformation &rplInfo);
static bool addReloationEntry(dyn_linking_relocation_entry_t *linking_entries, uint32_t linking_entry_length, char type, size_t offset, int32_t addend, const void *destination, dyn_linking_function_t *functionName,
dyn_linking_import_t *importInfo);
static bool addReloationEntry(dyn_linking_relocation_entry_t * linking_entries, uint32_t linking_entry_length, char type, size_t offset, int32_t addend, const void *destination, dyn_linking_function_t * functionName, dyn_linking_import_t * importInfo);
private:
DynamicLinkingHelper() {
}

View File

@ -22,7 +22,7 @@
class FunctionData {
public:
FunctionData(void * paddress, void * vaddress, const std::string& name, wups_loader_library_type_t library, void * replaceAddr, void * replaceCall) {
FunctionData(void *paddress, void *vaddress, const std::string &name, wups_loader_library_type_t library, void *replaceAddr, void *replaceCall) {
this->paddress = paddress;
this->vaddress = vaddress;
this->name = name;
@ -35,35 +35,36 @@ public:
}
const std::string& getName() const{
const std::string &getName() const {
return this->name;
}
wups_loader_library_type_t getLibrary() const{
wups_loader_library_type_t getLibrary() const {
return this->library;
}
const void * getPhysicalAddress() const{
const void *getPhysicalAddress() const {
return paddress;
}
const void * getVirtualAddress() const{
const void *getVirtualAddress() const {
return vaddress;
}
const void * getReplaceAddress() const{
const void *getReplaceAddress() const {
return replaceAddr;
}
const void * getReplaceCall() const{
const void *getReplaceCall() const {
return replaceCall;
}
private:
void * paddress = NULL;
void * vaddress = NULL;
void *paddress = NULL;
void *vaddress = NULL;
std::string name;
wups_loader_library_type_t library;
void * replaceAddr = NULL;
void * replaceCall = NULL;
void *replaceAddr = NULL;
void *replaceCall = NULL;
};

View File

@ -23,7 +23,7 @@
class HookData {
public:
HookData(void * function_pointer, wups_loader_hook_type_t type) {
HookData(void *function_pointer, wups_loader_hook_type_t type) {
this->function_pointer = function_pointer;
this->type = type;
}
@ -32,14 +32,15 @@ public:
}
void * getFunctionPointer() const{
void *getFunctionPointer() const {
return function_pointer;
}
wups_loader_hook_type_t getType() const{
wups_loader_hook_type_t getType() const {
return this->type;
}
private:
void * function_pointer;
void *function_pointer;
wups_loader_hook_type_t type;
};

View File

@ -35,7 +35,7 @@ public:
return name;
}
bool isData() const{
bool isData() const {
return _isData;
}

View File

@ -23,30 +23,31 @@
class PluginContainer {
public:
PluginContainer(){
PluginContainer() {
}
const PluginMetaInformation& getMetaInformation() const{
const PluginMetaInformation &getMetaInformation() const {
return this->metaInformation;
}
void setMetaInformation(PluginMetaInformation& metaInfo){
void setMetaInformation(PluginMetaInformation &metaInfo) {
this->metaInformation = metaInfo;
}
const PluginInformation& getPluginInformation() const{
const PluginInformation &getPluginInformation() const {
return pluginInformation;
}
void setPluginInformation(PluginInformation& pluginInformation){
void setPluginInformation(PluginInformation &pluginInformation) {
this->pluginInformation = pluginInformation;
}
const PluginData& getPluginData() const{
const PluginData &getPluginData() const {
return pluginData;
}
void setPluginData(PluginData& pluginData){
void setPluginData(PluginData &pluginData) {
this->pluginData = pluginData;
}

View File

@ -9,7 +9,7 @@
#include "PluginInformation.h"
#include "RelocationData.h"
bool PluginContainerPersistence::savePlugin(plugin_information_t * pluginInformation, PluginContainer& plugin) {
bool PluginContainerPersistence::savePlugin(plugin_information_t *pluginInformation, PluginContainer &plugin) {
int32_t plugin_count = pluginInformation->number_used_plugins;
@ -17,50 +17,50 @@ bool PluginContainerPersistence::savePlugin(plugin_information_t * pluginInforma
//auto pluginPath = plugin.getMetaInformation().getPath();
if(plugin_count >= MAXIMUM_PLUGINS - 1) {
if (plugin_count >= MAXIMUM_PLUGINS - 1) {
DEBUG_FUNCTION_LINE("Maximum of %d plugins reached. %s won't be loaded!\n", MAXIMUM_PLUGINS, pluginName.c_str());
return false;
}
// Copy data to global struct.
plugin_information_single_t * plugin_data = &(pluginInformation->plugin_data[plugin_count]);
plugin_information_single_t *plugin_data = &(pluginInformation->plugin_data[plugin_count]);
DEBUG_FUNCTION_LINE("%08X", plugin_data);
// Make sure everything is reset.
//plugin_data = {};
memset((void*)plugin_data, 0, sizeof(plugin_information_single_t));
memset((void *) plugin_data, 0, sizeof(plugin_information_single_t));
auto pluginMetaInfo = plugin.getMetaInformation();
auto plugin_meta_data = &plugin_data->meta;
auto plugin_meta_data = &plugin_data->meta;
if(pluginMetaInfo.getName().size() >= MAXIMUM_PLUGIN_META_FIELD_LENGTH) {
if (pluginMetaInfo.getName().size() >= MAXIMUM_PLUGIN_META_FIELD_LENGTH) {
DEBUG_FUNCTION_LINE("Warning: name will be truncated.");
}
strncpy(plugin_meta_data->name, pluginMetaInfo.getName().c_str(), MAXIMUM_PLUGIN_META_FIELD_LENGTH-1);
if(pluginMetaInfo.getAuthor().size() >= MAXIMUM_PLUGIN_META_FIELD_LENGTH) {
strncpy(plugin_meta_data->name, pluginMetaInfo.getName().c_str(), MAXIMUM_PLUGIN_META_FIELD_LENGTH - 1);
if (pluginMetaInfo.getAuthor().size() >= MAXIMUM_PLUGIN_META_FIELD_LENGTH) {
DEBUG_FUNCTION_LINE("Warning: author will be truncated.");
}
strncpy(plugin_meta_data->author, pluginMetaInfo.getAuthor().c_str(), MAXIMUM_PLUGIN_META_FIELD_LENGTH-1);
strncpy(plugin_meta_data->author, pluginMetaInfo.getAuthor().c_str(), MAXIMUM_PLUGIN_META_FIELD_LENGTH - 1);
if(pluginMetaInfo.getVersion().size() >= MAXIMUM_PLUGIN_META_FIELD_LENGTH) {
if (pluginMetaInfo.getVersion().size() >= MAXIMUM_PLUGIN_META_FIELD_LENGTH) {
DEBUG_FUNCTION_LINE("Warning: version will be truncated.");
}
strncpy(plugin_meta_data->version, pluginMetaInfo.getVersion().c_str(), MAXIMUM_PLUGIN_META_FIELD_LENGTH-1);
strncpy(plugin_meta_data->version, pluginMetaInfo.getVersion().c_str(), MAXIMUM_PLUGIN_META_FIELD_LENGTH - 1);
if(pluginMetaInfo.getLicense().size() >= MAXIMUM_PLUGIN_META_FIELD_LENGTH) {
if (pluginMetaInfo.getLicense().size() >= MAXIMUM_PLUGIN_META_FIELD_LENGTH) {
DEBUG_FUNCTION_LINE("Warning: license will be truncated.");
}
strncpy(plugin_meta_data->license, pluginMetaInfo.getLicense().c_str(), MAXIMUM_PLUGIN_META_FIELD_LENGTH-1);
strncpy(plugin_meta_data->license, pluginMetaInfo.getLicense().c_str(), MAXIMUM_PLUGIN_META_FIELD_LENGTH - 1);
if(pluginMetaInfo.getBuildTimestamp().size() >= MAXIMUM_PLUGIN_META_FIELD_LENGTH) {
if (pluginMetaInfo.getBuildTimestamp().size() >= MAXIMUM_PLUGIN_META_FIELD_LENGTH) {
DEBUG_FUNCTION_LINE("Warning: build timestampt will be truncated.");
}
strncpy(plugin_meta_data->buildTimestamp, pluginMetaInfo.getBuildTimestamp().c_str(), MAXIMUM_PLUGIN_META_FIELD_LENGTH-1);
strncpy(plugin_meta_data->buildTimestamp, pluginMetaInfo.getBuildTimestamp().c_str(), MAXIMUM_PLUGIN_META_FIELD_LENGTH - 1);
if(pluginMetaInfo.getDescription().size() >= MAXIMUM_PLUGIN_DESCRIPTION_LENGTH) {
if (pluginMetaInfo.getDescription().size() >= MAXIMUM_PLUGIN_DESCRIPTION_LENGTH) {
DEBUG_FUNCTION_LINE("Warning: description will be truncated.");
DEBUG_FUNCTION_LINE("%s", pluginMetaInfo.getDescription().c_str());
}
strncpy(plugin_meta_data->descripion, pluginMetaInfo.getDescription().c_str(), MAXIMUM_PLUGIN_DESCRIPTION_LENGTH-1);
strncpy(plugin_meta_data->descripion, pluginMetaInfo.getDescription().c_str(), MAXIMUM_PLUGIN_DESCRIPTION_LENGTH - 1);
plugin_meta_data->size = pluginMetaInfo.getSize();
@ -69,8 +69,8 @@ bool PluginContainerPersistence::savePlugin(plugin_information_t * pluginInforma
// Relocation
std::vector<RelocationData> relocationData = pluginInfo.getRelocationDataList();
for (auto & reloc : relocationData) {
if(!DynamicLinkingHelper::addReloationEntry(&(pluginInformation->linking_data), plugin_data->info.linking_entries, PLUGIN_DYN_LINK_RELOCATION_LIST_LENGTH, reloc)) {
for (auto &reloc : relocationData) {
if (!DynamicLinkingHelper::addReloationEntry(&(pluginInformation->linking_data), plugin_data->info.linking_entries, PLUGIN_DYN_LINK_RELOCATION_LIST_LENGTH, reloc)) {
DEBUG_FUNCTION_LINE("Failed to add a relocation entry");
return false;
}
@ -81,32 +81,32 @@ bool PluginContainerPersistence::savePlugin(plugin_information_t * pluginInforma
std::vector<HookData> hook_data_list = pluginInfo.getHookDataList();
if(function_data_list.size() > MAXIMUM_FUNCTION_PER_PLUGIN) {
DEBUG_FUNCTION_LINE("Plugin %s would replace to many function (%d, maximum is %d). It won't be loaded.",pluginName.c_str(), function_data_list.size(), MAXIMUM_FUNCTION_PER_PLUGIN);
if (function_data_list.size() > MAXIMUM_FUNCTION_PER_PLUGIN) {
DEBUG_FUNCTION_LINE("Plugin %s would replace to many function (%d, maximum is %d). It won't be loaded.", pluginName.c_str(), function_data_list.size(), MAXIMUM_FUNCTION_PER_PLUGIN);
return false;
}
if(hook_data_list.size() > MAXIMUM_HOOKS_PER_PLUGIN) {
if (hook_data_list.size() > MAXIMUM_HOOKS_PER_PLUGIN) {
DEBUG_FUNCTION_LINE("Plugin %s would set too many hooks (%d, maximum is %d). It won't be loaded.", pluginName.c_str(), hook_data_list.size(), MAXIMUM_HOOKS_PER_PLUGIN);
return false;
}
if(pluginName.length() > MAXIMUM_PLUGIN_NAME_LENGTH-1) {
if (pluginName.length() > MAXIMUM_PLUGIN_NAME_LENGTH - 1) {
DEBUG_FUNCTION_LINE("Name for plugin %s was too long to be stored.", pluginName.c_str());
return false;
}
/* Store function replacement information */
uint32_t i = 0;
for(auto & curFunction : pluginInfo.getFunctionDataList()) {
replacement_data_function_t * function_data = &plugin_data->info.functions[i];
if(strlen(curFunction.getName().c_str()) > MAXIMUM_FUNCTION_NAME_LENGTH-1) {
for (auto &curFunction : pluginInfo.getFunctionDataList()) {
replacement_data_function_t *function_data = &plugin_data->info.functions[i];
if (strlen(curFunction.getName().c_str()) > MAXIMUM_FUNCTION_NAME_LENGTH - 1) {
DEBUG_FUNCTION_LINE("Could not add function \"%s\" for plugin \"%s\" function name is too long.", curFunction.getName().c_str(), pluginName.c_str());
continue;
}
DEBUG_FUNCTION_LINE("Adding function \"%s\" for plugin \"%s\"",curFunction.getName().c_str(), pluginName.c_str());
DEBUG_FUNCTION_LINE("Adding function \"%s\" for plugin \"%s\"", curFunction.getName().c_str(), pluginName.c_str());
strncpy(function_data->function_name, curFunction.getName().c_str(),MAXIMUM_FUNCTION_NAME_LENGTH-1);
strncpy(function_data->function_name, curFunction.getName().c_str(), MAXIMUM_FUNCTION_NAME_LENGTH - 1);
function_data->library = curFunction.getLibrary();
function_data->replaceAddr = (uint32_t) curFunction.getReplaceAddress();
@ -119,37 +119,37 @@ bool PluginContainerPersistence::savePlugin(plugin_information_t * pluginInforma
}
i = 0;
for(auto & curHook : pluginInfo.getHookDataList()) {
replacement_data_hook_t * hook_data = &plugin_data->info.hooks[i];
for (auto &curHook : pluginInfo.getHookDataList()) {
replacement_data_hook_t *hook_data = &plugin_data->info.hooks[i];
DEBUG_FUNCTION_LINE("Set hook for plugin \"%s\" of type %08X to target %08X",plugin_data->meta.name, curHook.getType(),(void*) curHook.getFunctionPointer());
DEBUG_FUNCTION_LINE("Set hook for plugin \"%s\" of type %08X to target %08X", plugin_data->meta.name, curHook.getType(), (void *) curHook.getFunctionPointer());
hook_data->func_pointer = (void*) curHook.getFunctionPointer();
hook_data->type = curHook.getType();
hook_data->func_pointer = (void *) curHook.getFunctionPointer();
hook_data->type = curHook.getType();
plugin_data->info.number_used_hooks++;
i++;
}
/* Saving SectionInfos */
for(auto & curSection : pluginInfo.getSectionInfoList()) {
for (auto &curSection : pluginInfo.getSectionInfoList()) {
bool foundFreeSlot = false;
uint32_t slot = 0;
for(uint32_t i = 0; i < MAXIMUM_PLUGIN_SECTION_LENGTH; i++) {
plugin_section_info_t * sectionInfo = &(plugin_data->info.sectionInfos[i]);
if(sectionInfo->addr == 0 && sectionInfo->size == 0) {
for (uint32_t i = 0; i < MAXIMUM_PLUGIN_SECTION_LENGTH; i++) {
plugin_section_info_t *sectionInfo = &(plugin_data->info.sectionInfos[i]);
if (sectionInfo->addr == 0 && sectionInfo->size == 0) {
foundFreeSlot = true;
slot = i;
break;
}
}
if(foundFreeSlot) {
plugin_section_info_t * sectionInfo = &(plugin_data->info.sectionInfos[slot]);
if(strlen(curSection.first.c_str()) > MAXIMUM_PLUGIN_SECTION_NAME_LENGTH-1) {
DEBUG_FUNCTION_LINE("Could not add section info \"%s\" for plugin \"%s\" section name is too long.",curSection.first.c_str(), pluginName.c_str());
if (foundFreeSlot) {
plugin_section_info_t *sectionInfo = &(plugin_data->info.sectionInfos[slot]);
if (strlen(curSection.first.c_str()) > MAXIMUM_PLUGIN_SECTION_NAME_LENGTH - 1) {
DEBUG_FUNCTION_LINE("Could not add section info \"%s\" for plugin \"%s\" section name is too long.", curSection.first.c_str(), pluginName.c_str());
break;
}
strncpy(sectionInfo->name, curSection.first.c_str(), MAXIMUM_PLUGIN_SECTION_NAME_LENGTH-1);
strncpy(sectionInfo->name, curSection.first.c_str(), MAXIMUM_PLUGIN_SECTION_NAME_LENGTH - 1);
sectionInfo->addr = curSection.second.getAddress();
sectionInfo->size = curSection.second.getSize();
@ -165,42 +165,42 @@ bool PluginContainerPersistence::savePlugin(plugin_information_t * pluginInforma
/* Copy plugin data */
auto pluginData = plugin.getPluginData();
auto plugin_data_data = &plugin_data->data;
auto plugin_data_data = &plugin_data->data;
plugin_data_data->buffer = (char*)pluginData.buffer;
plugin_data_data->buffer = (char *) pluginData.buffer;
plugin_data_data->bufferLength = pluginData.length;
plugin_data_data->memoryType = pluginData.memoryType;
plugin_data_data->heapHandle = (int)pluginData.heapHandle;
plugin_data_data->heapHandle = (int) pluginData.heapHandle;
pluginInformation->number_used_plugins++;
DCFlushRange((void*)pluginInformation,sizeof(plugin_information_t));
ICInvalidateRange((void*)pluginInformation,sizeof(plugin_information_t));
DCFlushRange((void *) pluginInformation, sizeof(plugin_information_t));
ICInvalidateRange((void *) pluginInformation, sizeof(plugin_information_t));
return true;
}
std::vector<PluginContainer> PluginContainerPersistence::loadPlugins(plugin_information_t * pluginInformation) {
std::vector<PluginContainer> PluginContainerPersistence::loadPlugins(plugin_information_t *pluginInformation) {
std::vector<PluginContainer> result;
if(pluginInformation == NULL) {
if (pluginInformation == NULL) {
DEBUG_FUNCTION_LINE("pluginInformation == NULL");
return result;
}
DCFlushRange((void*)pluginInformation,sizeof(plugin_information_t));
ICInvalidateRange((void*)pluginInformation,sizeof(plugin_information_t));
DCFlushRange((void *) pluginInformation, sizeof(plugin_information_t));
ICInvalidateRange((void *) pluginInformation, sizeof(plugin_information_t));
int32_t plugin_count = pluginInformation->number_used_plugins;
if(plugin_count > MAXIMUM_PLUGINS) {
DEBUG_FUNCTION_LINE("pluginInformation->plugin_count was bigger then allowed. %d > %d. Limiting to %d",plugin_count, MAXIMUM_PLUGINS, MAXIMUM_PLUGINS);
if (plugin_count > MAXIMUM_PLUGINS) {
DEBUG_FUNCTION_LINE("pluginInformation->plugin_count was bigger then allowed. %d > %d. Limiting to %d", plugin_count, MAXIMUM_PLUGINS, MAXIMUM_PLUGINS);
plugin_count = MAXIMUM_PLUGINS;
}
for(int32_t i = 0; i < plugin_count; i++) {
for (int32_t i = 0; i < plugin_count; i++) {
// Copy data from struct.
plugin_information_single_t * plugin_data = &(pluginInformation->plugin_data[i]);
plugin_information_single_t *plugin_data = &(pluginInformation->plugin_data[i]);
PluginMetaInformation metaInformation;
plugin_meta_info_t * meta = &(plugin_data->meta);
plugin_meta_info_t *meta = &(plugin_data->meta);
metaInformation.setAuthor(meta->author);
metaInformation.setVersion(meta->version);
metaInformation.setBuildTimestamp(meta->buildTimestamp);
@ -211,7 +211,7 @@ std::vector<PluginContainer> PluginContainerPersistence::loadPlugins(plugin_info
PluginData pluginData;
plugin_data_t * data = &(plugin_data->data);
plugin_data_t *data = &(plugin_data->data);
pluginData.buffer = data->buffer;
pluginData.length = data->bufferLength;
@ -225,9 +225,9 @@ std::vector<PluginContainer> PluginContainerPersistence::loadPlugins(plugin_info
pluginInformation.allocatedTextMemoryAddress = plugin_data->info.allocatedTextMemoryAddress;
pluginInformation.allocatedDataMemoryAddress = plugin_data->info.allocatedDataMemoryAddress;
for(uint32_t i = 0; i < MAXIMUM_PLUGIN_SECTION_LENGTH; i++) {
plugin_section_info_t * sectionInfo = &(plugin_data->info.sectionInfos[i]);
if(sectionInfo->addr == 0 && sectionInfo->size == 0) {
for (uint32_t i = 0; i < MAXIMUM_PLUGIN_SECTION_LENGTH; i++) {
plugin_section_info_t *sectionInfo = &(plugin_data->info.sectionInfos[i]);
if (sectionInfo->addr == 0 && sectionInfo->size == 0) {
continue;
}
DEBUG_FUNCTION_LINE("Add SectionInfo %s", sectionInfo->name);
@ -237,13 +237,13 @@ std::vector<PluginContainer> PluginContainerPersistence::loadPlugins(plugin_info
/* load hook data */
uint32_t hookCount = plugin_data->info.number_used_hooks;
if(hookCount > MAXIMUM_HOOKS_PER_PLUGIN) {
DEBUG_FUNCTION_LINE("number_used_hooks was bigger then allowed. %d > %d. Limiting to %d",hookCount, MAXIMUM_HOOKS_PER_PLUGIN, MAXIMUM_HOOKS_PER_PLUGIN);
if (hookCount > MAXIMUM_HOOKS_PER_PLUGIN) {
DEBUG_FUNCTION_LINE("number_used_hooks was bigger then allowed. %d > %d. Limiting to %d", hookCount, MAXIMUM_HOOKS_PER_PLUGIN, MAXIMUM_HOOKS_PER_PLUGIN);
hookCount = MAXIMUM_HOOKS_PER_PLUGIN;
}
for(uint32_t j = 0; j < hookCount; j++) {
replacement_data_hook_t * hook_entry = &(plugin_data->info.hooks[j]);
for (uint32_t j = 0; j < hookCount; j++) {
replacement_data_hook_t *hook_entry = &(plugin_data->info.hooks[j]);
HookData curHook(hook_entry->func_pointer, hook_entry->type);
pluginInformation.addHookData(curHook);
}
@ -251,39 +251,39 @@ std::vector<PluginContainer> PluginContainerPersistence::loadPlugins(plugin_info
/* load function replacement data */
uint32_t functionReplaceCount = plugin_data->info.number_used_functions;
if(functionReplaceCount > MAXIMUM_FUNCTION_PER_PLUGIN) {
DEBUG_FUNCTION_LINE("number_used_functions was bigger then allowed. %d > %d. Limiting to %d",functionReplaceCount, MAXIMUM_FUNCTION_PER_PLUGIN, MAXIMUM_FUNCTION_PER_PLUGIN);
if (functionReplaceCount > MAXIMUM_FUNCTION_PER_PLUGIN) {
DEBUG_FUNCTION_LINE("number_used_functions was bigger then allowed. %d > %d. Limiting to %d", functionReplaceCount, MAXIMUM_FUNCTION_PER_PLUGIN, MAXIMUM_FUNCTION_PER_PLUGIN);
functionReplaceCount = MAXIMUM_FUNCTION_PER_PLUGIN;
}
for(uint32_t j = 0; j < functionReplaceCount; j++) {
replacement_data_function_t * entry = &(plugin_data->info.functions[j]);
for (uint32_t j = 0; j < functionReplaceCount; j++) {
replacement_data_function_t *entry = &(plugin_data->info.functions[j]);
FunctionData func((void *) entry->physicalAddr, (void *) entry->virtualAddr, entry->function_name, entry->library, (void *) entry->replaceAddr, (void *) entry->replaceCall);
pluginInformation.addFunctionData(func);
}
/* load relocation data */
for(uint32_t j = 0; j < PLUGIN_DYN_LINK_RELOCATION_LIST_LENGTH; j++) {
dyn_linking_relocation_entry_t * linking_entry = &(plugin_data->info.linking_entries[j]);
if(linking_entry->destination == NULL) {
for (uint32_t j = 0; j < PLUGIN_DYN_LINK_RELOCATION_LIST_LENGTH; j++) {
dyn_linking_relocation_entry_t *linking_entry = &(plugin_data->info.linking_entries[j]);
if (linking_entry->destination == NULL) {
break;
}
dyn_linking_import_t* importEntry = linking_entry->importEntry;
if(importEntry == NULL) {
dyn_linking_import_t *importEntry = linking_entry->importEntry;
if (importEntry == NULL) {
DEBUG_FUNCTION_LINE("importEntry was NULL, skipping relocation entry");
continue;
}
if(importEntry->importName == NULL) {
if (importEntry->importName == NULL) {
DEBUG_FUNCTION_LINE("importEntry->importName was NULL, skipping relocation entry");
continue;
}
dyn_linking_function_t* functionEntry = linking_entry->functionEntry;
dyn_linking_function_t *functionEntry = linking_entry->functionEntry;
if(functionEntry == NULL) {
if (functionEntry == NULL) {
DEBUG_FUNCTION_LINE("functionEntry was NULL, skipping relocation entry");
continue;
}
if(functionEntry->functionName == NULL) {
if (functionEntry->functionName == NULL) {
DEBUG_FUNCTION_LINE("functionEntry->functionName was NULL, skipping relocation entry");
continue;
}

View File

@ -5,6 +5,7 @@
class PluginContainerPersistence {
public:
static bool savePlugin(plugin_information_t * pluginInformation, PluginContainer& plugin);
static std::vector<PluginContainer> loadPlugins(plugin_information_t * pluginInformation);
static bool savePlugin(plugin_information_t *pluginInformation, PluginContainer &plugin);
static std::vector<PluginContainer> loadPlugins(plugin_information_t *pluginInformation);
};

View File

@ -1,20 +1,20 @@
#include "PluginData.h"
void PluginData::freeMemory() {
if(buffer == NULL) {
if (buffer == NULL) {
return;
}
switch(memoryType) {
default:
case eMemTypeExpHeap:
MEMFreeToExpHeap(this->heapHandle, buffer);
this->buffer = NULL;
break;
case eMemTypeMEM2:
free(this->buffer);
this->buffer = NULL;
break;
switch (memoryType) {
default:
case eMemTypeExpHeap:
MEMFreeToExpHeap(this->heapHandle, buffer);
this->buffer = NULL;
break;
case eMemTypeMEM2:
free(this->buffer);
this->buffer = NULL;
break;
}
}
@ -22,15 +22,15 @@ PluginData::PluginData(std::vector<uint8_t> buffer) : PluginData(buffer, 0, eMem
}
void PluginData::loadReader() {
if(this->buffer == NULL) {
if (this->buffer == NULL) {
this->reader = std::nullopt;
} else {
elfio * nReader = new elfio;
if(nReader != NULL && nReader->load((char*)this->buffer, length)) {
elfio *nReader = new elfio;
if (nReader != NULL && nReader->load((char *) this->buffer, length)) {
DEBUG_FUNCTION_LINE("Loading was okay");
this->reader = nReader;
} else {
if(nReader){
if (nReader) {
delete nReader;
nReader = NULL;
}
@ -41,36 +41,36 @@ void PluginData::loadReader() {
}
PluginData::PluginData(std::vector<uint8_t> input, MEMHeapHandle heapHandle, eMemoryTypes memoryType):
heapHandle(heapHandle),
memoryType(memoryType),
length(input.size()) {
void * data_copy = NULL;
switch(memoryType) {
default:
case eMemTypeExpHeap:
data_copy = MEMAllocFromExpHeapEx(heapHandle, length, 4);
if(data_copy == NULL) {
DEBUG_FUNCTION_LINE("Failed to allocate space on exp heap");
} else {
memcpy(data_copy, &input[0], length);
}
this->buffer = data_copy;
DEBUG_FUNCTION_LINE("copied data to exp heap");
break;
case eMemTypeMEM2:
data_copy = memalign(length, 4);
if(data_copy == NULL) {
DEBUG_FUNCTION_LINE("Failed to allocate space on default heap");
} else {
memcpy(data_copy, &input[0], length);
}
this->buffer = data_copy;
break;
PluginData::PluginData(std::vector<uint8_t> input, MEMHeapHandle heapHandle, eMemoryTypes memoryType) :
heapHandle(heapHandle),
memoryType(memoryType),
length(input.size()) {
void *data_copy = NULL;
switch (memoryType) {
default:
case eMemTypeExpHeap:
data_copy = MEMAllocFromExpHeapEx(heapHandle, length, 4);
if (data_copy == NULL) {
DEBUG_FUNCTION_LINE("Failed to allocate space on exp heap");
} else {
memcpy(data_copy, &input[0], length);
}
this->buffer = data_copy;
DEBUG_FUNCTION_LINE("copied data to exp heap");
break;
case eMemTypeMEM2:
data_copy = memalign(length, 4);
if (data_copy == NULL) {
DEBUG_FUNCTION_LINE("Failed to allocate space on default heap");
} else {
memcpy(data_copy, &input[0], length);
}
this->buffer = data_copy;
break;
}
loadReader();
}
std::optional<PluginData> PluginData::createFromExistingData(const void* buffer, MEMHeapHandle heapHandle, eMemoryTypes memoryType, const size_t length) {
std::optional<PluginData> PluginData::createFromExistingData(const void *buffer, MEMHeapHandle heapHandle, eMemoryTypes memoryType, const size_t length) {
return std::nullopt;
}

View File

@ -16,6 +16,7 @@
****************************************************************************/
#pragma once
#include <optional>
#include <vector>
#include <malloc.h>
@ -32,11 +33,12 @@ enum eMemoryTypes {
class PluginData {
public:
const std::optional<elfio*>& getReader() const {
const std::optional<elfio *> &getReader() const {
return reader;
}
~PluginData() {
if(nReader != NULL) {
if (nReader != NULL) {
delete nReader;
nReader = NULL;
}
@ -44,25 +46,30 @@ public:
void freeMemory();
private:
PluginData() {
}
PluginData(std::vector<uint8_t> buffer);
PluginData(std::vector<uint8_t> input, MEMHeapHandle heapHandle, eMemoryTypes memoryType);
void loadReader();
static std::optional<PluginData> createFromExistingData(const void* buffer, MEMHeapHandle heapHandle, eMemoryTypes memoryType, const size_t length);
static std::optional<PluginData> createFromExistingData(const void *buffer, MEMHeapHandle heapHandle, eMemoryTypes memoryType, const size_t length);
std::optional<elfio*> reader;
elfio* nReader = NULL;
void* buffer;
std::optional<elfio *> reader;
elfio *nReader = NULL;
void *buffer;
MEMHeapHandle heapHandle;
eMemoryTypes memoryType;
size_t length;
friend class PluginDataFactory;
friend class PluginContainer;
friend class PluginContainerPersistence;
};

View File

@ -24,53 +24,53 @@
#include "utils/StringTools.h"
std::vector<PluginData> PluginDataFactory::loadDir(const std::string & path, MEMHeapHandle heapHandle) {
std::vector<PluginData> PluginDataFactory::loadDir(const std::string &path, MEMHeapHandle heapHandle) {
std::vector<PluginData> result;
struct dirent *dp;
DIR *dfd = NULL;
if(path.empty()) {
if (path.empty()) {
DEBUG_FUNCTION_LINE("Path was empty\n");
return result;
}
if ((dfd = opendir(path.c_str())) == NULL) {
DEBUG_FUNCTION_LINE("Couldn't open dir %s\n",path.c_str());
DEBUG_FUNCTION_LINE("Couldn't open dir %s\n", path.c_str());
return result;
}
while ((dp = readdir(dfd)) != NULL) {
struct stat stbuf ;
std::string full_file_path = StringTools::strfmt("%s/%s",path.c_str(),dp->d_name);
struct stat stbuf;
std::string full_file_path = StringTools::strfmt("%s/%s", path.c_str(), dp->d_name);
StringTools::RemoveDoubleSlashs(full_file_path);
if( stat(full_file_path.c_str(),&stbuf ) == -1 ) {
DEBUG_FUNCTION_LINE("Unable to stat file: %s\n",full_file_path.c_str()) ;
if (stat(full_file_path.c_str(), &stbuf) == -1) {
DEBUG_FUNCTION_LINE("Unable to stat file: %s\n", full_file_path.c_str());
continue;
}
if ( ( stbuf.st_mode & S_IFMT ) == S_IFDIR ) { // Skip directories
if ((stbuf.st_mode & S_IFMT) == S_IFDIR) { // Skip directories
continue;
} else {
DEBUG_FUNCTION_LINE("Found file: %s\n",full_file_path.c_str()) ;
DEBUG_FUNCTION_LINE("Found file: %s\n", full_file_path.c_str());
auto pluginData = load(full_file_path, heapHandle);
if(pluginData) {
if (pluginData) {
result.push_back(pluginData.value());
}
}
}
if(dfd != NULL) {
if (dfd != NULL) {
closedir(dfd);
}
return result;
}
std::optional<PluginData> PluginDataFactory::load(const std::string & filename, MEMHeapHandle heapHandle) {
std::optional<PluginData> PluginDataFactory::load(const std::string &filename, MEMHeapHandle heapHandle) {
// open the file:
DEBUG_FUNCTION_LINE();
std::ifstream file(filename, std::ios::binary);
DEBUG_FUNCTION_LINE();
if(!file.is_open()){
if (!file.is_open()) {
DEBUG_FUNCTION_LINE("Failed to open %s", filename.c_str());
return std::nullopt;
}
@ -102,8 +102,8 @@ std::optional<PluginData> PluginDataFactory::load(const std::string & filename,
return load(vBuffer, heapHandle);
}
std::optional<PluginData> PluginDataFactory::load(std::vector<uint8_t>& buffer, MEMHeapHandle heapHandle) {
if(buffer.empty()){
std::optional<PluginData> PluginDataFactory::load(std::vector<uint8_t> &buffer, MEMHeapHandle heapHandle) {
if (buffer.empty()) {
return std::nullopt;
}

View File

@ -25,7 +25,9 @@
class PluginDataFactory {
public:
static std::vector<PluginData> loadDir(const std::string & path, MEMHeapHandle heapHandle);
static std::optional<PluginData> load(const std::string & path, MEMHeapHandle heapHandle);
static std::optional<PluginData> load(std::vector<uint8_t>& buffer, MEMHeapHandle heapHandle);
static std::vector<PluginData> loadDir(const std::string &path, MEMHeapHandle heapHandle);
static std::optional<PluginData> load(const std::string &path, MEMHeapHandle heapHandle);
static std::optional<PluginData> load(std::vector<uint8_t> &buffer, MEMHeapHandle heapHandle);
};

View File

@ -29,17 +29,17 @@
class PluginInformation {
public:
PluginInformation(){
PluginInformation() {
}
virtual ~PluginInformation() {
}
void addHookData(const HookData& hook_data) {
void addHookData(const HookData &hook_data) {
hook_data_list.push_back(hook_data);
}
const std::vector<HookData>& getHookDataList() const {
const std::vector<HookData> &getHookDataList() const {
return hook_data_list;
}
@ -47,7 +47,7 @@ public:
function_data_list.push_back(function_data);
}
const std::vector<FunctionData>& getFunctionDataList() const {
const std::vector<FunctionData> &getFunctionDataList() const {
return function_data_list;
}
@ -55,20 +55,20 @@ public:
relocation_data_list.push_back(relocation_data);
}
const std::vector<RelocationData>& getRelocationDataList() const {
const std::vector<RelocationData> &getRelocationDataList() const {
return relocation_data_list;
}
void addSectionInfo(const SectionInfo& sectionInfo) {
void addSectionInfo(const SectionInfo &sectionInfo) {
section_info_list[sectionInfo.getName()] = sectionInfo;
}
const std::map<std::string, SectionInfo>& getSectionInfoList() const {
const std::map<std::string, SectionInfo> &getSectionInfoList() const {
return section_info_list;
}
std::optional<SectionInfo> getSectionInfo(const std::string& sectionName) const {
if(getSectionInfoList().count(sectionName) > 0) {
std::optional<SectionInfo> getSectionInfo(const std::string &sectionName) const {
if (getSectionInfoList().count(sectionName) > 0) {
return section_info_list.at(sectionName);
}
return std::nullopt;
@ -91,9 +91,10 @@ private:
uint8_t trampolinId = 0;
void* allocatedTextMemoryAddress = 0;
void* allocatedDataMemoryAddress = 0;
void *allocatedTextMemoryAddress = 0;
void *allocatedDataMemoryAddress = 0;
friend class PluginInformationFactory;
friend class PluginContainerPersistence;
};

View File

@ -33,9 +33,9 @@
using namespace ELFIO;
std::optional<PluginInformation> PluginInformationFactory::load(const PluginData & pluginData, MEMHeapHandle heapHandle, relocation_trampolin_entry_t * trampolin_data, uint32_t trampolin_data_length, uint8_t trampolinId) {
std::optional<PluginInformation> PluginInformationFactory::load(const PluginData &pluginData, MEMHeapHandle heapHandle, relocation_trampolin_entry_t *trampolin_data, uint32_t trampolin_data_length, uint8_t trampolinId) {
auto readerOpt = pluginData.getReader();
if(!readerOpt) {
if (!readerOpt) {
DEBUG_FUNCTION_LINE("Can't find or process ELF file");
return std::nullopt;
}
@ -50,8 +50,8 @@ std::optional<PluginInformation> PluginInformationFactory::load(const PluginData
uint32_t text_size = 0;
uint32_t data_size = 0;
for(uint32_t i = 0; i < sec_num; ++i ) {
section* psec = reader->sections[i];
for (uint32_t i = 0; i < sec_num; ++i) {
section *psec = reader->sections[i];
if (psec->get_type() == 0x80000002) {
continue;
}
@ -59,35 +59,35 @@ std::optional<PluginInformation> PluginInformationFactory::load(const PluginData
if ((psec->get_type() == SHT_PROGBITS || psec->get_type() == SHT_NOBITS) && (psec->get_flags() & SHF_ALLOC)) {
uint32_t sectionSize = psec->get_size();
uint32_t address = (uint32_t) psec->get_address();
if((address >= 0x02000000) && address < 0x10000000) {
if ((address >= 0x02000000) && address < 0x10000000) {
text_size += sectionSize;
} else if((address >= 0x10000000) && address < 0xC0000000) {
} else if ((address >= 0x10000000) && address < 0xC0000000) {
data_size += sectionSize;
}
}
}
void * text_data = MEMAllocFromExpHeapEx(heapHandle, text_size, 0x1000);
void *text_data = MEMAllocFromExpHeapEx(heapHandle, text_size, 0x1000);
if(text_data == NULL) {
if (text_data == NULL) {
DEBUG_FUNCTION_LINE("Failed to alloc memory for the .text section (%d bytes)\n", text_size);
return std::nullopt;
}
DEBUG_FUNCTION_LINE("Allocated %d kb from ExpHeap", text_size/1024);
void * data_data = MEMAllocFromExpHeapEx(heapHandle, data_size, 0x1000);
if(data_data == NULL) {
DEBUG_FUNCTION_LINE("Allocated %d kb from ExpHeap", text_size / 1024);
void *data_data = MEMAllocFromExpHeapEx(heapHandle, data_size, 0x1000);
if (data_data == NULL) {
DEBUG_FUNCTION_LINE("Failed to alloc memory for the .data section (%d bytes)\n", data_size);
MEMFreeToExpHeap(heapHandle, text_data);
return std::nullopt;
}
DEBUG_FUNCTION_LINE("Allocated %d kb from ExpHeap", data_size/1024);
DEBUG_FUNCTION_LINE("Allocated %d kb from ExpHeap", data_size / 1024);
uint32_t entrypoint = (uint32_t)text_data + (uint32_t) reader->get_entry() - 0x02000000;
uint32_t entrypoint = (uint32_t) text_data + (uint32_t) reader->get_entry() - 0x02000000;
for(uint32_t i = 0; i < sec_num; ++i ) {
section* psec = reader->sections[i];
for (uint32_t i = 0; i < sec_num; ++i) {
section *psec = reader->sections[i];
if (psec->get_type() == 0x80000002) {
continue;
}
@ -97,15 +97,15 @@ std::optional<PluginInformation> PluginInformationFactory::load(const PluginData
uint32_t address = (uint32_t) psec->get_address();
uint32_t destination = address;
if((address >= 0x02000000) && address < 0x10000000) {
if ((address >= 0x02000000) && address < 0x10000000) {
destination += (uint32_t) text_data;
destination -= 0x02000000;
destinations[psec->get_index()] = (uint8_t *) text_data;
} else if((address >= 0x10000000) && address < 0xC0000000) {
} else if ((address >= 0x10000000) && address < 0xC0000000) {
destination += (uint32_t) data_data;
destination -= 0x10000000;
destinations[psec->get_index()] = (uint8_t *) data_data;
} else if(address >= 0xC0000000) {
} else if (address >= 0xC0000000) {
destination += (uint32_t) data_data;
destination -= 0xC0000000;
//destinations[psec->get_index()] = (uint8_t *) data_data;
@ -118,14 +118,14 @@ std::optional<PluginInformation> PluginInformationFactory::load(const PluginData
return std::nullopt;
}
const char* p = psec->get_data();
const char *p = psec->get_data();
if(psec->get_type() == SHT_NOBITS) {
if (psec->get_type() == SHT_NOBITS) {
DEBUG_FUNCTION_LINE("memset section %s %08X to 0 (%d bytes)", psec->get_name().c_str(), destination, sectionSize);
memset((void*) destination, 0, sectionSize);
} else if(psec->get_type() == SHT_PROGBITS) {
memset((void *) destination, 0, sectionSize);
} else if (psec->get_type() == SHT_PROGBITS) {
DEBUG_FUNCTION_LINE("Copy section %s %08X -> %08X (%d bytes)", psec->get_name().c_str(), p, destination, sectionSize);
memcpy((void*) destination, p, sectionSize);
memcpy((void *) destination, p, sectionSize);
}
pluginInfo.addSectionInfo(SectionInfo(psec->get_name(), destination, sectionSize));
@ -133,15 +133,15 @@ std::optional<PluginInformation> PluginInformationFactory::load(const PluginData
totalSize += sectionSize;
DCFlushRange((void*)destination, sectionSize);
ICInvalidateRange((void*)destination, sectionSize);
DCFlushRange((void *) destination, sectionSize);
ICInvalidateRange((void *) destination, sectionSize);
}
}
for(uint32_t i = 0; i < sec_num; ++i ) {
section* psec = reader->sections[i];
for (uint32_t i = 0; i < sec_num; ++i) {
section *psec = reader->sections[i];
if ((psec->get_type() == SHT_PROGBITS || psec->get_type() == SHT_NOBITS) && (psec->get_flags() & SHF_ALLOC)) {
DEBUG_FUNCTION_LINE("Linking (%d)... %s at %08X",i,psec->get_name().c_str(), destinations[psec->get_index()]);
DEBUG_FUNCTION_LINE("Linking (%d)... %s at %08X", i, psec->get_name().c_str(), destinations[psec->get_index()]);
if (!linkSection(pluginData, psec->get_index(), (uint32_t) destinations[psec->get_index()], (uint32_t) text_data, (uint32_t) data_data, trampolin_data, trampolin_data_length, trampolinId)) {
DEBUG_FUNCTION_LINE("elfLink failed");
@ -154,14 +154,14 @@ std::optional<PluginInformation> PluginInformationFactory::load(const PluginData
}
std::vector<RelocationData> relocationData = getImportRelocationData(pluginData, destinations);
for (auto const& reloc : relocationData) {
for (auto const &reloc : relocationData) {
pluginInfo.addRelocationData(reloc);
}
DCFlushRange((void*)text_data, text_size);
ICInvalidateRange((void*)text_data, text_size);
DCFlushRange((void*)data_data, data_size);
ICInvalidateRange((void*)data_data, data_size);
DCFlushRange((void *) text_data, text_size);
ICInvalidateRange((void *) text_data, text_size);
DCFlushRange((void *) data_data, data_size);
ICInvalidateRange((void *) data_data, data_size);
free(destinations);
@ -170,28 +170,30 @@ std::optional<PluginInformation> PluginInformationFactory::load(const PluginData
DEBUG_FUNCTION_LINE("Saved entrypoint as %08X", entrypoint);
std::optional<SectionInfo> secInfo = pluginInfo.getSectionInfo(".wups.hooks");
if(secInfo && secInfo->getSize() > 0) {
if (secInfo && secInfo->getSize() > 0) {
size_t entries_count = secInfo->getSize() / sizeof(wups_loader_hook_t);
wups_loader_hook_t * entries = (wups_loader_hook_t *) secInfo->getAddress();
if(entries != NULL) {
for(size_t j=0; j<entries_count; j++) {
wups_loader_hook_t * hook = &entries[j];
DEBUG_FUNCTION_LINE("Saving hook of plugin Type: %08X, target: %08X"/*,pluginData.getPluginInformation()->getName().c_str()*/,hook->type,(void*) hook->target);
HookData hook_data((void *) hook->target,hook->type);
wups_loader_hook_t *entries = (wups_loader_hook_t *) secInfo->getAddress();
if (entries != NULL) {
for (size_t j = 0; j < entries_count; j++) {
wups_loader_hook_t *hook = &entries[j];
DEBUG_FUNCTION_LINE("Saving hook of plugin Type: %08X, target: %08X"/*,pluginData.getPluginInformation()->getName().c_str()*/, hook->type, (void *) hook->target);
HookData hook_data((void *) hook->target, hook->type);
pluginInfo.addHookData(hook_data);
}
}
}
secInfo = pluginInfo.getSectionInfo(".wups.load");
if(secInfo && secInfo->getSize() > 0) {
if (secInfo && secInfo->getSize() > 0) {
size_t entries_count = secInfo->getSize() / sizeof(wups_loader_entry_t);
wups_loader_entry_t * entries = (wups_loader_entry_t *) secInfo->getAddress();
if(entries != NULL) {
for(size_t j=0; j<entries_count; j++) {
wups_loader_entry_t * cur_function = &entries[j];
DEBUG_FUNCTION_LINE("Saving function \"%s\" of plugin . PA:%08X VA:%08X Library: %08X, target: %08X, call_addr: %08X",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((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);
wups_loader_entry_t *entries = (wups_loader_entry_t *) secInfo->getAddress();
if (entries != NULL) {
for (size_t j = 0; j < entries_count; j++) {
wups_loader_entry_t *cur_function = &entries[j];
DEBUG_FUNCTION_LINE("Saving function \"%s\" of plugin . PA:%08X VA:%08X Library: %08X, target: %08X, call_addr: %08X", 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((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);
pluginInfo.addFunctionData(function_data);
}
}
@ -204,45 +206,45 @@ std::optional<PluginInformation> PluginInformationFactory::load(const PluginData
return pluginInfo;
}
std::vector<RelocationData> PluginInformationFactory::getImportRelocationData(const PluginData &pluginData, uint8_t ** destinations) {
std::vector<RelocationData> PluginInformationFactory::getImportRelocationData(const PluginData &pluginData, uint8_t **destinations) {
auto readerOpt = pluginData.getReader();
std::vector<RelocationData> result;
if(!readerOpt) {
if (!readerOpt) {
return result;
}
auto reader = readerOpt.value();
std::map<uint32_t,std::string> infoMap;
std::map<uint32_t, std::string> infoMap;
uint32_t sec_num = reader->sections.size();
for ( uint32_t i = 0; i < sec_num; ++i ) {
section* psec = reader->sections[i];
for (uint32_t i = 0; i < sec_num; ++i) {
section *psec = reader->sections[i];
if (psec->get_type() == 0x80000002) {
infoMap[i] = psec->get_name();
}
}
for (uint32_t i = 0; i < sec_num; ++i ) {
section* psec = reader->sections[i];
if(psec->get_type() == SHT_RELA || psec->get_type() == SHT_REL) {
DEBUG_FUNCTION_LINE("Found relocation section %s",psec->get_name().c_str());
for (uint32_t i = 0; i < sec_num; ++i) {
section *psec = reader->sections[i];
if (psec->get_type() == SHT_RELA || psec->get_type() == SHT_REL) {
DEBUG_FUNCTION_LINE("Found relocation section %s", psec->get_name().c_str());
relocation_section_accessor rel(*reader, psec);
for ( uint32_t j = 0; j < (uint32_t) rel.get_entries_num(); ++j ) {
Elf64_Addr offset;
Elf_Word type;
Elf_Sxword addend;
std::string sym_name;
Elf64_Addr sym_value;
Elf_Half sym_section_index;
for (uint32_t j = 0; j < (uint32_t) rel.get_entries_num(); ++j) {
Elf64_Addr offset;
Elf_Word type;
Elf_Sxword addend;
std::string sym_name;
Elf64_Addr sym_value;
Elf_Half sym_section_index;
if(!rel.get_entry(j, offset, sym_value, sym_name, type, addend, sym_section_index)) {
if (!rel.get_entry(j, offset, sym_value, sym_name, type, addend, sym_section_index)) {
DEBUG_FUNCTION_LINE("Failed to get relocation");
break;
}
uint32_t adjusted_sym_value = (uint32_t) sym_value;
if(adjusted_sym_value < 0xC0000000) {
if (adjusted_sym_value < 0xC0000000) {
continue;
}
@ -254,7 +256,7 @@ std::vector<RelocationData> PluginInformationFactory::getImportRelocationData(co
std::string rplName = "";
std::string rawSectionName = infoMap[sym_section_index];
if(rawSectionName.size() < fimport.size()) {
if (rawSectionName.size() < fimport.size()) {
DEBUG_FUNCTION_LINE("Section name was shorter than expected, skipping this relocation");
continue;
} else if (std::equal(fimport.begin(), fimport.end(), rawSectionName.begin())) {
@ -271,75 +273,77 @@ std::vector<RelocationData> PluginInformationFactory::getImportRelocationData(co
uint32_t section_index = psec->get_info();
result.push_back(RelocationData(type, offset - 0x02000000, addend, (void*)(destinations[section_index]), sym_name, rplInfo));
result.push_back(RelocationData(type, offset - 0x02000000, addend, (void *) (destinations[section_index]), sym_name, rplInfo));
}
}
}
return result;
}
bool PluginInformationFactory::linkSection(const PluginData& pluginData, uint32_t section_index, uint32_t destination, uint32_t base_text, uint32_t base_data, relocation_trampolin_entry_t * trampolin_data, uint32_t trampolin_data_length, uint8_t trampolinId) {
bool PluginInformationFactory::linkSection(const PluginData &pluginData, uint32_t section_index, uint32_t destination, uint32_t base_text, uint32_t base_data, relocation_trampolin_entry_t *trampolin_data, uint32_t trampolin_data_length,
uint8_t trampolinId) {
auto readerOpt = pluginData.getReader();
if(!readerOpt) {
if (!readerOpt) {
return false;
}
auto reader = readerOpt.value();
uint32_t sec_num = reader->sections.size();
for (uint32_t i = 0; i < sec_num; ++i ) {
section* psec = reader->sections[i];
if(psec->get_info() == section_index) {
DEBUG_FUNCTION_LINE("Found relocation section %s",psec->get_name().c_str());
for (uint32_t i = 0; i < sec_num; ++i) {
section *psec = reader->sections[i];
if (psec->get_info() == section_index) {
DEBUG_FUNCTION_LINE("Found relocation section %s", psec->get_name().c_str());
relocation_section_accessor rel(*reader, psec);
for ( uint32_t j = 0; j < (uint32_t) rel.get_entries_num(); ++j ) {
Elf64_Addr offset;
Elf_Word type;
Elf_Sxword addend;
std::string sym_name;
Elf64_Addr sym_value;
Elf_Half sym_section_index;
for (uint32_t j = 0; j < (uint32_t) rel.get_entries_num(); ++j) {
Elf64_Addr offset;
Elf_Word type;
Elf_Sxword addend;
std::string sym_name;
Elf64_Addr sym_value;
Elf_Half sym_section_index;
if(!rel.get_entry(j, offset, sym_value, sym_name, type, addend, sym_section_index)) {
if (!rel.get_entry(j, offset, sym_value, sym_name, type, addend, sym_section_index)) {
DEBUG_FUNCTION_LINE("Failed to get relocation");
break;
}
uint32_t adjusted_sym_value = (uint32_t) sym_value;
if((adjusted_sym_value >= 0x02000000) && adjusted_sym_value < 0x10000000) {
if ((adjusted_sym_value >= 0x02000000) && adjusted_sym_value < 0x10000000) {
adjusted_sym_value -= 0x02000000;
adjusted_sym_value += base_text;
} else if((adjusted_sym_value >= 0x10000000) && adjusted_sym_value < 0xC0000000) {
} else if ((adjusted_sym_value >= 0x10000000) && adjusted_sym_value < 0xC0000000) {
adjusted_sym_value -= 0x10000000;
adjusted_sym_value += base_data;
} else if(adjusted_sym_value >= 0xC0000000) {
} else if (adjusted_sym_value >= 0xC0000000) {
//DEBUG_FUNCTION_LINE("Skip imports");
// Skip imports
continue;
} else if(adjusted_sym_value == 0x0) {
} else if (adjusted_sym_value == 0x0) {
//
} else {
DEBUG_FUNCTION_LINE("Unhandled case %08X",adjusted_sym_value);
DEBUG_FUNCTION_LINE("Unhandled case %08X", adjusted_sym_value);
return false;
}
uint32_t adjusted_offset = (uint32_t) offset;
if((offset >= 0x02000000) && offset < 0x10000000) {
if ((offset >= 0x02000000) && offset < 0x10000000) {
adjusted_offset -= 0x02000000;
} else if((adjusted_offset >= 0x10000000) && adjusted_offset < 0xC0000000) {
} else if ((adjusted_offset >= 0x10000000) && adjusted_offset < 0xC0000000) {
adjusted_offset -= 0x10000000;
} else if(adjusted_offset >= 0xC0000000) {
} else if (adjusted_offset >= 0xC0000000) {
adjusted_offset -= 0xC0000000;
}
if(sym_section_index == SHN_ABS) {
if (sym_section_index == SHN_ABS) {
//
} else if(sym_section_index > SHN_LORESERVE) {
} else if (sym_section_index > SHN_LORESERVE) {
DEBUG_FUNCTION_LINE("NOT IMPLEMENTED: %04X", sym_section_index);
return false;
}
if(false) {
if (false) {
DEBUG_FUNCTION_LINE("sym_value %08X adjusted_sym_value %08X offset %08X adjusted_offset %08X", (uint32_t) sym_value, adjusted_sym_value, (uint32_t) offset, adjusted_offset);
}
if(!ElfUtils::elfLinkOne(type, adjusted_offset, addend, destination, adjusted_sym_value, trampolin_data, trampolin_data_length, RELOC_TYPE_FIXED, trampolinId)) {
if (!ElfUtils::elfLinkOne(type, adjusted_offset, addend, destination, adjusted_sym_value, trampolin_data, trampolin_data_length, RELOC_TYPE_FIXED, trampolinId)) {
DEBUG_FUNCTION_LINE("Link failed");
return false;
}

View File

@ -29,7 +29,10 @@
class PluginInformationFactory {
public:
static std::optional<PluginInformation> load(const PluginData & pluginData, MEMHeapHandle heaphandle, relocation_trampolin_entry_t * trampolin_data, uint32_t trampolin_data_length, uint8_t trampolinId);
static bool linkSection(const PluginData & pluginData, uint32_t section_index, uint32_t destination, uint32_t base_text, uint32_t base_data, relocation_trampolin_entry_t * trampolin_data, uint32_t trampolin_data_length, uint8_t trampolinId);
static std::vector<RelocationData> getImportRelocationData(const PluginData & pluginData, uint8_t ** destinations);
static std::optional<PluginInformation> load(const PluginData &pluginData, MEMHeapHandle heaphandle, relocation_trampolin_entry_t *trampolin_data, uint32_t trampolin_data_length, uint8_t trampolinId);
static bool
linkSection(const PluginData &pluginData, uint32_t section_index, uint32_t destination, uint32_t base_text, uint32_t base_data, relocation_trampolin_entry_t *trampolin_data, uint32_t trampolin_data_length, uint8_t trampolinId);
static std::vector<RelocationData> getImportRelocationData(const PluginData &pluginData, uint8_t **destinations);
};

View File

@ -54,27 +54,27 @@ private:
PluginMetaInformation() {
}
void setName(const std::string& name) {
void setName(const std::string &name) {
this->name = name;
}
void setAuthor(const std::string& author) {
void setAuthor(const std::string &author) {
this->author = author;
}
void setVersion(const std::string& version) {
void setVersion(const std::string &version) {
this->version = version;
}
void setLicense(const std::string& license) {
void setLicense(const std::string &license) {
this->license = license;
}
void setBuildTimestamp(const std::string& buildtimestamp) {
void setBuildTimestamp(const std::string &buildtimestamp) {
this->buildtimestamp = buildtimestamp;
}
void setDescription(const std::string& description) {
void setDescription(const std::string &description) {
this->description = description;
}
@ -91,6 +91,8 @@ private:
size_t size;
friend class PluginMetaInformationFactory;
friend class PluginContainerPersistence;
friend class PluginContainer;
};

View File

@ -26,7 +26,7 @@
using namespace ELFIO;
std::optional<PluginMetaInformation> PluginMetaInformationFactory::loadPlugin(const PluginData& pluginData) {
std::optional<PluginMetaInformation> PluginMetaInformationFactory::loadPlugin(const PluginData &pluginData) {
auto readerOpt = pluginData.getReader();
// Load ELF data
@ -45,53 +45,53 @@ std::optional<PluginMetaInformation> PluginMetaInformationFactory::loadPlugin(co
DEBUG_FUNCTION_LINE("%d number of sections", sec_num);
for(uint32_t i = 0; i < sec_num; ++i ) {
section* psec = reader->sections[i];
for (uint32_t i = 0; i < sec_num; ++i) {
section *psec = reader->sections[i];
// Calculate total size:
if ((psec->get_type() == SHT_PROGBITS || psec->get_type() == SHT_NOBITS) && (psec->get_flags() & SHF_ALLOC)) {
uint32_t sectionSize = psec->get_size();
uint32_t address = (uint32_t) psec->get_address();
if((address >= 0x02000000) && address < 0x10000000) {
if ((address >= 0x02000000) && address < 0x10000000) {
pluginSize += sectionSize;
} else if((address >= 0x10000000) && address < 0xC0000000) {
} else if ((address >= 0x10000000) && address < 0xC0000000) {
pluginSize += sectionSize;
}
}
// Get meta information and check WUPS version:
if (psec->get_name().compare(".wups.meta") == 0) {
const void * sectionData = psec->get_data();
const void *sectionData = psec->get_data();
uint32_t sectionSize = psec->get_size();
char * curEntry = (char *) sectionData;
while((uint32_t) curEntry < (uint32_t) sectionData + sectionSize) {
char *curEntry = (char *) sectionData;
while ((uint32_t) curEntry < (uint32_t) sectionData + sectionSize) {
if (*curEntry == '\0') {
curEntry++;
continue;
}
auto firstFound = std::string(curEntry).find_first_of("=");
if(firstFound != std::string::npos) {
if (firstFound != std::string::npos) {
curEntry[firstFound] = '\0';
std::string key(curEntry);
std::string value(curEntry + firstFound + 1);
if(key.compare("name") == 0) {
if (key.compare("name") == 0) {
DEBUG_FUNCTION_LINE("Name = %s", value.c_str());
pluginInfo.setName(value);
} else if(key.compare("author") == 0) {
} else if (key.compare("author") == 0) {
pluginInfo.setAuthor(value);
} else if(key.compare("version") == 0) {
} else if (key.compare("version") == 0) {
pluginInfo.setVersion(value);
} else if(key.compare("license") == 0) {
} else if (key.compare("license") == 0) {
pluginInfo.setLicense(value);
} else if(key.compare("buildtimestamp") == 0) {
} else if (key.compare("buildtimestamp") == 0) {
pluginInfo.setBuildTimestamp(value);
} else if(key.compare("description") == 0) {
} else if (key.compare("description") == 0) {
pluginInfo.setDescription(value);
} else if(key.compare("wups") == 0) {
if(value.compare("0.2") != 0) {
} else if (key.compare("wups") == 0) {
if (value.compare("0.2") != 0) {
DEBUG_FUNCTION_LINE("Warning: Ignoring plugin - Unsupported WUPS version: %s.\n", value);
return std::nullopt;
}

View File

@ -25,5 +25,5 @@
class PluginMetaInformationFactory {
public:
static std::optional<PluginMetaInformation> loadPlugin(const PluginData& pluginData);
static std::optional<PluginMetaInformation> loadPlugin(const PluginData &pluginData);
};

View File

@ -23,48 +23,48 @@
class RelocationData {
public:
RelocationData(const char type, size_t offset, int32_t addend, void *destination, std::string name, ImportRPLInformation rplInfo):
type(type),
offset(offset),
addend(addend),
destination(destination),
name(name),
rplInfo(rplInfo) {
RelocationData(const char type, size_t offset, int32_t addend, void *destination, std::string name, ImportRPLInformation rplInfo) :
type(type),
offset(offset),
addend(addend),
destination(destination),
name(name),
rplInfo(rplInfo) {
}
RelocationData(const RelocationData &o2):
type(o2.type),
offset(o2.offset),
addend(o2.addend),
destination(o2.destination),
name(o2.name),
rplInfo(o2.rplInfo) {
RelocationData(const RelocationData &o2) :
type(o2.type),
offset(o2.offset),
addend(o2.addend),
destination(o2.destination),
name(o2.name),
rplInfo(o2.rplInfo) {
}
virtual ~RelocationData() {
}
const char getType() const{
const char getType() const {
return type;
}
const size_t getOffset() const{
const size_t getOffset() const {
return offset;
}
const int32_t getAddend() const{
const int32_t getAddend() const {
return addend;
}
const void * getDestination() const{
const void *getDestination() const {
return destination;
}
const std::string& getName() const{
const std::string &getName() const {
return name;
}
const ImportRPLInformation& getImportRPLInformation() const{
const ImportRPLInformation &getImportRPLInformation() const {
return rplInfo;
}

View File

@ -22,19 +22,19 @@
class SectionInfo {
public:
SectionInfo(std::string name, uint32_t address, uint32_t sectionSize):
name(name),
address(address),
sectionSize(sectionSize) {
SectionInfo(std::string name, uint32_t address, uint32_t sectionSize) :
name(name),
address(address),
sectionSize(sectionSize) {
}
SectionInfo(){
SectionInfo() {
}
SectionInfo(const SectionInfo &o2):
name(o2.name),
address(o2.address),
sectionSize(o2.sectionSize) {
SectionInfo(const SectionInfo &o2) :
name(o2.name),
address(o2.address),
sectionSize(o2.sectionSize) {
}
@ -42,7 +42,7 @@ public:
}
const std::string& getName() const {
const std::string &getName() const {
return name;
}

View File

@ -8,152 +8,152 @@
#include "ElfUtils.h"
// See https://github.com/decaf-emu/decaf-emu/blob/43366a34e7b55ab9d19b2444aeb0ccd46ac77dea/src/libdecaf/src/cafe/loader/cafe_loader_reloc.cpp#L144
bool ElfUtils::elfLinkOne(char type, size_t offset, int32_t addend, uint32_t destination, uint32_t symbol_addr, relocation_trampolin_entry_t * trampolin_data, uint32_t trampolin_data_length, RelocationType reloc_type, uint8_t trampolinId) {
if(type == R_PPC_NONE) {
bool ElfUtils::elfLinkOne(char type, size_t offset, int32_t addend, uint32_t destination, uint32_t symbol_addr, relocation_trampolin_entry_t *trampolin_data, uint32_t trampolin_data_length, RelocationType reloc_type, uint8_t trampolinId) {
if (type == R_PPC_NONE) {
return true;
}
auto target = destination + offset;
auto target = destination + offset;
auto value = symbol_addr + addend;
auto relValue = value - static_cast<uint32_t>(target);
switch (type) {
case R_PPC_NONE:
break;
case R_PPC_ADDR32:
*((uint32_t *)(target)) = value;
break;
case R_PPC_ADDR16_LO:
*((uint16_t *)(target)) = static_cast<uint16_t>(value & 0xFFFF);
break;
case R_PPC_ADDR16_HI:
*((uint16_t *)(target)) = static_cast<uint16_t>(value >> 16);
break;
case R_PPC_ADDR16_HA:
*((uint16_t *)(target)) = static_cast<uint16_t>((value + 0x8000) >> 16);
break;
case R_PPC_DTPMOD32:
DEBUG_FUNCTION_LINE("################IMPLEMENT ME\n");
//*((int32_t *)(target)) = tlsModuleIndex;
break;
case R_PPC_DTPREL32:
*((uint32_t *)(target)) = value;
break;
case R_PPC_GHS_REL16_HA:
*((uint16_t *)(target)) = static_cast<uint16_t>((relValue + 0x8000) >> 16);
break;
case R_PPC_GHS_REL16_HI:
*((uint16_t *)(target)) = static_cast<uint16_t>(relValue >> 16);
break;
case R_PPC_GHS_REL16_LO:
*((uint16_t *)(target)) = static_cast<uint16_t>(relValue & 0xFFFF);
break;
case R_PPC_REL14: {
auto distance = static_cast<int32_t>(value) - static_cast<int32_t>(target);
if (distance > 0x7FFC || distance < -0x7FFC) {
DEBUG_FUNCTION_LINE("***14-bit relative branch cannot hit target.");
return false;
}
if (distance & 3) {
DEBUG_FUNCTION_LINE("***RELOC ERROR %d: lower 2 bits must be zero before shifting.", -470040);
return false;
}
if ((distance >= 0 && (distance & 0xFFFF8000)) ||
(distance < 0 && ((distance & 0xFFFF8000) != 0xFFFF8000))) {
DEBUG_FUNCTION_LINE("***RELOC ERROR %d: upper 17 bits before shift must all be the same.", -470040);
return false;
}
*(int32_t *)target = (*(int32_t *)target & 0xFFBF0003) | (distance & 0x0000fffc);
break;
}
case R_PPC_REL24: {
// if (isWeakSymbol && !symbolValue) {
// symbolValue = static_cast<uint32_t>(target);
// value = symbolValue + addend;
// }
auto distance = static_cast<int32_t>(value) - static_cast<int32_t>(target);
if (distance > 0x1FFFFFC || distance < -0x1FFFFFC) {
if(trampolin_data == NULL) {
DEBUG_FUNCTION_LINE("***24-bit relative branch cannot hit target. Trampolin isn't provided\n");
DEBUG_FUNCTION_LINE("***value %08X - target %08X = distance %08X\n", value, target, distance);
case R_PPC_NONE:
break;
case R_PPC_ADDR32:
*((uint32_t *) (target)) = value;
break;
case R_PPC_ADDR16_LO:
*((uint16_t *) (target)) = static_cast<uint16_t>(value & 0xFFFF);
break;
case R_PPC_ADDR16_HI:
*((uint16_t *) (target)) = static_cast<uint16_t>(value >> 16);
break;
case R_PPC_ADDR16_HA:
*((uint16_t *) (target)) = static_cast<uint16_t>((value + 0x8000) >> 16);
break;
case R_PPC_DTPMOD32:
DEBUG_FUNCTION_LINE("################IMPLEMENT ME\n");
//*((int32_t *)(target)) = tlsModuleIndex;
break;
case R_PPC_DTPREL32:
*((uint32_t *) (target)) = value;
break;
case R_PPC_GHS_REL16_HA:
*((uint16_t *) (target)) = static_cast<uint16_t>((relValue + 0x8000) >> 16);
break;
case R_PPC_GHS_REL16_HI:
*((uint16_t *) (target)) = static_cast<uint16_t>(relValue >> 16);
break;
case R_PPC_GHS_REL16_LO:
*((uint16_t *) (target)) = static_cast<uint16_t>(relValue & 0xFFFF);
break;
case R_PPC_REL14: {
auto distance = static_cast<int32_t>(value) - static_cast<int32_t>(target);
if (distance > 0x7FFC || distance < -0x7FFC) {
DEBUG_FUNCTION_LINE("***14-bit relative branch cannot hit target.");
return false;
} else {
relocation_trampolin_entry_t * freeSlot = NULL;
for(uint32_t i = 0; i < trampolin_data_length; i++) {
// We want to override "old" relocations of imports
// Pending relocations have the status RELOC_TRAMP_IMPORT_IN_PROGRESS.
// When all relocations are done successfully, they will be turned into RELOC_TRAMP_IMPORT_DONE
// so they can be overridden/updated/reused on the next application launch.
//
// Relocations that won't change will have the status RELOC_TRAMP_FIXED and are set to free when the module is unloaded.
if(trampolin_data[i].status == RELOC_TRAMP_FREE ||
trampolin_data[i].status == RELOC_TRAMP_IMPORT_DONE) {
freeSlot = &(trampolin_data[i]);
break;
}
}
if(freeSlot != NULL) {
DEBUG_FUNCTION_LINE("***24-bit relative branch cannot hit target. Trampolin data list is full\n");
DEBUG_FUNCTION_LINE("***value %08X - target %08X = distance %08X\n", value, target, distance);
return false;
}
if(target - (uint32_t)&(freeSlot->trampolin[0]) > 0x1FFFFFC) {
DEBUG_FUNCTION_LINE("**Cannot link 24-bit jump (too far to tramp buffer).");
DEBUG_FUNCTION_LINE("***value %08X - target %08X = distance %08X\n", value, target, distance);
return false;
}
DEBUG_FUNCTION_LINE("freeSlot = %08X", freeSlot);
freeSlot->trampolin[0] = 0x3D600000 | ((((uint32_t) value) >> 16) & 0x0000FFFF); // lis r11, real_addr@h
freeSlot->trampolin[1] = 0x616B0000 | (((uint32_t) value) & 0x0000ffff); // ori r11, r11, real_addr@l
freeSlot->trampolin[2] = 0x7D6903A6; // mtctr r11
freeSlot->trampolin[3] = 0x4E800420; // bctr
DCFlushRange((void*)freeSlot->trampolin, sizeof(freeSlot->trampolin));
ICInvalidateRange((unsigned char*)freeSlot->trampolin, sizeof(freeSlot->trampolin));
freeSlot->id = trampolinId;
DCFlushRange((void*)&freeSlot->id, sizeof(freeSlot->id));
ICInvalidateRange((unsigned char*)&freeSlot->id, sizeof(freeSlot->id));
if(reloc_type == RELOC_TYPE_FIXED) {
freeSlot->status = RELOC_TRAMP_FIXED;
} else {
// Relocations for the imports may be overridden
freeSlot->status = RELOC_TRAMP_IMPORT_IN_PROGRESS;
}
uint32_t symbolValue = (uint32_t)&(freeSlot->trampolin[0]);
value = symbolValue + addend;
distance = static_cast<int32_t>(value) - static_cast<int32_t>(target);
DEBUG_FUNCTION_LINE("Created tramp\n");
}
}
if (distance & 3) {
DEBUG_FUNCTION_LINE("***RELOC ERROR %d: lower 2 bits must be zero before shifting.", -470022);
if (distance & 3) {
DEBUG_FUNCTION_LINE("***RELOC ERROR %d: lower 2 bits must be zero before shifting.", -470040);
return false;
}
if ((distance >= 0 && (distance & 0xFFFF8000)) ||
(distance < 0 && ((distance & 0xFFFF8000) != 0xFFFF8000))) {
DEBUG_FUNCTION_LINE("***RELOC ERROR %d: upper 17 bits before shift must all be the same.", -470040);
return false;
}
*(int32_t *) target = (*(int32_t *) target & 0xFFBF0003) | (distance & 0x0000fffc);
break;
}
case R_PPC_REL24: {
// if (isWeakSymbol && !symbolValue) {
// symbolValue = static_cast<uint32_t>(target);
// value = symbolValue + addend;
// }
auto distance = static_cast<int32_t>(value) - static_cast<int32_t>(target);
if (distance > 0x1FFFFFC || distance < -0x1FFFFFC) {
if (trampolin_data == NULL) {
DEBUG_FUNCTION_LINE("***24-bit relative branch cannot hit target. Trampolin isn't provided\n");
DEBUG_FUNCTION_LINE("***value %08X - target %08X = distance %08X\n", value, target, distance);
return false;
} else {
relocation_trampolin_entry_t *freeSlot = NULL;
for (uint32_t i = 0; i < trampolin_data_length; i++) {
// We want to override "old" relocations of imports
// Pending relocations have the status RELOC_TRAMP_IMPORT_IN_PROGRESS.
// When all relocations are done successfully, they will be turned into RELOC_TRAMP_IMPORT_DONE
// so they can be overridden/updated/reused on the next application launch.
//
// Relocations that won't change will have the status RELOC_TRAMP_FIXED and are set to free when the module is unloaded.
if (trampolin_data[i].status == RELOC_TRAMP_FREE ||
trampolin_data[i].status == RELOC_TRAMP_IMPORT_DONE) {
freeSlot = &(trampolin_data[i]);
break;
}
}
if (freeSlot != NULL) {
DEBUG_FUNCTION_LINE("***24-bit relative branch cannot hit target. Trampolin data list is full\n");
DEBUG_FUNCTION_LINE("***value %08X - target %08X = distance %08X\n", value, target, distance);
return false;
}
if (target - (uint32_t) &(freeSlot->trampolin[0]) > 0x1FFFFFC) {
DEBUG_FUNCTION_LINE("**Cannot link 24-bit jump (too far to tramp buffer).");
DEBUG_FUNCTION_LINE("***value %08X - target %08X = distance %08X\n", value, target, distance);
return false;
}
DEBUG_FUNCTION_LINE("freeSlot = %08X", freeSlot);
freeSlot->trampolin[0] = 0x3D600000 | ((((uint32_t) value) >> 16) & 0x0000FFFF); // lis r11, real_addr@h
freeSlot->trampolin[1] = 0x616B0000 | (((uint32_t) value) & 0x0000ffff); // ori r11, r11, real_addr@l
freeSlot->trampolin[2] = 0x7D6903A6; // mtctr r11
freeSlot->trampolin[3] = 0x4E800420; // bctr
DCFlushRange((void *) freeSlot->trampolin, sizeof(freeSlot->trampolin));
ICInvalidateRange((unsigned char *) freeSlot->trampolin, sizeof(freeSlot->trampolin));
freeSlot->id = trampolinId;
DCFlushRange((void *) &freeSlot->id, sizeof(freeSlot->id));
ICInvalidateRange((unsigned char *) &freeSlot->id, sizeof(freeSlot->id));
if (reloc_type == RELOC_TYPE_FIXED) {
freeSlot->status = RELOC_TRAMP_FIXED;
} else {
// Relocations for the imports may be overridden
freeSlot->status = RELOC_TRAMP_IMPORT_IN_PROGRESS;
}
uint32_t symbolValue = (uint32_t) &(freeSlot->trampolin[0]);
value = symbolValue + addend;
distance = static_cast<int32_t>(value) - static_cast<int32_t>(target);
DEBUG_FUNCTION_LINE("Created tramp\n");
}
}
if (distance & 3) {
DEBUG_FUNCTION_LINE("***RELOC ERROR %d: lower 2 bits must be zero before shifting.", -470022);
return false;
}
if (distance < 0 && (distance & 0xFE000000) != 0xFE000000) {
DEBUG_FUNCTION_LINE("***RELOC ERROR %d: upper 7 bits before shift must all be the same (1).", -470040);
return false;
}
if (distance >= 0 && (distance & 0xFE000000)) {
DEBUG_FUNCTION_LINE("***RELOC ERROR %d: upper 7 bits before shift must all be the same (0).", -470040);
return false;
}
*(int32_t *) target = (*(int32_t *) target & 0xfc000003) | (distance & 0x03fffffc);
break;
}
default:
DEBUG_FUNCTION_LINE("***ERROR: Unsupported Relocation_Add Type (%08X):", type);
return false;
}
if (distance < 0 && (distance & 0xFE000000) != 0xFE000000) {
DEBUG_FUNCTION_LINE("***RELOC ERROR %d: upper 7 bits before shift must all be the same (1).", -470040);
return false;
}
if (distance >= 0 && (distance & 0xFE000000)) {
DEBUG_FUNCTION_LINE("***RELOC ERROR %d: upper 7 bits before shift must all be the same (0).", -470040);
return false;
}
*(int32_t *)target = (*(int32_t *)target & 0xfc000003) | (distance & 0x03fffffc);
break;
}
default:
DEBUG_FUNCTION_LINE("***ERROR: Unsupported Relocation_Add Type (%08X):", type);
return false;
}
return true;
}

View File

@ -7,9 +7,9 @@
extern "C" {
#endif
int32_t LoadFileToMem(const char *relativefilepath, char **fileOut, uint32_t * sizeOut);
uint32_t load_loader_elf_from_sd(unsigned char* baseAddress, const char* relativePath);
uint32_t load_loader_elf(unsigned char* baseAddress, char * elf_data, uint32_t fileSize);
int32_t LoadFileToMem(const char *relativefilepath, char **fileOut, uint32_t *sizeOut);
uint32_t load_loader_elf_from_sd(unsigned char *baseAddress, const char *relativePath);
uint32_t load_loader_elf(unsigned char *baseAddress, char *elf_data, uint32_t fileSize);
#define R_PPC_NONE 0
#define R_PPC_ADDR32 1
@ -46,5 +46,5 @@ uint32_t load_loader_elf(unsigned char* baseAddress, char * elf_data, uint32_t f
class ElfUtils {
public:
static bool elfLinkOne(char type, size_t offset, int32_t addend, uint32_t destination, uint32_t symbol_addr, relocation_trampolin_entry_t * trampolin_data, uint32_t trampolin_data_length, RelocationType reloc_type, uint8_t trampolinId);
static bool elfLinkOne(char type, size_t offset, int32_t addend, uint32_t destination, uint32_t symbol_addr, relocation_trampolin_entry_t *trampolin_data, uint32_t trampolin_data_length, RelocationType reloc_type, uint8_t trampolinId);
};

View File

@ -36,13 +36,13 @@
#include <utils/StringTools.h>
BOOL StringTools::EndsWith(const std::string& a, const std::string& b) {
BOOL StringTools::EndsWith(const std::string &a, const std::string &b) {
if (b.size() > a.size())
return false;
return std::equal(a.begin() + a.size() - b.size(), a.end(), b.begin());
}
const char * StringTools::byte_to_binary(int32_t x) {
const char *StringTools::byte_to_binary(int32_t x) {
static char b[9];
b[0] = '\0';
@ -54,25 +54,25 @@ const char * StringTools::byte_to_binary(int32_t x) {
return b;
}
std::string StringTools::removeCharFromString(std::string& input,char toBeRemoved) {
std::string StringTools::removeCharFromString(std::string &input, char toBeRemoved) {
std::string output = input;
size_t position;
while(1) {
while (1) {
position = output.find(toBeRemoved);
if(position == std::string::npos)
if (position == std::string::npos)
break;
output.erase(position, 1);
}
return output;
}
const char * StringTools::fmt(const char * format, ...) {
const char *StringTools::fmt(const char *format, ...) {
static char strChar[512];
strChar[0] = 0;
va_list va;
va_start(va, format);
if((vsprintf(strChar, format, va) >= 0)) {
if ((vsprintf(strChar, format, va) >= 0)) {
va_end(va);
return (const char *) strChar;
}
@ -81,26 +81,26 @@ const char * StringTools::fmt(const char * format, ...) {
return NULL;
}
const wchar_t * StringTools::wfmt(const char * format, ...) {
const wchar_t *StringTools::wfmt(const char *format, ...) {
static char tmp[512];
static wchar_t strWChar[512];
strWChar[0] = 0;
tmp[0] = 0;
if(!format)
if (!format)
return (const wchar_t *) strWChar;
if(strcmp(format, "") == 0)
if (strcmp(format, "") == 0)
return (const wchar_t *) strWChar;
va_list va;
va_start(va, format);
if((vsprintf(tmp, format, va) >= 0)) {
int bt;
if ((vsprintf(tmp, format, va) >= 0)) {
int bt;
int32_t strlength = strlen(tmp);
bt = mbstowcs(strWChar, tmp, (strlength < 512) ? strlength : 512 );
bt = mbstowcs(strWChar, tmp, (strlength < 512) ? strlength : 512);
if(bt > 0) {
if (bt > 0) {
strWChar[bt] = 0;
return (const wchar_t *) strWChar;
}
@ -110,14 +110,14 @@ const wchar_t * StringTools::wfmt(const char * format, ...) {
return NULL;
}
int32_t StringTools::strprintf(std::string &str, const char * format, ...) {
int32_t StringTools::strprintf(std::string &str, const char *format, ...) {
static char tmp[512];
tmp[0] = 0;
int32_t result = 0;
va_list va;
va_start(va, format);
if((vsprintf(tmp, format, va) >= 0)) {
if ((vsprintf(tmp, format, va) >= 0)) {
str = tmp;
result = str.size();
}
@ -126,14 +126,14 @@ int32_t StringTools::strprintf(std::string &str, const char * format, ...) {
return result;
}
std::string StringTools::strfmt(const char * format, ...) {
std::string StringTools::strfmt(const char *format, ...) {
std::string str;
static char tmp[512];
tmp[0] = 0;
va_list va;
va_start(va, format);
if((vsprintf(tmp, format, va) >= 0)) {
if ((vsprintf(tmp, format, va) >= 0)) {
str = tmp;
}
va_end(va);
@ -141,11 +141,11 @@ std::string StringTools::strfmt(const char * format, ...) {
return str;
}
BOOL StringTools::char2wchar_t(const char * strChar, wchar_t * dest) {
if(!strChar || !dest)
BOOL StringTools::char2wchar_t(const char *strChar, wchar_t *dest) {
if (!strChar || !dest)
return false;
int bt;
int bt;
bt = mbstowcs(dest, strChar, strlen(strChar));
if (bt > 0) {
dest[bt] = 0;
@ -155,39 +155,39 @@ BOOL StringTools::char2wchar_t(const char * strChar, wchar_t * dest) {
return false;
}
int32_t StringTools::strtokcmp(const char * string, const char * compare, const char * separator) {
if(!string || !compare)
int32_t StringTools::strtokcmp(const char *string, const char *compare, const char *separator) {
if (!string || !compare)
return -1;
char TokCopy[512];
strncpy(TokCopy, compare, sizeof(TokCopy));
TokCopy[511] = '\0';
char * strTok = strtok(TokCopy, separator);
char *strTok = strtok(TokCopy, separator);
while (strTok != NULL) {
if (strcasecmp(string, strTok) == 0) {
return 0;
}
strTok = strtok(NULL,separator);
strTok = strtok(NULL, separator);
}
return -1;
}
int32_t StringTools::strextcmp(const char * string, const char * extension, char seperator) {
if(!string || !extension)
int32_t StringTools::strextcmp(const char *string, const char *extension, char seperator) {
if (!string || !extension)
return -1;
char *ptr = strrchr(string, seperator);
if(!ptr)
if (!ptr)
return -1;
return strcasecmp(ptr + 1, extension);
}
std::vector<std::string> StringTools::stringSplit(const std::string & inValue, const std::string & splitter) {
std::vector<std::string> StringTools::stringSplit(const std::string &inValue, const std::string &splitter) {
std::string value = inValue;
std::vector<std::string> result;
while (true) {
@ -202,7 +202,7 @@ std::vector<std::string> StringTools::stringSplit(const std::string & inValue, c
result.push_back("");
break;
}
if(index + splitter.size() > value.length()) {
if (index + splitter.size() > value.length()) {
break;
}
value = value.substr(index + splitter.size(), value.length());

View File

@ -32,27 +32,36 @@
class StringTools {
public:
static BOOL EndsWith(const std::string& a, const std::string& b);
static const char * byte_to_binary(int32_t x);
static std::string removeCharFromString(std::string& input,char toBeRemoved);
static const char * fmt(const char * format, ...);
static const wchar_t * wfmt(const char * format, ...);
static int32_t strprintf(std::string &str, const char * format, ...);
static std::string strfmt(const char * format, ...);
static BOOL char2wchar_t(const char * src, wchar_t * dest);
static int32_t strtokcmp(const char * string, const char * compare, const char * separator);
static int32_t strextcmp(const char * string, const char * extension, char seperator);
static BOOL EndsWith(const std::string &a, const std::string &b);
static const char * FullpathToFilename(const char *path) {
if(!path)
static const char *byte_to_binary(int32_t x);
static std::string removeCharFromString(std::string &input, char toBeRemoved);
static const char *fmt(const char *format, ...);
static const wchar_t *wfmt(const char *format, ...);
static int32_t strprintf(std::string &str, const char *format, ...);
static std::string strfmt(const char *format, ...);
static BOOL char2wchar_t(const char *src, wchar_t *dest);
static int32_t strtokcmp(const char *string, const char *compare, const char *separator);
static int32_t strextcmp(const char *string, const char *extension, char seperator);
static const char *FullpathToFilename(const char *path) {
if (!path)
return path;
const char * ptr = path;
const char * Filename = ptr;
const char *ptr = path;
const char *Filename = ptr;
while(*ptr != '\0') {
if(ptr[0] == '/' && ptr[1] != '\0')
Filename = ptr+1;
while (*ptr != '\0') {
if (ptr[0] == '/' && ptr[1] != '\0')
Filename = ptr + 1;
++ptr;
}
@ -64,8 +73,8 @@ public:
uint32_t length = str.size();
//! clear path of double slashes
for(uint32_t i = 1; i < length; ++i) {
if(str[i-1] == '/' && str[i] == '/') {
for (uint32_t i = 1; i < length; ++i) {
if (str[i - 1] == '/' && str[i] == '/') {
str.erase(i, 1);
i--;
length--;
@ -73,7 +82,7 @@ public:
}
}
static std::vector<std::string> stringSplit(const std::string & value, const std::string & splitter);
static std::vector<std::string> stringSplit(const std::string &value, const std::string &splitter);
};
#endif /* __STRING_TOOLS_H */

View File

@ -70,15 +70,15 @@ typedef struct {
uint8_t alreadyPatched;
} hooks_magic_t;
void PatchInvidualMethodHooks(hooks_magic_t hook_information[],int32_t hook_information_size, volatile uint32_t dynamic_method_calls[]);
void RestoreInvidualInstructions(hooks_magic_t hook_information[],int32_t hook_information_size);
uint32_t GetAddressOfFunction(const char * functionName,uint32_t library);
void PatchInvidualMethodHooks(hooks_magic_t hook_information[], int32_t hook_information_size, volatile uint32_t dynamic_method_calls[]);
void RestoreInvidualInstructions(hooks_magic_t hook_information[], int32_t hook_information_size);
uint32_t GetAddressOfFunction(const char *functionName, uint32_t library);
int32_t isDynamicFunction(uint32_t physicalAddress);
void resetLibs();
//Orignal code by Chadderz.
#define MAKE_MAGIC(x, lib,functionType) { (uint32_t) my_ ## x, (uint32_t) &real_ ## x, lib, # x,0,0,functionType,0}
#define MAKE_MAGIC_NAME(x,y, lib,functionType) { (uint32_t) my_ ## x, (uint32_t) &real_ ## x, lib, # y,0,0,functionType,0}
#define MAKE_MAGIC(x, lib, functionType) { (uint32_t) my_ ## x, (uint32_t) &real_ ## x, lib, # x,0,0,functionType,0}
#define MAKE_MAGIC_NAME(x, y, lib, functionType) { (uint32_t) my_ ## x, (uint32_t) &real_ ## x, lib, # y,0,0,functionType,0}
#ifdef __cplusplus
}

View File

@ -57,10 +57,10 @@ OSDynLoad_Module vpadbase_handle_internal = 0;
* Patches a function that is loaded at the start of each application. Its not required to restore, at least when they are really dynamic.
* "normal" functions should be patch with the normal patcher. Current Code by Maschell with the help of dimok. Orignal code by Chadderz.
*/
void PatchInvidualMethodHooks(hooks_magic_t method_hooks[],int32_t hook_information_size, volatile uint32_t dynamic_method_calls[]) {
void PatchInvidualMethodHooks(hooks_magic_t method_hooks[], int32_t hook_information_size, volatile uint32_t dynamic_method_calls[]) {
resetLibs();
DEBUG_FUNCTION_LINE("Patching %d given functions",hook_information_size);
DEBUG_FUNCTION_LINE("Patching %d given functions", hook_information_size);
/* Patch branches to it. */
volatile uint32_t *space = &dynamic_method_calls[0];
@ -69,11 +69,11 @@ void PatchInvidualMethodHooks(hooks_magic_t method_hooks[],int32_t hook_informat
uint32_t skip_instr = 1;
uint32_t my_instr_len = 6;
uint32_t instr_len = my_instr_len + skip_instr;
uint32_t flush_len = 4*instr_len;
for(int32_t i = 0; i < method_hooks_count; i++) {
log_printf("Patching %s ...",method_hooks[i].functionName);
if(method_hooks[i].functionType == STATIC_FUNCTION && method_hooks[i].alreadyPatched == 1) {
if(isDynamicFunction((uint32_t)OSEffectiveToPhysical(method_hooks[i].realAddr))) {
uint32_t flush_len = 4 * instr_len;
for (int32_t i = 0; i < method_hooks_count; i++) {
log_printf("Patching %s ...", method_hooks[i].functionName);
if (method_hooks[i].functionType == STATIC_FUNCTION && method_hooks[i].alreadyPatched == 1) {
if (isDynamicFunction((uint32_t) OSEffectiveToPhysical(method_hooks[i].realAddr))) {
log_printf("The function %s is a dynamic function. Please fix that <3", method_hooks[i].functionName);
method_hooks[i].functionType = DYNAMIC_FUNCTION;
} else {
@ -84,38 +84,38 @@ void PatchInvidualMethodHooks(hooks_magic_t method_hooks[],int32_t hook_informat
}
uint32_t physical = 0;
uint32_t repl_addr = (uint32_t)method_hooks[i].replaceAddr;
uint32_t call_addr = (uint32_t)method_hooks[i].replaceCall;
uint32_t repl_addr = (uint32_t) method_hooks[i].replaceAddr;
uint32_t call_addr = (uint32_t) method_hooks[i].replaceCall;
uint32_t real_addr = GetAddressOfFunction(method_hooks[i].functionName,method_hooks[i].library);
uint32_t real_addr = GetAddressOfFunction(method_hooks[i].functionName, method_hooks[i].library);
if(!real_addr) {
if (!real_addr) {
log_printf("");
DEBUG_FUNCTION_LINE("OSDynLoad_FindExport failed for %s", method_hooks[i].functionName);
space += instr_len;
continue;
}
if(DEBUG_LOG_DYN) {
DEBUG_FUNCTION_LINE("%s is located at %08X!", method_hooks[i].functionName,real_addr);
if (DEBUG_LOG_DYN) {
DEBUG_FUNCTION_LINE("%s is located at %08X!", method_hooks[i].functionName, real_addr);
}
physical = (uint32_t)OSEffectiveToPhysical(real_addr);
if(!physical) {
physical = (uint32_t) OSEffectiveToPhysical(real_addr);
if (!physical) {
log_printf("Error. Something is wrong with the physical address");
space += instr_len;
continue;
}
if(DEBUG_LOG_DYN) {
DEBUG_FUNCTION_LINE("%s physical is located at %08X!", method_hooks[i].functionName,physical);
if (DEBUG_LOG_DYN) {
DEBUG_FUNCTION_LINE("%s physical is located at %08X!", method_hooks[i].functionName, physical);
}
*(volatile uint32_t *)(call_addr) = (uint32_t)(space) - CODE_RW_BASE_OFFSET;
*(volatile uint32_t *) (call_addr) = (uint32_t) (space) - CODE_RW_BASE_OFFSET;
uint32_t targetAddr = (uint32_t)space;
if(targetAddr < 0x00800000 || targetAddr >= 0x01000000) {
uint32_t targetAddr = (uint32_t) space;
if (targetAddr < 0x00800000 || targetAddr >= 0x01000000) {
targetAddr = (uint32_t) OSEffectiveToPhysical(targetAddr);
} else {
targetAddr = targetAddr + 0x30800000 - 0x00800000;
@ -123,20 +123,20 @@ void PatchInvidualMethodHooks(hooks_magic_t method_hooks[],int32_t hook_informat
KernelCopyData(targetAddr, physical, 4);
ICInvalidateRange((void*)(space), 4);
DCFlushRange((void*)(space), 4);
ICInvalidateRange((void *) (space), 4);
DCFlushRange((void *) (space), 4);
space++;
//Only works if skip_instr == 1
if(skip_instr == 1) {
if (skip_instr == 1) {
// fill the restore instruction section
method_hooks[i].realAddr = real_addr;
method_hooks[i].restoreInstruction = *(space-1);
if(DEBUG_LOG_DYN) {
method_hooks[i].restoreInstruction = *(space - 1);
if (DEBUG_LOG_DYN) {
DEBUG_FUNCTION_LINE("method_hooks[i].realAddr = %08X!", method_hooks[i].realAddr);
}
if(DEBUG_LOG_DYN) {
DEBUG_FUNCTION_LINE("method_hooks[i].restoreInstruction = %08X!",method_hooks[i].restoreInstruction) ;
if (DEBUG_LOG_DYN) {
DEBUG_FUNCTION_LINE("method_hooks[i].restoreInstruction = %08X!", method_hooks[i].restoreInstruction);
}
} else {
log_printf("Error. Can't save %s for restoring!", method_hooks[i].functionName);
@ -154,7 +154,7 @@ void PatchInvidualMethodHooks(hooks_magic_t method_hooks[],int32_t hook_informat
space++;
*space = 0x3C600000 | (((real_addr + (skip_instr * 4)) >> 16) & 0x0000FFFF); // lis r3, real_addr@h
space++;
*space = 0x60630000 | ((real_addr + (skip_instr * 4)) & 0x0000ffff); // ori r3, r3, real_addr@l
*space = 0x60630000 | ((real_addr + (skip_instr * 4)) & 0x0000ffff); // ori r3, r3, real_addr@l
space++;
*space = 0x7C6903A6; // mtctr r3
space++;
@ -162,15 +162,15 @@ void PatchInvidualMethodHooks(hooks_magic_t method_hooks[],int32_t hook_informat
space++;
*space = 0x4E800420; // bctr
space++;
DCFlushRange((void*)(space - instr_len), flush_len);
ICInvalidateRange((unsigned char*)(space - instr_len), flush_len);
DCFlushRange((void *) (space - instr_len), flush_len);
ICInvalidateRange((unsigned char *) (space - instr_len), flush_len);
//setting jump back
uint32_t replace_instr = 0x48000002 | (repl_addr & 0x03fffffc);
DCFlushRange(&replace_instr, 4);
KernelCopyData(physical, (uint32_t)OSEffectiveToPhysical((uint32_t)&replace_instr), 4);
ICInvalidateRange((void*)(real_addr), 4);
KernelCopyData(physical, (uint32_t) OSEffectiveToPhysical((uint32_t) &replace_instr), 4);
ICInvalidateRange((void *) (real_addr), 4);
method_hooks[i].alreadyPatched = 1;
log_printf("done!\n");
@ -182,49 +182,49 @@ void PatchInvidualMethodHooks(hooks_magic_t method_hooks[],int32_t hook_informat
/* ****************************************************************** */
/* RESTORE ORIGINAL INSTRUCTIONS */
/* ****************************************************************** */
void RestoreInvidualInstructions(hooks_magic_t method_hooks[],int32_t hook_information_size) {
void RestoreInvidualInstructions(hooks_magic_t method_hooks[], int32_t hook_information_size) {
resetLibs();
DEBUG_FUNCTION_LINE("Restoring given functions!");
int32_t method_hooks_count = hook_information_size;
for(int32_t i = 0; i < method_hooks_count; i++) {
DEBUG_FUNCTION_LINE("Restoring %s... ",method_hooks[i].functionName);
if(method_hooks[i].restoreInstruction == 0 || method_hooks[i].realAddr == 0) {
for (int32_t i = 0; i < method_hooks_count; i++) {
DEBUG_FUNCTION_LINE("Restoring %s... ", method_hooks[i].functionName);
if (method_hooks[i].restoreInstruction == 0 || method_hooks[i].realAddr == 0) {
log_printf("I dont have the information for the restore =( skip");
continue;
}
uint32_t real_addr = GetAddressOfFunction(method_hooks[i].functionName,method_hooks[i].library);
uint32_t real_addr = GetAddressOfFunction(method_hooks[i].functionName, method_hooks[i].library);
if(!real_addr) {
if (!real_addr) {
log_printf("OSDynLoad_FindExport failed for %s", method_hooks[i].functionName);
continue;
}
uint32_t physical = (uint32_t)OSEffectiveToPhysical(real_addr);
if(!physical) {
uint32_t physical = (uint32_t) OSEffectiveToPhysical(real_addr);
if (!physical) {
log_printf("Something is wrong with the physical address");
continue;
}
if(isDynamicFunction(physical)) {
log_printf("Its a dynamic function. We don't need to restore it!",method_hooks[i].functionName);
if (isDynamicFunction(physical)) {
log_printf("Its a dynamic function. We don't need to restore it!", method_hooks[i].functionName);
} else {
physical = (uint32_t)OSEffectiveToPhysical(method_hooks[i].realAddr); //When its an static function, we need to use the old location
if(DEBUG_LOG_DYN) {
DEBUG_FUNCTION_LINE("Restoring %08X to %08X",(uint32_t)method_hooks[i].restoreInstruction,physical);
physical = (uint32_t) OSEffectiveToPhysical(method_hooks[i].realAddr); //When its an static function, we need to use the old location
if (DEBUG_LOG_DYN) {
DEBUG_FUNCTION_LINE("Restoring %08X to %08X", (uint32_t) method_hooks[i].restoreInstruction, physical);
}
uint32_t targetAddr = (uint32_t)&method_hooks[i].restoreInstruction;
if(targetAddr < 0x00800000 || targetAddr >= 0x01000000) {
uint32_t targetAddr = (uint32_t) &method_hooks[i].restoreInstruction;
if (targetAddr < 0x00800000 || targetAddr >= 0x01000000) {
targetAddr = (uint32_t) OSEffectiveToPhysical(targetAddr);
} else {
targetAddr = targetAddr + 0x30800000 - 0x00800000;
}
KernelCopyData(physical,targetAddr, 4);
if(DEBUG_LOG_DYN) {
DEBUG_FUNCTION_LINE("ICInvalidateRange %08X",(void*)method_hooks[i].realAddr);
KernelCopyData(physical, targetAddr, 4);
if (DEBUG_LOG_DYN) {
DEBUG_FUNCTION_LINE("ICInvalidateRange %08X", (void *) method_hooks[i].realAddr);
}
ICInvalidateRange((void*)method_hooks[i].realAddr, 4);
ICInvalidateRange((void *) method_hooks[i].realAddr, 4);
log_printf("done");
}
method_hooks[i].alreadyPatched = 0; // In case a
@ -234,13 +234,13 @@ void RestoreInvidualInstructions(hooks_magic_t method_hooks[],int32_t hook_infor
}
int32_t isDynamicFunction(uint32_t physicalAddress) {
if((physicalAddress & 0x80000000) == 0x80000000) {
if ((physicalAddress & 0x80000000) == 0x80000000) {
return 1;
}
return 0;
}
uint32_t GetAddressOfFunction(const char * functionName,uint32_t library) {
uint32_t GetAddressOfFunction(const char *functionName, uint32_t library) {
uint32_t real_addr = 0;
/*
@ -262,282 +262,282 @@ uint32_t GetAddressOfFunction(const char * functionName,uint32_t library) {
*/
OSDynLoad_Module rpl_handle = 0;
if(library == LIB_CORE_INIT) {
if(DEBUG_LOG_DYN) {
if (library == LIB_CORE_INIT) {
if (DEBUG_LOG_DYN) {
DEBUG_FUNCTION_LINE("FindExport of %s! From LIB_CORE_INIT", functionName);
}
if(coreinit_handle_internal == 0) {
if (coreinit_handle_internal == 0) {
OSDynLoad_Acquire("coreinit.rpl", &coreinit_handle_internal);
}
if(coreinit_handle_internal == 0) {
if (coreinit_handle_internal == 0) {
DEBUG_FUNCTION_LINE("LIB_CORE_INIT failed to acquire");
return 0;
}
rpl_handle = coreinit_handle_internal;
} else if(library == LIB_NSYSNET) {
if(DEBUG_LOG_DYN) {
} else if (library == LIB_NSYSNET) {
if (DEBUG_LOG_DYN) {
DEBUG_FUNCTION_LINE("FindExport of %s! From LIB_NSYSNET", functionName);
}
if(nsysnet_handle_internal == 0) {
if (nsysnet_handle_internal == 0) {
OSDynLoad_Acquire("nsysnet.rpl", &nsysnet_handle_internal);
}
if(nsysnet_handle_internal == 0) {
if (nsysnet_handle_internal == 0) {
DEBUG_FUNCTION_LINE("LIB_NSYSNET failed to acquire");
return 0;
}
rpl_handle = nsysnet_handle_internal;
} else if(library == LIB_GX2) {
if(DEBUG_LOG_DYN) {
} else if (library == LIB_GX2) {
if (DEBUG_LOG_DYN) {
DEBUG_FUNCTION_LINE("FindExport of %s! From LIB_GX2", functionName);
}
if(gx2_handle_internal == 0) {
if (gx2_handle_internal == 0) {
OSDynLoad_Acquire("gx2.rpl", &gx2_handle_internal);
}
if(gx2_handle_internal == 0) {
if (gx2_handle_internal == 0) {
DEBUG_FUNCTION_LINE("LIB_GX2 failed to acquire");
return 0;
}
rpl_handle = gx2_handle_internal;
} else if(library == LIB_AOC) {
if(DEBUG_LOG_DYN) {
} else if (library == LIB_AOC) {
if (DEBUG_LOG_DYN) {
DEBUG_FUNCTION_LINE("FindExport of %s! From LIB_AOC", functionName);
}
if(aoc_handle_internal == 0) {
if (aoc_handle_internal == 0) {
OSDynLoad_Acquire("nn_aoc.rpl", &aoc_handle_internal);
}
if(aoc_handle_internal == 0) {
if (aoc_handle_internal == 0) {
DEBUG_FUNCTION_LINE("LIB_AOC failed to acquire");
return 0;
}
rpl_handle = aoc_handle_internal;
} else if(library == LIB_AX) {
if(DEBUG_LOG_DYN) {
} else if (library == LIB_AX) {
if (DEBUG_LOG_DYN) {
DEBUG_FUNCTION_LINE("FindExport of %s! From LIB_AX", functionName);
}
if(sound_handle_internal == 0) {
if (sound_handle_internal == 0) {
OSDynLoad_Acquire("sndcore2.rpl", &sound_handle_internal);
}
if(sound_handle_internal == 0) {
if (sound_handle_internal == 0) {
DEBUG_FUNCTION_LINE("LIB_AX failed to acquire");
return 0;
}
rpl_handle = sound_handle_internal;
} else if(library == LIB_AX_OLD) {
if(DEBUG_LOG_DYN) {
} else if (library == LIB_AX_OLD) {
if (DEBUG_LOG_DYN) {
DEBUG_FUNCTION_LINE("FindExport of %s! From LIB_AX_OLD", functionName);
}
if(sound_handle_internal_old == 0) {
if (sound_handle_internal_old == 0) {
OSDynLoad_Acquire("snd_core.rpl", &sound_handle_internal_old);
}
if(sound_handle_internal_old == 0) {
if (sound_handle_internal_old == 0) {
DEBUG_FUNCTION_LINE("LIB_AX_OLD failed to acquire");
return 0;
}
rpl_handle = sound_handle_internal_old;
} else if(library == LIB_FS) {
if(DEBUG_LOG_DYN) {
} else if (library == LIB_FS) {
if (DEBUG_LOG_DYN) {
DEBUG_FUNCTION_LINE("FindExport of %s! From LIB_FS", functionName);
}
if(coreinit_handle_internal == 0) {
if (coreinit_handle_internal == 0) {
OSDynLoad_Acquire("coreinit.rpl", &coreinit_handle_internal);
}
if(coreinit_handle_internal == 0) {
if (coreinit_handle_internal == 0) {
DEBUG_FUNCTION_LINE("LIB_FS failed to acquire");
return 0;
}
rpl_handle = coreinit_handle_internal;
} else if(library == LIB_OS) {
if(DEBUG_LOG_DYN) {
} else if (library == LIB_OS) {
if (DEBUG_LOG_DYN) {
DEBUG_FUNCTION_LINE("FindExport of %s! From LIB_OS", functionName);
}
if(coreinit_handle_internal == 0) {
if (coreinit_handle_internal == 0) {
OSDynLoad_Acquire("coreinit.rpl", &coreinit_handle_internal);
}
if(coreinit_handle_internal == 0) {
if (coreinit_handle_internal == 0) {
DEBUG_FUNCTION_LINE("LIB_OS failed to acquire");
return 0;
}
rpl_handle = coreinit_handle_internal;
} else if(library == LIB_PADSCORE) {
if(DEBUG_LOG_DYN) {
} else if (library == LIB_PADSCORE) {
if (DEBUG_LOG_DYN) {
DEBUG_FUNCTION_LINE("FindExport of %s! From LIB_PADSCORE", functionName);
}
if(padscore_handle_internal == 0) {
if (padscore_handle_internal == 0) {
OSDynLoad_Acquire("padscore.rpl", &padscore_handle_internal);
}
if(padscore_handle_internal == 0) {
if (padscore_handle_internal == 0) {
DEBUG_FUNCTION_LINE("LIB_PADSCORE failed to acquire");
return 0;
}
rpl_handle = padscore_handle_internal;
} else if(library == LIB_SOCKET) {
if(DEBUG_LOG_DYN) {
} else if (library == LIB_SOCKET) {
if (DEBUG_LOG_DYN) {
DEBUG_FUNCTION_LINE("FindExport of %s! From LIB_SOCKET", functionName);
}
if(nsysnet_handle_internal == 0) {
if (nsysnet_handle_internal == 0) {
OSDynLoad_Acquire("nsysnet.rpl", &nsysnet_handle_internal);
}
if(nsysnet_handle_internal == 0) {
if (nsysnet_handle_internal == 0) {
DEBUG_FUNCTION_LINE("LIB_SOCKET failed to acquire");
return 0;
}
rpl_handle = nsysnet_handle_internal;
} else if(library == LIB_SYS) {
if(DEBUG_LOG_DYN) {
} else if (library == LIB_SYS) {
if (DEBUG_LOG_DYN) {
DEBUG_FUNCTION_LINE("FindExport of %s! From LIB_SYS", functionName);
}
if(sysapp_handle_internal == 0) {
if (sysapp_handle_internal == 0) {
OSDynLoad_Acquire("sysapp.rpl", &sysapp_handle_internal);
}
if(sysapp_handle_internal == 0) {
if (sysapp_handle_internal == 0) {
DEBUG_FUNCTION_LINE("LIB_SYS failed to acquire");
return 0;
}
rpl_handle = sysapp_handle_internal;
} else if(library == LIB_VPAD) {
if(DEBUG_LOG_DYN) {
} else if (library == LIB_VPAD) {
if (DEBUG_LOG_DYN) {
DEBUG_FUNCTION_LINE("FindExport of %s! From LIB_VPAD", functionName);
}
if(vpad_handle_internal == 0) {
if (vpad_handle_internal == 0) {
OSDynLoad_Acquire("vpad.rpl", &vpad_handle_internal);
}
if(vpad_handle_internal == 0) {
if (vpad_handle_internal == 0) {
DEBUG_FUNCTION_LINE("LIB_VPAD failed to acquire");
return 0;
}
rpl_handle = vpad_handle_internal;
} else if(library == LIB_NN_ACP) {
if(DEBUG_LOG_DYN) {
} else if (library == LIB_NN_ACP) {
if (DEBUG_LOG_DYN) {
DEBUG_FUNCTION_LINE("FindExport of %s! From LIB_NN_ACP", functionName);
}
if(acp_handle_internal == 0) {
if (acp_handle_internal == 0) {
OSDynLoad_Acquire("nn_acp.rpl", &acp_handle_internal);
}
if(acp_handle_internal == 0) {
if (acp_handle_internal == 0) {
DEBUG_FUNCTION_LINE("LIB_NN_ACP failed to acquire");
return 0;
}
rpl_handle = acp_handle_internal;
} else if(library == LIB_SYSHID) {
if(DEBUG_LOG_DYN) {
} else if (library == LIB_SYSHID) {
if (DEBUG_LOG_DYN) {
DEBUG_FUNCTION_LINE("FindExport of %s! From LIB_SYSHID", functionName);
}
if(syshid_handle_internal == 0) {
if (syshid_handle_internal == 0) {
OSDynLoad_Acquire("nsyshid.rpl", &syshid_handle_internal);
}
if(syshid_handle_internal == 0) {
if (syshid_handle_internal == 0) {
DEBUG_FUNCTION_LINE("LIB_SYSHID failed to acquire");
return 0;
}
rpl_handle = syshid_handle_internal;
} else if(library == LIB_VPADBASE) {
if(DEBUG_LOG_DYN) {
} else if (library == LIB_VPADBASE) {
if (DEBUG_LOG_DYN) {
DEBUG_FUNCTION_LINE("FindExport of %s! From LIB_VPADBASE", functionName);
}
if(vpadbase_handle_internal == 0) {
if (vpadbase_handle_internal == 0) {
OSDynLoad_Acquire("vpadbase.rpl", &vpadbase_handle_internal);
}
if(vpadbase_handle_internal == 0) {
if (vpadbase_handle_internal == 0) {
DEBUG_FUNCTION_LINE("LIB_VPADBASE failed to acquire");
return 0;
}
rpl_handle = vpadbase_handle_internal;
} else if(library == LIB_PROC_UI) {
if(DEBUG_LOG_DYN) {
} else if (library == LIB_PROC_UI) {
if (DEBUG_LOG_DYN) {
DEBUG_FUNCTION_LINE("FindExport of %s! From LIB_PROC_UI", functionName);
}
if(proc_ui_handle_internal == 0) {
if (proc_ui_handle_internal == 0) {
OSDynLoad_Acquire("proc_ui.rpl", &proc_ui_handle_internal);
}
if(proc_ui_handle_internal == 0) {
if (proc_ui_handle_internal == 0) {
DEBUG_FUNCTION_LINE("LIB_PROC_UI failed to acquire");
return 0;
}
rpl_handle = proc_ui_handle_internal;
} else if(library == LIB_NTAG) {
if(DEBUG_LOG_DYN) {
} else if (library == LIB_NTAG) {
if (DEBUG_LOG_DYN) {
log_printf("FindExport of %s! From LIB_NTAG", functionName);
}
if(ntag_handle_internal == 0) {
if (ntag_handle_internal == 0) {
OSDynLoad_Acquire("ntag.rpl", &ntag_handle_internal);
}
if(ntag_handle_internal == 0) {
if (ntag_handle_internal == 0) {
log_print("LIB_NTAG failed to acquire");
return 0;
}
rpl_handle = ntag_handle_internal;
} else if(library == LIB_NFP) {
if(DEBUG_LOG_DYN) {
} else if (library == LIB_NFP) {
if (DEBUG_LOG_DYN) {
log_printf("FindExport of %s! From LIB_NFP", functionName);
}
if(nfp_handle_internal == 0) {
if (nfp_handle_internal == 0) {
OSDynLoad_Acquire("nn_nfp.rpl", &nfp_handle_internal);
}
if(nfp_handle_internal == 0) {
if (nfp_handle_internal == 0) {
log_print("LIB_NFP failed to acquire");
return 0;
}
rpl_handle = nfp_handle_internal;
} else if(library == LIB_SAVE) {
if(DEBUG_LOG_DYN) {
} else if (library == LIB_SAVE) {
if (DEBUG_LOG_DYN) {
log_printf("FindExport of %s! From LIB_SAVE", functionName);
}
if(nn_save_handle_internal == 0) {
if (nn_save_handle_internal == 0) {
OSDynLoad_Acquire("nn_save.rpl", &nn_save_handle_internal);
}
if(nn_save_handle_internal == 0) {
if (nn_save_handle_internal == 0) {
log_print("LIB_SAVE failed to acquire");
return 0;
}
rpl_handle = nn_save_handle_internal;
} else if(library == LIB_ACT) {
if(DEBUG_LOG_DYN) {
} else if (library == LIB_ACT) {
if (DEBUG_LOG_DYN) {
log_printf("FindExport of %s! From LIB_ACT", functionName);
}
if(nn_act_handle_internal == 0) {
if (nn_act_handle_internal == 0) {
OSDynLoad_Acquire("nn_act.rpl", &nn_act_handle_internal);
}
if(nn_act_handle_internal == 0) {
if (nn_act_handle_internal == 0) {
log_print("LIB_ACT failed to acquire");
return 0;
}
rpl_handle = nn_act_handle_internal;
} else if(library == LIB_NIM) {
if(DEBUG_LOG_DYN) {
} else if (library == LIB_NIM) {
if (DEBUG_LOG_DYN) {
log_printf("FindExport of %s! From LIB_NIM", functionName);
}
if(nn_nim_handle_internal == 0) {
if (nn_nim_handle_internal == 0) {
OSDynLoad_Acquire("nn_nim.rpl", &nn_nim_handle_internal);
}
if(nn_nim_handle_internal == 0) {
if (nn_nim_handle_internal == 0) {
log_print("LIB_NIM failed to acquire");
return 0;
}
rpl_handle = nn_nim_handle_internal;
}
if(!rpl_handle) {
if (!rpl_handle) {
DEBUG_FUNCTION_LINE("Failed to find the RPL handle for %s", functionName);
return 0;
}
OSDynLoad_FindExport(rpl_handle, 0, functionName, (void**) &real_addr);
OSDynLoad_FindExport(rpl_handle, 0, functionName, (void **) &real_addr);
if(!real_addr) {
OSDynLoad_FindExport(rpl_handle, 1, functionName, (void**) &real_addr);
if(!real_addr) {
if (!real_addr) {
OSDynLoad_FindExport(rpl_handle, 1, functionName, (void **) &real_addr);
if (!real_addr) {
DEBUG_FUNCTION_LINE("OSDynLoad_FindExport failed for %s", functionName);
return 0;
}
}
if((library == LIB_NN_ACP) && (uint32_t)(*(volatile uint32_t*)(real_addr) & 0x48000002) == 0x48000000) {
uint32_t address_diff = (uint32_t)(*(volatile uint32_t*)(real_addr) & 0x03FFFFFC);
if((address_diff & 0x03000000) == 0x03000000) {
address_diff |= 0xFC000000;
if ((library == LIB_NN_ACP) && (uint32_t) (*(volatile uint32_t *) (real_addr) & 0x48000002) == 0x48000000) {
uint32_t address_diff = (uint32_t) (*(volatile uint32_t *) (real_addr) & 0x03FFFFFC);
if ((address_diff & 0x03000000) == 0x03000000) {
address_diff |= 0xFC000000;
}
real_addr += (int32_t)address_diff;
if((uint32_t)(*(volatile uint32_t*)(real_addr) & 0x48000002) == 0x48000000) {
real_addr += (int32_t) address_diff;
if ((uint32_t) (*(volatile uint32_t *) (real_addr) & 0x48000002) == 0x48000000) {
return 0;
}
}

View File

@ -10,7 +10,7 @@
#include <coreinit/systeminfo.h>
#include <coreinit/thread.h>
static int log_socket __attribute__((section(".data")))= -1;
static int log_socket __attribute__((section(".data"))) = -1;
static struct sockaddr_in connect_addr __attribute__((section(".data")));
static volatile int log_lock __attribute__((section(".data"))) = 0;
@ -30,11 +30,11 @@ void log_init_() {
void log_print_(const char *str) {
// socket is always 0 initially as it is in the BSS
if(log_socket < 0) {
if (log_socket < 0) {
return;
}
while(log_lock)
while (log_lock)
OSSleepTicks(OSMicrosecondsToTicks(1000));
log_lock = 1;
@ -42,8 +42,8 @@ void log_print_(const char *str) {
int ret;
while (len > 0) {
int block = len < 1400 ? len : 1400; // take max 1400 bytes per UDP packet
ret = sendto(log_socket, str, block, 0, (struct sockaddr *)&connect_addr, sizeof(struct sockaddr_in));
if(ret < 0)
ret = sendto(log_socket, str, block, 0, (struct sockaddr *) &connect_addr, sizeof(struct sockaddr_in));
if (ret < 0)
break;
len -= ret;
@ -58,14 +58,14 @@ void OSFatal_printf(const char *format, ...) {
tmp[0] = 0;
va_list va;
va_start(va, format);
if((vsprintf(tmp, format, va) >= 0)) {
if ((vsprintf(tmp, format, va) >= 0)) {
OSFatal(tmp);
}
va_end(va);
}
void log_printf_(const char *format, ...) {
if(log_socket < 0) {
if (log_socket < 0) {
return;
}
@ -74,7 +74,7 @@ void log_printf_(const char *format, ...) {
va_list va;
va_start(va, format);
if((vsprintf(tmp, format, va) >= 0)) {
if ((vsprintf(tmp, format, va) >= 0)) {
log_print_(tmp);
}
va_end(va);

View File

@ -8,9 +8,12 @@ extern "C" {
#include <string.h>
void log_init_();
//void log_deinit_(void);
void log_print_(const char *str);
void log_printf_(const char *format, ...);
void OSFatal_printf(const char *format, ...);
#define __FILENAME_X__ (strrchr(__FILE__, '\\') ? strrchr(__FILE__, '\\') + 1 : __FILE__)
@ -21,7 +24,6 @@ void OSFatal_printf(const char *format, ...);
} while (0)
#define log_init() log_init_()
//#define log_deinit() log_deinit_()
#define log_print(str) log_print_(str)

View File

@ -7,31 +7,31 @@
#include "utils/logger.h"
// https://gist.github.com/ccbrown/9722406
void dumpHex(const void* data, size_t size) {
void dumpHex(const void *data, size_t size) {
char ascii[17];
size_t i, j;
ascii[16] = '\0';
DEBUG_FUNCTION_LINE("0x%08X (0x0000): ", data);
for (i = 0; i < size; ++i) {
log_printf("%02X ", ((unsigned char*)data)[i]);
if (((unsigned char*)data)[i] >= ' ' && ((unsigned char*)data)[i] <= '~') {
ascii[i % 16] = ((unsigned char*)data)[i];
log_printf("%02X ", ((unsigned char *) data)[i]);
if (((unsigned char *) data)[i] >= ' ' && ((unsigned char *) data)[i] <= '~') {
ascii[i % 16] = ((unsigned char *) data)[i];
} else {
ascii[i % 16] = '.';
}
if ((i+1) % 8 == 0 || i+1 == size) {
if ((i + 1) % 8 == 0 || i + 1 == size) {
log_printf(" ");
if ((i+1) % 16 == 0) {
if ((i + 1) % 16 == 0) {
log_printf("| %s \n", ascii);
if(i + 1 < size) {
DEBUG_FUNCTION_LINE("0x%08X (0x%04X); ", data + i + 1,i+1);
if (i + 1 < size) {
DEBUG_FUNCTION_LINE("0x%08X (0x%04X); ", data + i + 1, i + 1);
}
} else if (i+1 == size) {
ascii[(i+1) % 16] = '\0';
if ((i+1) % 16 <= 8) {
} else if (i + 1 == size) {
ascii[(i + 1) % 16] = '\0';
if ((i + 1) % 16 <= 8) {
log_printf(" ");
}
for (j = (i+1) % 16; j < 16; ++j) {
for (j = (i + 1) % 16; j < 16; ++j) {
log_printf(" ");
}
log_printf("| %s \n", ascii);

View File

@ -7,12 +7,12 @@
extern "C" {
#endif
#define LIMIT(x, min, max) \
({ \
typeof( x ) _x = x; \
typeof( min ) _min = min; \
typeof( max ) _max = max; \
( ( ( _x ) < ( _min ) ) ? ( _min ) : ( ( _x ) > ( _max ) ) ? ( _max) : ( _x ) ); \
#define LIMIT(x, min, max) \
({ \
typeof( x ) _x = x; \
typeof( min ) _min = min; \
typeof( max ) _max = max; \
( ( ( _x ) < ( _min ) ) ? ( _min ) : ( ( _x ) > ( _max ) ) ? ( _max) : ( _x ) ); \
})
#define DegToRad(a) ( (a) * 0.01745329252f )
@ -31,7 +31,7 @@ extern "C" {
#define le64(i) ((((uint64_t)le32((i) & 0xFFFFFFFFLL)) << 32) | ((uint64_t)le32(((i) & 0xFFFFFFFF00000000LL) >> 32)))
//Needs to have log_init() called beforehand.
void dumpHex(const void* data, size_t size);
void dumpHex(const void *data, size_t size);
#ifdef __cplusplus
}