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 { class PluginManagement {
public: public:
static void doRelocations(const std::vector<PluginContainer>& plugins, relocation_trampolin_entry_t *trampData, uint32_t tramp_size); 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 memsetBSS(const std::vector<PluginContainer> &plugins);
static void callInitHooks(plugin_information_t *pluginInformation); 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); 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 #define DYN_LINK_TRAMPOLIN_LIST_LENGTH DYN_LINK_FUNCTION_LIST_LENGTH
typedef struct _dyn_linking_function_t { typedef struct _dyn_linking_function_t {
char functionName[DYN_LINK_FUNCTION_NAME_LENGTH+1]; char functionName[DYN_LINK_FUNCTION_NAME_LENGTH + 1];
void * address; void *address;
} dyn_linking_function_t; } dyn_linking_function_t;
typedef struct _dyn_linking_import_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; bool isData = false;
} dyn_linking_import_t; } dyn_linking_import_t;
typedef struct _dyn_linking_relocation_entry_t { typedef struct _dyn_linking_relocation_entry_t {
dyn_linking_function_t* functionEntry = NULL; dyn_linking_function_t *functionEntry = NULL;
dyn_linking_import_t* importEntry = NULL; dyn_linking_import_t *importEntry = NULL;
void * destination = NULL; void *destination = NULL;
char type; char type;
size_t offset; size_t offset;
int32_t addend; int32_t addend;

View File

@ -1,4 +1,5 @@
#pragma once #pragma once
#include <stdint.h> #include <stdint.h>
#include <wups.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))(); ((void (*)(void)) ((uint32_t *) func_ptr))();
} else if (hook_type == WUPS_LOADER_HOOK_APPLICATION_END) { } else if (hook_type == WUPS_LOADER_HOOK_APPLICATION_END) {
((void (*)(void)) ((uint32_t *) func_ptr))(); ((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))(); ((void (*)(void)) ((uint32_t *) func_ptr))();
} else if (hook_type == WUPS_LOADER_HOOK_FINI_WUT_MALLOC) { } else if (hook_type == WUPS_LOADER_HOOK_FINI_WUT_MALLOC) {
((void (*)(void)) ((uint32_t *) func_ptr))(); ((void (*)(void)) ((uint32_t *) func_ptr))();

View File

@ -1,7 +1,10 @@
#pragma once #pragma once
#include <wups.h> #include <wups.h>
#include "common/plugin_defines.h" #include "common/plugin_defines.h"
void CallHook(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); 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) { void KernelWrite(uint32_t addr, const void *data, uint32_t length) {
uint32_t dst = (uint32_t) OSEffectiveToPhysical(addr); 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); KernelCopyData(dst, src, length);
DCFlushRange((void *)addr, length); DCFlushRange((void *) addr, length);
ICInvalidateRange((void *)addr, length); ICInvalidateRange((void *) addr, length);
} }
void KernelWriteU32(uint32_t addr, uint32_t value) { void KernelWriteU32(uint32_t addr, uint32_t value) {
uint32_t dst = (uint32_t) OSEffectiveToPhysical(addr); 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); KernelCopyData(dst, src, 4);
DCFlushRange((void *)addr, 4); DCFlushRange((void *) addr, 4);
ICInvalidateRange((void *)addr, 4); ICInvalidateRange((void *) addr, 4);
} }
/* Write a 32-bit word with kernel permissions */ /* 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 ( asm volatile (
"li 3,1\n" "li 3,1\n"
"li 4,0\n" "li 4,0\n"
"mr 5,%1\n" "mr 5,%1\n"
"li 6,0\n" "li 6,0\n"
"li 7,0\n" "li 7,0\n"
"lis 8,1\n" "lis 8,1\n"
"mr 9,%0\n" "mr 9,%0\n"
"mr %1,1\n" "mr %1,1\n"
"li 0,0x3500\n" "li 0,0x3500\n"
"sc\n" "sc\n"
"nop\n" "nop\n"
"mr 1,%1\n" "mr 1,%1\n"
: :
: "r"(addr), "r"(value) : "r"(addr), "r"(value)
: "memory", "ctr", "lr", "0", "3", "4", "5", "6", "7", "8", "9", "10", : "memory", "ctr", "lr", "0", "3", "4", "5", "6", "7", "8", "9", "10",
"11", "12" "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 __attribute__ ((noinline)) kern_read(const void *addr) {
uint32_t result; uint32_t result;
asm volatile ( asm volatile (
"li 3,1\n" "li 3,1\n"
"li 4,0\n" "li 4,0\n"
"li 5,0\n" "li 5,0\n"
"li 6,0\n" "li 6,0\n"
"li 7,0\n" "li 7,0\n"
"lis 8,1\n" "lis 8,1\n"
"mr 9,%1\n" "mr 9,%1\n"
"li 0,0x3400\n" "li 0,0x3400\n"
"mr %0,1\n" "mr %0,1\n"
"sc\n" "sc\n"
"nop\n" "nop\n"
"mr 1,%0\n" "mr 1,%0\n"
"mr %0,3\n" "mr %0,3\n"
: "=r"(result) : "=r"(result)
: "b"(addr) : "b"(addr)
: "memory", "ctr", "lr", "0", "3", "4", "5", "6", "7", "8", "9", "10", : "memory", "ctr", "lr", "0", "3", "4", "5", "6", "7", "8", "9", "10",
"11", "12" "11", "12"
); );
return result; return result;
@ -80,12 +80,12 @@ void PatchSyscall(int index, uint32_t addr) {
void kernelInitialize() { void kernelInitialize() {
static uint8_t ucSyscallsSetupRequired = 1; static uint8_t ucSyscallsSetupRequired = 1;
if(!ucSyscallsSetupRequired) if (!ucSyscallsSetupRequired)
return; return;
ucSyscallsSetupRequired = 0; 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); 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); uint32_t kern_read(const void *addr);
void SC0x0A_KernelWriteSRs(sr_table_t * table); void SC0x0A_KernelWriteSRs(sr_table_t *table);
void SC0x36_KernelReadSRs(sr_table_t * table);
void SC0x36_KernelReadSRs(sr_table_t *table);
void KernelReadPTE(uint32_t addr, int32_t length); void KernelReadPTE(uint32_t addr, int32_t length);
void KernelWritePTE(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 KernelWrite(uint32_t addr, const void *data, uint32_t length);
void KernelWriteU32(uint32_t addr, uint32_t value); void KernelWriteU32(uint32_t addr, uint32_t value);
void kernelInitialize(); void kernelInitialize();
#ifdef __cplusplus #ifdef __cplusplus

View File

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

View File

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

View File

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

View File

@ -8,7 +8,7 @@
#include <coreinit/core.h> #include <coreinit/core.h>
#include "hooks.h" #include "hooks.h"
extern plugin_information_t * gPluginInformation; extern plugin_information_t *gPluginInformation;
DECL(void, GX2WaitForVsync, void) { DECL(void, GX2WaitForVsync, void) {
CallHook(gPluginInformation, WUPS_LOADER_HOOK_VSYNC); CallHook(gPluginInformation, WUPS_LOADER_HOOK_VSYNC);
@ -28,18 +28,18 @@ void checkMagic(VPADStatus *buffer) {
// Check for rotation every only 5 frames. // Check for rotation every only 5 frames.
angleX_frameCounter++; angleX_frameCounter++;
if(angleX_frameCounter >= 5) { if (angleX_frameCounter >= 5) {
// Get how much the gamepad rotated within the last 5 frames. // Get how much the gamepad rotated within the last 5 frames.
float diff_angle = -(buffer->angle.x - angleX_last); 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). // 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); float target_diff = (0.16f);
// Calculate if rotated enough in this step (including the delta from the last step). // Calculate if rotated enough in this step (including the delta from the last step).
float total_diff = (diff_angle + angleX_delta) - target_diff; 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. // The rotation in this step was enough.
angleX_counter++; angleX_counter++;
// When the gamepad rotated ~0.16% for 6 times in a row we made a full rotation! // 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(); //ConfigUtils::openConfigMenu();
// reset stuff. // reset stuff.
angleX_counter = 0; 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) { 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); 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()) { //if(MemoryMapping::isMemoryMapped()) {
//MemoryMapping::readTestValuesFromMemory(); //MemoryMapping::readTestValuesFromMemory();
//} else { //} else {
// DEBUG_FUNCTION_LINE("Memory was not mapped. To test the memory please exit the plugin loader by pressing MINUS\n"); // DEBUG_FUNCTION_LINE("Memory was not mapped. To test the memory please exit the plugin loader by pressing MINUS\n");
//} //}
vpadPressCooldown = 0x3C; 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(); //ConfigUtils::openConfigMenu();
vpadPressCooldown = 0x3C; vpadPressCooldown = 0x3C;
} else if(result > 0 && OSIsHomeButtonMenuEnabled()) { } else if (result > 0 && OSIsHomeButtonMenuEnabled()) {
checkMagic(buffer); checkMagic(buffer);
} }
if(vpadPressCooldown > 0) { if (vpadPressCooldown > 0) {
vpadPressCooldown--; vpadPressCooldown--;
} }
return result; return result;
} }
/* /*
void setupContextState() { void setupContextState() {
g_vid_ownContextState = (GX2ContextState*)memalign( g_vid_ownContextState = (GX2ContextState*)memalign(
@ -248,7 +249,7 @@ DECL_FUNCTION(void, GX2CopyColorBufferToScanBuffer, GX2ColorBuffer* cbuf, int32_
static uint32_t lastData0 = 0; static uint32_t lastData0 = 0;
DECL(uint32_t, OSReceiveMessage, OSMessageQueue *queue, OSMessage *message, uint32_t flags) { 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_ACQUIRED_FOREGROUND);
CallHook(gPluginInformation, WUPS_LOADER_HOOK_APPLICATION_END); CallHook(gPluginInformation, WUPS_LOADER_HOOK_APPLICATION_END);
CallHook(gPluginInformation, WUPS_LOADER_HOOK_FINI_WUT_DEVOPTAB); CallHook(gPluginInformation, WUPS_LOADER_HOOK_FINI_WUT_DEVOPTAB);
@ -256,13 +257,13 @@ DECL(uint32_t, OSReceiveMessage, OSMessageQueue *queue, OSMessage *message, uint
//DCFlushRange(&gInBackground,4); //DCFlushRange(&gInBackground,4);
return false; return false;
} }
int32_t res = real_OSReceiveMessage(queue, message, flags); int32_t res = real_OSReceiveMessage(queue, message, flags);
if(queue == OSGetSystemMessageQueue()) { if (queue == OSGetSystemMessageQueue()) {
if(message != NULL) { if (message != NULL) {
if(lastData0 != message->args[0]) { if (lastData0 != message->args[0]) {
if(message->args[0] == 0xFACEF000) { if (message->args[0] == 0xFACEF000) {
CallHook(gPluginInformation, WUPS_LOADER_HOOK_ACQUIRED_FOREGROUND); 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_APPLICATION_END);
//CallHook(gPluginInformation, WUPS_LOADER_HOOK_FINI_WUT_DEVOPTAB); //CallHook(gPluginInformation, WUPS_LOADER_HOOK_FINI_WUT_DEVOPTAB);
//gInBackground = false; //gInBackground = false;
@ -277,25 +278,25 @@ DECL(uint32_t, OSReceiveMessage, OSMessageQueue *queue, OSMessage *message, uint
} }
DECL(void, OSReleaseForeground) { DECL(void, OSReleaseForeground) {
if(OSGetCoreId() == 1) { if (OSGetCoreId() == 1) {
CallHook(gPluginInformation, WUPS_LOADER_HOOK_RELEASE_FOREGROUND); CallHook(gPluginInformation, WUPS_LOADER_HOOK_RELEASE_FOREGROUND);
} }
real_OSReleaseForeground(); real_OSReleaseForeground();
} }
hooks_magic_t method_hooks_hooks_static[] __attribute__((section(".data"))) = { hooks_magic_t method_hooks_hooks_static[] __attribute__((section(".data"))) = {
//MAKE_MAGIC(GX2SetTVBuffer, LIB_GX2, STATIC_FUNCTION), //MAKE_MAGIC(GX2SetTVBuffer, LIB_GX2, STATIC_FUNCTION),
//MAKE_MAGIC(GX2SetDRCBuffer, LIB_GX2, STATIC_FUNCTION), //MAKE_MAGIC(GX2SetDRCBuffer, LIB_GX2, STATIC_FUNCTION),
//MAKE_MAGIC(GX2WaitForVsync, LIB_GX2, STATIC_FUNCTION), //MAKE_MAGIC(GX2WaitForVsync, LIB_GX2, STATIC_FUNCTION),
//MAKE_MAGIC(GX2CopyColorBufferToScanBuffer, LIB_GX2, STATIC_FUNCTION), //MAKE_MAGIC(GX2CopyColorBufferToScanBuffer, LIB_GX2, STATIC_FUNCTION),
//MAKE_MAGIC(GX2SetContextState, LIB_GX2, STATIC_FUNCTION), //MAKE_MAGIC(GX2SetContextState, LIB_GX2, STATIC_FUNCTION),
MAKE_MAGIC(VPADRead, LIB_VPAD, STATIC_FUNCTION), MAKE_MAGIC(VPADRead, LIB_VPAD, STATIC_FUNCTION),
//MAKE_MAGIC(OSIsAddressValid, LIB_CORE_INIT, STATIC_FUNCTION), //MAKE_MAGIC(OSIsAddressValid, LIB_CORE_INIT, STATIC_FUNCTION),
//MAKE_MAGIC(__OSPhysicalToEffectiveUncached, LIB_CORE_INIT, STATIC_FUNCTION), //MAKE_MAGIC(__OSPhysicalToEffectiveUncached, LIB_CORE_INIT, STATIC_FUNCTION),
//MAKE_MAGIC(__OSPhysicalToEffectiveCached, LIB_CORE_INIT, STATIC_FUNCTION), //MAKE_MAGIC(__OSPhysicalToEffectiveCached, LIB_CORE_INIT, STATIC_FUNCTION),
//MAKE_MAGIC(OSEffectiveToPhysical, LIB_CORE_INIT, STATIC_FUNCTION), //MAKE_MAGIC(OSEffectiveToPhysical, LIB_CORE_INIT, STATIC_FUNCTION),
MAKE_MAGIC(OSReceiveMessage, LIB_CORE_INIT, STATIC_FUNCTION), MAKE_MAGIC(OSReceiveMessage, LIB_CORE_INIT, STATIC_FUNCTION),
MAKE_MAGIC(OSReleaseForeground, 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); 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 "utils/logger.h"
#include "common/plugin_defines.h" #include "common/plugin_defines.h"
dyn_linking_function_t * DynamicLinkingHelper::getOrAddFunctionEntryByName(dyn_linking_relocation_data_t * data, const char* functionName) { dyn_linking_function_t *DynamicLinkingHelper::getOrAddFunctionEntryByName(dyn_linking_relocation_data_t *data, const char *functionName) {
if(data == NULL) { if (data == NULL) {
return NULL; return NULL;
} }
if(functionName == NULL) { if (functionName == NULL) {
return NULL; return NULL;
} }
dyn_linking_function_t * result = NULL; dyn_linking_function_t *result = NULL;
for(int32_t i = 0; i < DYN_LINK_FUNCTION_LIST_LENGTH; i++) { for (int32_t i = 0; i < DYN_LINK_FUNCTION_LIST_LENGTH; i++) {
dyn_linking_function_t * curEntry = &(data->functions[i]); dyn_linking_function_t *curEntry = &(data->functions[i]);
if(strlen(curEntry->functionName) == 0) { if (strlen(curEntry->functionName) == 0) {
if(strlen(functionName) > DYN_LINK_FUNCTION_NAME_LENGTH) { if (strlen(functionName) > DYN_LINK_FUNCTION_NAME_LENGTH) {
DEBUG_FUNCTION_LINE("Failed to add function name, it's too long.\n"); DEBUG_FUNCTION_LINE("Failed to add function name, it's too long.\n");
return NULL; return NULL;
} }
strncpy(curEntry->functionName,functionName,DYN_LINK_FUNCTION_NAME_LENGTH); strncpy(curEntry->functionName, functionName, DYN_LINK_FUNCTION_NAME_LENGTH);
result = curEntry; result = curEntry;
break; 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; result = curEntry;
break; break;
} }
@ -33,68 +33,71 @@ dyn_linking_function_t * DynamicLinkingHelper::getOrAddFunctionEntryByName(dyn_l
return result; 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); 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); return getOrAddImport(data, importName, true);
} }
dyn_linking_import_t * DynamicLinkingHelper::getOrAddImport(dyn_linking_relocation_data_t * data, const char* importName, bool isData) { dyn_linking_import_t *DynamicLinkingHelper::getOrAddImport(dyn_linking_relocation_data_t *data, const char *importName, bool isData) {
if(importName == NULL || data == NULL) { if (importName == NULL || data == NULL) {
return NULL; return NULL;
} }
dyn_linking_import_t * result = NULL; dyn_linking_import_t *result = NULL;
for(int32_t i = 0; i < DYN_LINK_IMPORT_LIST_LENGTH; i++) { for (int32_t i = 0; i < DYN_LINK_IMPORT_LIST_LENGTH; i++) {
dyn_linking_import_t * curEntry = &(data->imports[i]); dyn_linking_import_t *curEntry = &(data->imports[i]);
if(strlen(curEntry->importName) == 0) { if (strlen(curEntry->importName) == 0) {
if(strlen(importName) > DYN_LINK_IMPORT_NAME_LENGTH) { if (strlen(importName) > DYN_LINK_IMPORT_NAME_LENGTH) {
DEBUG_FUNCTION_LINE("Failed to add Import, it's too long.\n"); DEBUG_FUNCTION_LINE("Failed to add Import, it's too long.\n");
return NULL; return NULL;
} }
strncpy(curEntry->importName,importName,DYN_LINK_IMPORT_NAME_LENGTH); strncpy(curEntry->importName, importName, DYN_LINK_IMPORT_NAME_LENGTH);
curEntry->isData = isData; curEntry->isData = isData;
result = curEntry; result = curEntry;
break; 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 curEntry;
} }
} }
return result; 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) { 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()); 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) { 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,
dyn_linking_import_t * importInfoGbl = DynamicLinkingHelper::getOrAddImport(linking_data, rplInfo.getName().c_str(),rplInfo.isData()); const std::string &name, const ImportRPLInformation &rplInfo) {
if(importInfoGbl == NULL) { dyn_linking_import_t *importInfoGbl = DynamicLinkingHelper::getOrAddImport(linking_data, rplInfo.getName().c_str(), rplInfo.isData());
DEBUG_FUNCTION_LINE("Getting import info failed. Probably maximum of %d rpl files to import reached.\n",DYN_LINK_IMPORT_LIST_LENGTH); 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; return false;
} }
dyn_linking_function_t * functionInfo = DynamicLinkingHelper::getOrAddFunctionEntryByName(linking_data, name.c_str()); dyn_linking_function_t *functionInfo = DynamicLinkingHelper::getOrAddFunctionEntryByName(linking_data, name.c_str());
if(functionInfo == NULL) { 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); 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 false;
} }
return addReloationEntry(linking_entries, linking_entry_length, type, offset, addend, destination, functionInfo, importInfoGbl); 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) { 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,
for(uint32_t i = 0; i < linking_entry_length; i++) { dyn_linking_import_t *importInfo) {
dyn_linking_relocation_entry_t * curEntry = &(linking_entries[i]); for (uint32_t i = 0; i < linking_entry_length; i++) {
if(curEntry->functionEntry != NULL) { dyn_linking_relocation_entry_t *curEntry = &(linking_entries[i]);
if (curEntry->functionEntry != NULL) {
continue; continue;
} }
curEntry->type = type; curEntry->type = type;
curEntry->offset = offset; curEntry->offset = offset;
curEntry->addend = addend; curEntry->addend = addend;
curEntry->destination = (void*) destination; curEntry->destination = (void *) destination;
curEntry->functionEntry = functionName; curEntry->functionEntry = functionName;
curEntry->importEntry = importInfo; curEntry->importEntry = importInfo;
return true; return true;

View File

@ -1,4 +1,5 @@
#pragma once #pragma once
#include "common/dynamic_linking_defines.h" #include "common/dynamic_linking_defines.h"
#include "utils/logger.h" #include "utils/logger.h"
#include <string> #include <string>
@ -13,7 +14,7 @@ public:
\param functionName Name of the function \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. \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. 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 \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. \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 \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. \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. \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: private:
DynamicLinkingHelper() { DynamicLinkingHelper() {
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -29,7 +29,10 @@
class PluginInformationFactory { class PluginInformationFactory {
public: 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 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 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() { PluginMetaInformation() {
} }
void setName(const std::string& name) { void setName(const std::string &name) {
this->name = name; this->name = name;
} }
void setAuthor(const std::string& author) { void setAuthor(const std::string &author) {
this->author = author; this->author = author;
} }
void setVersion(const std::string& version) { void setVersion(const std::string &version) {
this->version = version; this->version = version;
} }
void setLicense(const std::string& license) { void setLicense(const std::string &license) {
this->license = license; this->license = license;
} }
void setBuildTimestamp(const std::string& buildtimestamp) { void setBuildTimestamp(const std::string &buildtimestamp) {
this->buildtimestamp = buildtimestamp; this->buildtimestamp = buildtimestamp;
} }
void setDescription(const std::string& description) { void setDescription(const std::string &description) {
this->description = description; this->description = description;
} }
@ -91,6 +91,8 @@ private:
size_t size; size_t size;
friend class PluginMetaInformationFactory; friend class PluginMetaInformationFactory;
friend class PluginContainerPersistence; friend class PluginContainerPersistence;
friend class PluginContainer; friend class PluginContainer;
}; };

View File

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

View File

@ -25,5 +25,5 @@
class PluginMetaInformationFactory { class PluginMetaInformationFactory {
public: 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 { class RelocationData {
public: public:
RelocationData(const char type, size_t offset, int32_t addend, void *destination, std::string name, ImportRPLInformation rplInfo): RelocationData(const char type, size_t offset, int32_t addend, void *destination, std::string name, ImportRPLInformation rplInfo) :
type(type), type(type),
offset(offset), offset(offset),
addend(addend), addend(addend),
destination(destination), destination(destination),
name(name), name(name),
rplInfo(rplInfo) { rplInfo(rplInfo) {
} }
RelocationData(const RelocationData &o2): RelocationData(const RelocationData &o2) :
type(o2.type), type(o2.type),
offset(o2.offset), offset(o2.offset),
addend(o2.addend), addend(o2.addend),
destination(o2.destination), destination(o2.destination),
name(o2.name), name(o2.name),
rplInfo(o2.rplInfo) { rplInfo(o2.rplInfo) {
} }
virtual ~RelocationData() { virtual ~RelocationData() {
} }
const char getType() const{ const char getType() const {
return type; return type;
} }
const size_t getOffset() const{ const size_t getOffset() const {
return offset; return offset;
} }
const int32_t getAddend() const{ const int32_t getAddend() const {
return addend; return addend;
} }
const void * getDestination() const{ const void *getDestination() const {
return destination; return destination;
} }
const std::string& getName() const{ const std::string &getName() const {
return name; return name;
} }
const ImportRPLInformation& getImportRPLInformation() const{ const ImportRPLInformation &getImportRPLInformation() const {
return rplInfo; return rplInfo;
} }

View File

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

View File

@ -8,152 +8,152 @@
#include "ElfUtils.h" #include "ElfUtils.h"
// See https://github.com/decaf-emu/decaf-emu/blob/43366a34e7b55ab9d19b2444aeb0ccd46ac77dea/src/libdecaf/src/cafe/loader/cafe_loader_reloc.cpp#L144 // 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) { 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) { if (type == R_PPC_NONE) {
return true; return true;
} }
auto target = destination + offset; auto target = destination + offset;
auto value = symbol_addr + addend; auto value = symbol_addr + addend;
auto relValue = value - static_cast<uint32_t>(target); auto relValue = value - static_cast<uint32_t>(target);
switch (type) { switch (type) {
case R_PPC_NONE: case R_PPC_NONE:
break; break;
case R_PPC_ADDR32: case R_PPC_ADDR32:
*((uint32_t *)(target)) = value; *((uint32_t *) (target)) = value;
break; break;
case R_PPC_ADDR16_LO: case R_PPC_ADDR16_LO:
*((uint16_t *)(target)) = static_cast<uint16_t>(value & 0xFFFF); *((uint16_t *) (target)) = static_cast<uint16_t>(value & 0xFFFF);
break; break;
case R_PPC_ADDR16_HI: case R_PPC_ADDR16_HI:
*((uint16_t *)(target)) = static_cast<uint16_t>(value >> 16); *((uint16_t *) (target)) = static_cast<uint16_t>(value >> 16);
break; break;
case R_PPC_ADDR16_HA: case R_PPC_ADDR16_HA:
*((uint16_t *)(target)) = static_cast<uint16_t>((value + 0x8000) >> 16); *((uint16_t *) (target)) = static_cast<uint16_t>((value + 0x8000) >> 16);
break; break;
case R_PPC_DTPMOD32: case R_PPC_DTPMOD32:
DEBUG_FUNCTION_LINE("################IMPLEMENT ME\n"); DEBUG_FUNCTION_LINE("################IMPLEMENT ME\n");
//*((int32_t *)(target)) = tlsModuleIndex; //*((int32_t *)(target)) = tlsModuleIndex;
break; break;
case R_PPC_DTPREL32: case R_PPC_DTPREL32:
*((uint32_t *)(target)) = value; *((uint32_t *) (target)) = value;
break; break;
case R_PPC_GHS_REL16_HA: case R_PPC_GHS_REL16_HA:
*((uint16_t *)(target)) = static_cast<uint16_t>((relValue + 0x8000) >> 16); *((uint16_t *) (target)) = static_cast<uint16_t>((relValue + 0x8000) >> 16);
break; break;
case R_PPC_GHS_REL16_HI: case R_PPC_GHS_REL16_HI:
*((uint16_t *)(target)) = static_cast<uint16_t>(relValue >> 16); *((uint16_t *) (target)) = static_cast<uint16_t>(relValue >> 16);
break; break;
case R_PPC_GHS_REL16_LO: case R_PPC_GHS_REL16_LO:
*((uint16_t *)(target)) = static_cast<uint16_t>(relValue & 0xFFFF); *((uint16_t *) (target)) = static_cast<uint16_t>(relValue & 0xFFFF);
break; break;
case R_PPC_REL14: { case R_PPC_REL14: {
auto distance = static_cast<int32_t>(value) - static_cast<int32_t>(target); auto distance = static_cast<int32_t>(value) - static_cast<int32_t>(target);
if (distance > 0x7FFC || distance < -0x7FFC) { if (distance > 0x7FFC || distance < -0x7FFC) {
DEBUG_FUNCTION_LINE("***14-bit relative branch cannot hit target."); 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);
return false; 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) { if (distance & 3) {
DEBUG_FUNCTION_LINE("***RELOC ERROR %d: lower 2 bits must be zero before shifting.", -470022); 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; 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; return true;
} }

View File

@ -7,9 +7,9 @@
extern "C" { extern "C" {
#endif #endif
int32_t LoadFileToMem(const char *relativefilepath, char **fileOut, uint32_t * sizeOut); 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_from_sd(unsigned char *baseAddress, const char *relativePath);
uint32_t load_loader_elf(unsigned char* baseAddress, char * elf_data, uint32_t fileSize); uint32_t load_loader_elf(unsigned char *baseAddress, char *elf_data, uint32_t fileSize);
#define R_PPC_NONE 0 #define R_PPC_NONE 0
#define R_PPC_ADDR32 1 #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 { class ElfUtils {
public: 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> #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()) if (b.size() > a.size())
return false; return false;
return std::equal(a.begin() + a.size() - b.size(), a.end(), b.begin()); 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]; static char b[9];
b[0] = '\0'; b[0] = '\0';
@ -54,25 +54,25 @@ const char * StringTools::byte_to_binary(int32_t x) {
return b; return b;
} }
std::string StringTools::removeCharFromString(std::string& input,char toBeRemoved) { std::string StringTools::removeCharFromString(std::string &input, char toBeRemoved) {
std::string output = input; std::string output = input;
size_t position; size_t position;
while(1) { while (1) {
position = output.find(toBeRemoved); position = output.find(toBeRemoved);
if(position == std::string::npos) if (position == std::string::npos)
break; break;
output.erase(position, 1); output.erase(position, 1);
} }
return output; return output;
} }
const char * StringTools::fmt(const char * format, ...) { const char *StringTools::fmt(const char *format, ...) {
static char strChar[512]; static char strChar[512];
strChar[0] = 0; strChar[0] = 0;
va_list va; va_list va;
va_start(va, format); va_start(va, format);
if((vsprintf(strChar, format, va) >= 0)) { if ((vsprintf(strChar, format, va) >= 0)) {
va_end(va); va_end(va);
return (const char *) strChar; return (const char *) strChar;
} }
@ -81,26 +81,26 @@ const char * StringTools::fmt(const char * format, ...) {
return NULL; return NULL;
} }
const wchar_t * StringTools::wfmt(const char * format, ...) { const wchar_t *StringTools::wfmt(const char *format, ...) {
static char tmp[512]; static char tmp[512];
static wchar_t strWChar[512]; static wchar_t strWChar[512];
strWChar[0] = 0; strWChar[0] = 0;
tmp[0] = 0; tmp[0] = 0;
if(!format) if (!format)
return (const wchar_t *) strWChar; return (const wchar_t *) strWChar;
if(strcmp(format, "") == 0) if (strcmp(format, "") == 0)
return (const wchar_t *) strWChar; return (const wchar_t *) strWChar;
va_list va; va_list va;
va_start(va, format); va_start(va, format);
if((vsprintf(tmp, format, va) >= 0)) { if ((vsprintf(tmp, format, va) >= 0)) {
int bt; int bt;
int32_t strlength = strlen(tmp); 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; strWChar[bt] = 0;
return (const wchar_t *) strWChar; return (const wchar_t *) strWChar;
} }
@ -110,14 +110,14 @@ const wchar_t * StringTools::wfmt(const char * format, ...) {
return NULL; 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]; static char tmp[512];
tmp[0] = 0; tmp[0] = 0;
int32_t result = 0; int32_t result = 0;
va_list va; va_list va;
va_start(va, format); va_start(va, format);
if((vsprintf(tmp, format, va) >= 0)) { if ((vsprintf(tmp, format, va) >= 0)) {
str = tmp; str = tmp;
result = str.size(); result = str.size();
} }
@ -126,14 +126,14 @@ int32_t StringTools::strprintf(std::string &str, const char * format, ...) {
return result; return result;
} }
std::string StringTools::strfmt(const char * format, ...) { std::string StringTools::strfmt(const char *format, ...) {
std::string str; std::string str;
static char tmp[512]; static char tmp[512];
tmp[0] = 0; tmp[0] = 0;
va_list va; va_list va;
va_start(va, format); va_start(va, format);
if((vsprintf(tmp, format, va) >= 0)) { if ((vsprintf(tmp, format, va) >= 0)) {
str = tmp; str = tmp;
} }
va_end(va); va_end(va);
@ -141,11 +141,11 @@ std::string StringTools::strfmt(const char * format, ...) {
return str; return str;
} }
BOOL StringTools::char2wchar_t(const char * strChar, wchar_t * dest) { BOOL StringTools::char2wchar_t(const char *strChar, wchar_t *dest) {
if(!strChar || !dest) if (!strChar || !dest)
return false; return false;
int bt; int bt;
bt = mbstowcs(dest, strChar, strlen(strChar)); bt = mbstowcs(dest, strChar, strlen(strChar));
if (bt > 0) { if (bt > 0) {
dest[bt] = 0; dest[bt] = 0;
@ -155,39 +155,39 @@ BOOL StringTools::char2wchar_t(const char * strChar, wchar_t * dest) {
return false; return false;
} }
int32_t StringTools::strtokcmp(const char * string, const char * compare, const char * separator) { int32_t StringTools::strtokcmp(const char *string, const char *compare, const char *separator) {
if(!string || !compare) if (!string || !compare)
return -1; return -1;
char TokCopy[512]; char TokCopy[512];
strncpy(TokCopy, compare, sizeof(TokCopy)); strncpy(TokCopy, compare, sizeof(TokCopy));
TokCopy[511] = '\0'; TokCopy[511] = '\0';
char * strTok = strtok(TokCopy, separator); char *strTok = strtok(TokCopy, separator);
while (strTok != NULL) { while (strTok != NULL) {
if (strcasecmp(string, strTok) == 0) { if (strcasecmp(string, strTok) == 0) {
return 0; return 0;
} }
strTok = strtok(NULL,separator); strTok = strtok(NULL, separator);
} }
return -1; return -1;
} }
int32_t StringTools::strextcmp(const char * string, const char * extension, char seperator) { int32_t StringTools::strextcmp(const char *string, const char *extension, char seperator) {
if(!string || !extension) if (!string || !extension)
return -1; return -1;
char *ptr = strrchr(string, seperator); char *ptr = strrchr(string, seperator);
if(!ptr) if (!ptr)
return -1; return -1;
return strcasecmp(ptr + 1, extension); 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::string value = inValue;
std::vector<std::string> result; std::vector<std::string> result;
while (true) { while (true) {
@ -202,7 +202,7 @@ std::vector<std::string> StringTools::stringSplit(const std::string & inValue, c
result.push_back(""); result.push_back("");
break; break;
} }
if(index + splitter.size() > value.length()) { if (index + splitter.size() > value.length()) {
break; break;
} }
value = value.substr(index + splitter.size(), value.length()); value = value.substr(index + splitter.size(), value.length());

View File

@ -32,27 +32,36 @@
class StringTools { class StringTools {
public: public:
static BOOL EndsWith(const std::string& a, const std::string& b); 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 const char * FullpathToFilename(const char *path) { static const char *byte_to_binary(int32_t x);
if(!path)
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; return path;
const char * ptr = path; const char *ptr = path;
const char * Filename = ptr; const char *Filename = ptr;
while(*ptr != '\0') { while (*ptr != '\0') {
if(ptr[0] == '/' && ptr[1] != '\0') if (ptr[0] == '/' && ptr[1] != '\0')
Filename = ptr+1; Filename = ptr + 1;
++ptr; ++ptr;
} }
@ -64,8 +73,8 @@ public:
uint32_t length = str.size(); uint32_t length = str.size();
//! clear path of double slashes //! clear path of double slashes
for(uint32_t i = 1; i < length; ++i) { for (uint32_t i = 1; i < length; ++i) {
if(str[i-1] == '/' && str[i] == '/') { if (str[i - 1] == '/' && str[i] == '/') {
str.erase(i, 1); str.erase(i, 1);
i--; i--;
length--; 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 */ #endif /* __STRING_TOOLS_H */

