mirror of
https://github.com/wiiu-env/WiiUPluginLoaderBackend.git
synced 2024-11-16 01:45:10 +01:00
Even more formatting
This commit is contained in:
parent
4bf4a0eeea
commit
0c0680be77
@ -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);
|
||||||
};
|
};
|
@ -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;
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <wups.h>
|
#include <wups.h>
|
||||||
|
|
||||||
|
@ -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))();
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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?
|
||||||
|
@ -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();
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
|
@ -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() {
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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;
|
||||||
};
|
};
|
||||||
|
@ -35,7 +35,7 @@ public:
|
|||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isData() const{
|
bool isData() const {
|
||||||
return _isData;
|
return _isData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
};
|
};
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
};
|
};
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);
|
||||||
};
|
};
|
||||||
|
@ -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 §ionInfo) {
|
||||||
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 §ionName) 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;
|
||||||
};
|
};
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
};
|
};
|
||||||
|
@ -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;
|
||||||
};
|
};
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
};
|
};
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
};
|
};
|
||||||
|
@ -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());
|
||||||
|
@ -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 */
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
@ -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)
|
||||||
|
@ -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);
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user