View File

@ -70,15 +70,15 @@ typedef struct {
uint8_t alreadyPatched; uint8_t alreadyPatched;
} hooks_magic_t; } hooks_magic_t;
void PatchInvidualMethodHooks(hooks_magic_t hook_information[],int32_t hook_information_size, volatile uint32_t dynamic_method_calls[]); 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); void RestoreInvidualInstructions(hooks_magic_t hook_information[], int32_t hook_information_size);
uint32_t GetAddressOfFunction(const char * functionName,uint32_t library); uint32_t GetAddressOfFunction(const char *functionName, uint32_t library);
int32_t isDynamicFunction(uint32_t physicalAddress); int32_t isDynamicFunction(uint32_t physicalAddress);
void resetLibs(); void resetLibs();
//Orignal code by Chadderz. //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(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_NAME(x, y, lib, functionType) { (uint32_t) my_ ## x, (uint32_t) &real_ ## x, lib, # y,0,0,functionType,0}
#ifdef __cplusplus #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. * 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. * "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(); 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. */ /* Patch branches to it. */
volatile uint32_t *space = &dynamic_method_calls[0]; 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 skip_instr = 1;
uint32_t my_instr_len = 6; uint32_t my_instr_len = 6;
uint32_t instr_len = my_instr_len + skip_instr; uint32_t instr_len = my_instr_len + skip_instr;
uint32_t flush_len = 4*instr_len; uint32_t flush_len = 4 * instr_len;
for(int32_t i = 0; i < method_hooks_count; i++) { for (int32_t i = 0; i < method_hooks_count; i++) {
log_printf("Patching %s ...",method_hooks[i].functionName); log_printf("Patching %s ...", method_hooks[i].functionName);
if(method_hooks[i].functionType == STATIC_FUNCTION && method_hooks[i].alreadyPatched == 1) { if (method_hooks[i].functionType == STATIC_FUNCTION && method_hooks[i].alreadyPatched == 1) {
if(isDynamicFunction((uint32_t)OSEffectiveToPhysical(method_hooks[i].realAddr))) { 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); log_printf("The function %s is a dynamic function. Please fix that <3", method_hooks[i].functionName);
method_hooks[i].functionType = DYNAMIC_FUNCTION; method_hooks[i].functionType = DYNAMIC_FUNCTION;
} else { } else {
@ -84,38 +84,38 @@ void PatchInvidualMethodHooks(hooks_magic_t method_hooks[],int32_t hook_informat
} }
uint32_t physical = 0; uint32_t physical = 0;
uint32_t repl_addr = (uint32_t)method_hooks[i].replaceAddr; uint32_t repl_addr = (uint32_t) method_hooks[i].replaceAddr;
uint32_t call_addr = (uint32_t)method_hooks[i].replaceCall; 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(""); log_printf("");
DEBUG_FUNCTION_LINE("OSDynLoad_FindExport failed for %s", method_hooks[i].functionName); DEBUG_FUNCTION_LINE("OSDynLoad_FindExport failed for %s", method_hooks[i].functionName);
space += instr_len; space += instr_len;
continue; continue;
} }
if(DEBUG_LOG_DYN) { if (DEBUG_LOG_DYN) {
DEBUG_FUNCTION_LINE("%s is located at %08X!", method_hooks[i].functionName,real_addr); DEBUG_FUNCTION_LINE("%s is located at %08X!", method_hooks[i].functionName, real_addr);
} }
physical = (uint32_t)OSEffectiveToPhysical(real_addr); physical = (uint32_t) OSEffectiveToPhysical(real_addr);
if(!physical) { if (!physical) {
log_printf("Error. Something is wrong with the physical address"); log_printf("Error. Something is wrong with the physical address");
space += instr_len; space += instr_len;
continue; continue;
} }
if(DEBUG_LOG_DYN) { if (DEBUG_LOG_DYN) {
DEBUG_FUNCTION_LINE("%s physical is located at %08X!", method_hooks[i].functionName,physical); 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; uint32_t targetAddr = (uint32_t) space;
if(targetAddr < 0x00800000 || targetAddr >= 0x01000000) { if (targetAddr < 0x00800000 || targetAddr >= 0x01000000) {
targetAddr = (uint32_t) OSEffectiveToPhysical(targetAddr); targetAddr = (uint32_t) OSEffectiveToPhysical(targetAddr);
} else { } else {
targetAddr = targetAddr + 0x30800000 - 0x00800000; targetAddr = targetAddr + 0x30800000 - 0x00800000;
@ -123,20 +123,20 @@ void PatchInvidualMethodHooks(hooks_magic_t method_hooks[],int32_t hook_informat
KernelCopyData(targetAddr, physical, 4); KernelCopyData(targetAddr, physical, 4);
ICInvalidateRange((void*)(space), 4); ICInvalidateRange((void *) (space), 4);
DCFlushRange((void*)(space), 4); DCFlushRange((void *) (space), 4);
space++; space++;
//Only works if skip_instr == 1 //Only works if skip_instr == 1
if(skip_instr == 1) { if (skip_instr == 1) {
// fill the restore instruction section // fill the restore instruction section
method_hooks[i].realAddr = real_addr; method_hooks[i].realAddr = real_addr;
method_hooks[i].restoreInstruction = *(space-1); method_hooks[i].restoreInstruction = *(space - 1);
if(DEBUG_LOG_DYN) { if (DEBUG_LOG_DYN) {
DEBUG_FUNCTION_LINE("method_hooks[i].realAddr = %08X!", method_hooks[i].realAddr); DEBUG_FUNCTION_LINE("method_hooks[i].realAddr = %08X!", method_hooks[i].realAddr);
} }
if(DEBUG_LOG_DYN) { if (DEBUG_LOG_DYN) {
DEBUG_FUNCTION_LINE("method_hooks[i].restoreInstruction = %08X!",method_hooks[i].restoreInstruction) ; DEBUG_FUNCTION_LINE("method_hooks[i].restoreInstruction = %08X!", method_hooks[i].restoreInstruction);
} }
} else { } else {
log_printf("Error. Can't save %s for restoring!", method_hooks[i].functionName); 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++;
*space = 0x3C600000 | (((real_addr + (skip_instr * 4)) >> 16) & 0x0000FFFF); // lis r3, real_addr@h *space = 0x3C600000 | (((real_addr + (skip_instr * 4)) >> 16) & 0x0000FFFF); // lis r3, real_addr@h
space++; 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++;
*space = 0x7C6903A6; // mtctr r3 *space = 0x7C6903A6; // mtctr r3
space++; space++;
@ -162,15 +162,15 @@ void PatchInvidualMethodHooks(hooks_magic_t method_hooks[],int32_t hook_informat
space++; space++;
*space = 0x4E800420; // bctr *space = 0x4E800420; // bctr
space++; space++;
DCFlushRange((void*)(space - instr_len), flush_len); DCFlushRange((void *) (space - instr_len), flush_len);
ICInvalidateRange((unsigned char*)(space - instr_len), flush_len); ICInvalidateRange((unsigned char *) (space - instr_len), flush_len);
//setting jump back //setting jump back
uint32_t replace_instr = 0x48000002 | (repl_addr & 0x03fffffc); uint32_t replace_instr = 0x48000002 | (repl_addr & 0x03fffffc);
DCFlushRange(&replace_instr, 4); DCFlushRange(&replace_instr, 4);
KernelCopyData(physical, (uint32_t)OSEffectiveToPhysical((uint32_t)&replace_instr), 4); KernelCopyData(physical, (uint32_t) OSEffectiveToPhysical((uint32_t) &replace_instr), 4);
ICInvalidateRange((void*)(real_addr), 4); ICInvalidateRange((void *) (real_addr), 4);
method_hooks[i].alreadyPatched = 1; method_hooks[i].alreadyPatched = 1;
log_printf("done!\n"); log_printf("done!\n");
@ -182,49 +182,49 @@ void PatchInvidualMethodHooks(hooks_magic_t method_hooks[],int32_t hook_informat
/* ****************************************************************** */ /* ****************************************************************** */
/* RESTORE ORIGINAL INSTRUCTIONS */ /* 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(); resetLibs();
DEBUG_FUNCTION_LINE("Restoring given functions!"); DEBUG_FUNCTION_LINE("Restoring given functions!");
int32_t method_hooks_count = hook_information_size; int32_t method_hooks_count = hook_information_size;
for(int32_t i = 0; i < method_hooks_count; i++) { for (int32_t i = 0; i < method_hooks_count; i++) {
DEBUG_FUNCTION_LINE("Restoring %s... ",method_hooks[i].functionName); DEBUG_FUNCTION_LINE("Restoring %s... ", method_hooks[i].functionName);
if(method_hooks[i].restoreInstruction == 0 || method_hooks[i].realAddr == 0) { if (method_hooks[i].restoreInstruction == 0 || method_hooks[i].realAddr == 0) {
log_printf("I dont have the information for the restore =( skip"); log_printf("I dont have the information for the restore =( skip");
continue; 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); log_printf("OSDynLoad_FindExport failed for %s", method_hooks[i].functionName);
continue; continue;
} }
uint32_t physical = (uint32_t)OSEffectiveToPhysical(real_addr); uint32_t physical = (uint32_t) OSEffectiveToPhysical(real_addr);
if(!physical) { if (!physical) {
log_printf("Something is wrong with the physical address"); log_printf("Something is wrong with the physical address");
continue; continue;
} }
if(isDynamicFunction(physical)) { if (isDynamicFunction(physical)) {
log_printf("Its a dynamic function. We don't need to restore it!",method_hooks[i].functionName); log_printf("Its a dynamic function. We don't need to restore it!", method_hooks[i].functionName);
} else { } else {
physical = (uint32_t)OSEffectiveToPhysical(method_hooks[i].realAddr); //When its an static function, we need to use the old location physical = (uint32_t) OSEffectiveToPhysical(method_hooks[i].realAddr); //When its an static function, we need to use the old location
if(DEBUG_LOG_DYN) { if (DEBUG_LOG_DYN) {
DEBUG_FUNCTION_LINE("Restoring %08X to %08X",(uint32_t)method_hooks[i].restoreInstruction,physical); DEBUG_FUNCTION_LINE("Restoring %08X to %08X", (uint32_t) method_hooks[i].restoreInstruction, physical);
} }
uint32_t targetAddr = (uint32_t)&method_hooks[i].restoreInstruction; uint32_t targetAddr = (uint32_t) &method_hooks[i].restoreInstruction;
if(targetAddr < 0x00800000 || targetAddr >= 0x01000000) { if (targetAddr < 0x00800000 || targetAddr >= 0x01000000) {
targetAddr = (uint32_t) OSEffectiveToPhysical(targetAddr); targetAddr = (uint32_t) OSEffectiveToPhysical(targetAddr);
} else { } else {
targetAddr = targetAddr + 0x30800000 - 0x00800000; targetAddr = targetAddr + 0x30800000 - 0x00800000;
} }
KernelCopyData(physical,targetAddr, 4); KernelCopyData(physical, targetAddr, 4);
if(DEBUG_LOG_DYN) { if (DEBUG_LOG_DYN) {
DEBUG_FUNCTION_LINE("ICInvalidateRange %08X",(void*)method_hooks[i].realAddr); 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"); log_printf("done");
} }
method_hooks[i].alreadyPatched = 0; // In case a 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) { int32_t isDynamicFunction(uint32_t physicalAddress) {
if((physicalAddress & 0x80000000) == 0x80000000) { if ((physicalAddress & 0x80000000) == 0x80000000) {
return 1; return 1;
} }
return 0; 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; uint32_t real_addr = 0;
/* /*
@ -262,282 +262,282 @@ uint32_t GetAddressOfFunction(const char * functionName,uint32_t library) {
*/ */
OSDynLoad_Module rpl_handle = 0; OSDynLoad_Module rpl_handle = 0;
if(library == LIB_CORE_INIT) { if (library == LIB_CORE_INIT) {
if(DEBUG_LOG_DYN) { if (DEBUG_LOG_DYN) {
DEBUG_FUNCTION_LINE("FindExport of %s! From LIB_CORE_INIT", functionName); 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); 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"); DEBUG_FUNCTION_LINE("LIB_CORE_INIT failed to acquire");
return 0; return 0;
} }
rpl_handle = coreinit_handle_internal; rpl_handle = coreinit_handle_internal;
} else if(library == LIB_NSYSNET) { } else if (library == LIB_NSYSNET) {
if(DEBUG_LOG_DYN) { if (DEBUG_LOG_DYN) {
DEBUG_FUNCTION_LINE("FindExport of %s! From LIB_NSYSNET", functionName); 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); 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"); DEBUG_FUNCTION_LINE("LIB_NSYSNET failed to acquire");
return 0; return 0;
} }
rpl_handle = nsysnet_handle_internal; rpl_handle = nsysnet_handle_internal;
} else if(library == LIB_GX2) { } else if (library == LIB_GX2) {
if(DEBUG_LOG_DYN) { if (DEBUG_LOG_DYN) {
DEBUG_FUNCTION_LINE("FindExport of %s! From LIB_GX2", functionName); 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); 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"); DEBUG_FUNCTION_LINE("LIB_GX2 failed to acquire");
return 0; return 0;
} }
rpl_handle = gx2_handle_internal; rpl_handle = gx2_handle_internal;
} else if(library == LIB_AOC) { } else if (library == LIB_AOC) {
if(DEBUG_LOG_DYN) { if (DEBUG_LOG_DYN) {
DEBUG_FUNCTION_LINE("FindExport of %s! From LIB_AOC", functionName); 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); 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"); DEBUG_FUNCTION_LINE("LIB_AOC failed to acquire");
return 0; return 0;
} }
rpl_handle = aoc_handle_internal; rpl_handle = aoc_handle_internal;
} else if(library == LIB_AX) { } else if (library == LIB_AX) {
if(DEBUG_LOG_DYN) { if (DEBUG_LOG_DYN) {
DEBUG_FUNCTION_LINE("FindExport of %s! From LIB_AX", functionName); 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); 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"); DEBUG_FUNCTION_LINE("LIB_AX failed to acquire");
return 0; return 0;
} }
rpl_handle = sound_handle_internal; rpl_handle = sound_handle_internal;
} else if(library == LIB_AX_OLD) { } else if (library == LIB_AX_OLD) {
if(DEBUG_LOG_DYN) { if (DEBUG_LOG_DYN) {
DEBUG_FUNCTION_LINE("FindExport of %s! From LIB_AX_OLD", functionName); 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); 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"); DEBUG_FUNCTION_LINE("LIB_AX_OLD failed to acquire");
return 0; return 0;
} }
rpl_handle = sound_handle_internal_old; rpl_handle = sound_handle_internal_old;
} else if(library == LIB_FS) { } else if (library == LIB_FS) {
if(DEBUG_LOG_DYN) { if (DEBUG_LOG_DYN) {
DEBUG_FUNCTION_LINE("FindExport of %s! From LIB_FS", functionName); 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); 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"); DEBUG_FUNCTION_LINE("LIB_FS failed to acquire");
return 0; return 0;
} }
rpl_handle = coreinit_handle_internal; rpl_handle = coreinit_handle_internal;
} else if(library == LIB_OS) { } else if (library == LIB_OS) {
if(DEBUG_LOG_DYN) { if (DEBUG_LOG_DYN) {
DEBUG_FUNCTION_LINE("FindExport of %s! From LIB_OS", functionName); 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); 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"); DEBUG_FUNCTION_LINE("LIB_OS failed to acquire");
return 0; return 0;
} }
rpl_handle = coreinit_handle_internal; rpl_handle = coreinit_handle_internal;
} else if(library == LIB_PADSCORE) { } else if (library == LIB_PADSCORE) {
if(DEBUG_LOG_DYN) { if (DEBUG_LOG_DYN) {
DEBUG_FUNCTION_LINE("FindExport of %s! From LIB_PADSCORE", functionName); 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); 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"); DEBUG_FUNCTION_LINE("LIB_PADSCORE failed to acquire");
return 0; return 0;
} }
rpl_handle = padscore_handle_internal; rpl_handle = padscore_handle_internal;
} else if(library == LIB_SOCKET) { } else if (library == LIB_SOCKET) {
if(DEBUG_LOG_DYN) { if (DEBUG_LOG_DYN) {
DEBUG_FUNCTION_LINE("FindExport of %s! From LIB_SOCKET", functionName); 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); 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"); DEBUG_FUNCTION_LINE("LIB_SOCKET failed to acquire");
return 0; return 0;
} }
rpl_handle = nsysnet_handle_internal; rpl_handle = nsysnet_handle_internal;
} else if(library == LIB_SYS) { } else if (library == LIB_SYS) {
if(DEBUG_LOG_DYN) { if (DEBUG_LOG_DYN) {
DEBUG_FUNCTION_LINE("FindExport of %s! From LIB_SYS", functionName); 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); 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"); DEBUG_FUNCTION_LINE("LIB_SYS failed to acquire");
return 0; return 0;
} }
rpl_handle = sysapp_handle_internal; rpl_handle = sysapp_handle_internal;
} else if(library == LIB_VPAD) { } else if (library == LIB_VPAD) {
if(DEBUG_LOG_DYN) { if (DEBUG_LOG_DYN) {
DEBUG_FUNCTION_LINE("FindExport of %s! From LIB_VPAD", functionName); 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); 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"); DEBUG_FUNCTION_LINE("LIB_VPAD failed to acquire");
return 0; return 0;
} }
rpl_handle = vpad_handle_internal; rpl_handle = vpad_handle_internal;
} else if(library == LIB_NN_ACP) { } else if (library == LIB_NN_ACP) {
if(DEBUG_LOG_DYN) { if (DEBUG_LOG_DYN) {
DEBUG_FUNCTION_LINE("FindExport of %s! From LIB_NN_ACP", functionName); 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); 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"); DEBUG_FUNCTION_LINE("LIB_NN_ACP failed to acquire");
return 0; return 0;
} }
rpl_handle = acp_handle_internal; rpl_handle = acp_handle_internal;
} else if(library == LIB_SYSHID) { } else if (library == LIB_SYSHID) {
if(DEBUG_LOG_DYN) { if (DEBUG_LOG_DYN) {
DEBUG_FUNCTION_LINE("FindExport of %s! From LIB_SYSHID", functionName); 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); 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"); DEBUG_FUNCTION_LINE("LIB_SYSHID failed to acquire");
return 0; return 0;
} }
rpl_handle = syshid_handle_internal; rpl_handle = syshid_handle_internal;
} else if(library == LIB_VPADBASE) { } else if (library == LIB_VPADBASE) {
if(DEBUG_LOG_DYN) { if (DEBUG_LOG_DYN) {
DEBUG_FUNCTION_LINE("FindExport of %s! From LIB_VPADBASE", functionName); 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); 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"); DEBUG_FUNCTION_LINE("LIB_VPADBASE failed to acquire");
return 0; return 0;
} }
rpl_handle = vpadbase_handle_internal; rpl_handle = vpadbase_handle_internal;
} else if(library == LIB_PROC_UI) { } else if (library == LIB_PROC_UI) {
if(DEBUG_LOG_DYN) { if (DEBUG_LOG_DYN) {
DEBUG_FUNCTION_LINE("FindExport of %s! From LIB_PROC_UI", functionName); 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); 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"); DEBUG_FUNCTION_LINE("LIB_PROC_UI failed to acquire");
return 0; return 0;
} }
rpl_handle = proc_ui_handle_internal; rpl_handle = proc_ui_handle_internal;
} else if(library == LIB_NTAG) { } else if (library == LIB_NTAG) {
if(DEBUG_LOG_DYN) { if (DEBUG_LOG_DYN) {
log_printf("FindExport of %s! From LIB_NTAG", functionName); 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); OSDynLoad_Acquire("ntag.rpl", &ntag_handle_internal);
} }
if(ntag_handle_internal == 0) { if (ntag_handle_internal == 0) {
log_print("LIB_NTAG failed to acquire"); log_print("LIB_NTAG failed to acquire");
return 0; return 0;
} }
rpl_handle = ntag_handle_internal; rpl_handle = ntag_handle_internal;
} else if(library == LIB_NFP) { } else if (library == LIB_NFP) {
if(DEBUG_LOG_DYN) { if (DEBUG_LOG_DYN) {
log_printf("FindExport of %s! From LIB_NFP", functionName); 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); 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"); log_print("LIB_NFP failed to acquire");
return 0; return 0;
} }
rpl_handle = nfp_handle_internal; rpl_handle = nfp_handle_internal;
} else if(library == LIB_SAVE) { } else if (library == LIB_SAVE) {
if(DEBUG_LOG_DYN) { if (DEBUG_LOG_DYN) {
log_printf("FindExport of %s! From LIB_SAVE", functionName); 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); 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"); log_print("LIB_SAVE failed to acquire");
return 0; return 0;
} }
rpl_handle = nn_save_handle_internal; rpl_handle = nn_save_handle_internal;
} else if(library == LIB_ACT) { } else if (library == LIB_ACT) {
if(DEBUG_LOG_DYN) { if (DEBUG_LOG_DYN) {
log_printf("FindExport of %s! From LIB_ACT", functionName); 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); 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"); log_print("LIB_ACT failed to acquire");
return 0; return 0;
} }
rpl_handle = nn_act_handle_internal; rpl_handle = nn_act_handle_internal;
} else if(library == LIB_NIM) { } else if (library == LIB_NIM) {
if(DEBUG_LOG_DYN) { if (DEBUG_LOG_DYN) {
log_printf("FindExport of %s! From LIB_NIM", functionName); 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); 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"); log_print("LIB_NIM failed to acquire");
return 0; return 0;
} }
rpl_handle = nn_nim_handle_internal; rpl_handle = nn_nim_handle_internal;
} }
if(!rpl_handle) { if (!rpl_handle) {
DEBUG_FUNCTION_LINE("Failed to find the RPL handle for %s", functionName); DEBUG_FUNCTION_LINE("Failed to find the RPL handle for %s", functionName);
return 0; return 0;
} }
OSDynLoad_FindExport(rpl_handle, 0, functionName, (void**) &real_addr); OSDynLoad_FindExport(rpl_handle, 0, functionName, (void **) &real_addr);
if(!real_addr) { if (!real_addr) {
OSDynLoad_FindExport(rpl_handle, 1, functionName, (void**) &real_addr); OSDynLoad_FindExport(rpl_handle, 1, functionName, (void **) &real_addr);
if(!real_addr) { if (!real_addr) {
DEBUG_FUNCTION_LINE("OSDynLoad_FindExport failed for %s", functionName); DEBUG_FUNCTION_LINE("OSDynLoad_FindExport failed for %s", functionName);
return 0; return 0;
} }
} }
if((library == LIB_NN_ACP) && (uint32_t)(*(volatile uint32_t*)(real_addr) & 0x48000002) == 0x48000000) { 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); uint32_t address_diff = (uint32_t) (*(volatile uint32_t *) (real_addr) & 0x03FFFFFC);
if((address_diff & 0x03000000) == 0x03000000) { if ((address_diff & 0x03000000) == 0x03000000) {
address_diff |= 0xFC000000; address_diff |= 0xFC000000;
} }
real_addr += (int32_t)address_diff; real_addr += (int32_t) address_diff;
if((uint32_t)(*(volatile uint32_t*)(real_addr) & 0x48000002) == 0x48000000) { if ((uint32_t) (*(volatile uint32_t *) (real_addr) & 0x48000002) == 0x48000000) {
return 0; return 0;
} }
} }

View File

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

View File

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

View File

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

View File

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