mirror of
https://github.com/wiiu-env/WiiUPluginSystem.git
synced 2024-12-25 01:21:57 +01:00
[Loader] Added support for the init hook.
- The loader now returns to the system menu and restores all patches when entering mii maker.
This commit is contained in:
parent
81b5bed341
commit
ec217c6aef
@ -40,8 +40,16 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <dynamic_libs/os_functions.h>
|
#include <dynamic_libs/os_functions.h>
|
||||||
|
|
||||||
|
//TODO: Adjust this.
|
||||||
#define MODULE_ENTRIES_CAPACITY_DEFAULT 128
|
#define MODULE_ENTRIES_CAPACITY_DEFAULT 128
|
||||||
|
|
||||||
|
//TODO: Adjust this.
|
||||||
|
#define MODULE_HOOKS_CAPACITY_DEFAULT 128
|
||||||
|
|
||||||
|
wups_loader_hook_t *module_hooks = NULL;
|
||||||
|
size_t module_hooks_count = 0;
|
||||||
|
size_t module_hooks_capacity = 0;
|
||||||
|
|
||||||
wups_loader_entry_t *module_entries = NULL;
|
wups_loader_entry_t *module_entries = NULL;
|
||||||
size_t module_entries_count = 0;
|
size_t module_entries_count = 0;
|
||||||
size_t module_entries_capacity = 0;
|
size_t module_entries_capacity = 0;
|
||||||
@ -106,10 +114,11 @@ exit_error:
|
|||||||
|
|
||||||
bool Module_LinkModuleElf(size_t index, Elf *elf, uint8_t **space) {
|
bool Module_LinkModuleElf(size_t index, Elf *elf, uint8_t **space) {
|
||||||
Elf_Scn *scn;
|
Elf_Scn *scn;
|
||||||
size_t symtab_count, section_count, shstrndx, symtab_strndx, entries_count;
|
size_t symtab_count, section_count, shstrndx, symtab_strndx, entries_count, hooks_count;
|
||||||
Elf32_Sym *symtab = NULL;
|
Elf32_Sym *symtab = NULL;
|
||||||
uint8_t **destinations = NULL;
|
uint8_t **destinations = NULL;
|
||||||
wups_loader_entry_t *entries = NULL;
|
wups_loader_entry_t *entries = NULL;
|
||||||
|
wups_loader_hook_t *hooks = NULL;
|
||||||
bool result = false;
|
bool result = false;
|
||||||
|
|
||||||
if (!Module_LoadElfSymtab(elf, &symtab, &symtab_count, &symtab_strndx))
|
if (!Module_LoadElfSymtab(elf, &symtab, &symtab_count, &symtab_strndx))
|
||||||
@ -171,6 +180,30 @@ bool Module_LinkModuleElf(size_t index, Elf *elf, uint8_t **space) {
|
|||||||
gbl_replacement_data.module_data[index].functions[i].entry_index = entries_offset +i;
|
gbl_replacement_data.module_data[index].functions[i].entry_index = entries_offset +i;
|
||||||
gbl_replacement_data.module_data[index].number_used_functions++;
|
gbl_replacement_data.module_data[index].number_used_functions++;
|
||||||
}
|
}
|
||||||
|
}else if (strcmp(name, ".wups.hooks") == 0) {
|
||||||
|
if (hooks != NULL)
|
||||||
|
goto exit_error;
|
||||||
|
|
||||||
|
hooks_count = shdr->sh_size / sizeof(wups_loader_hook_t);
|
||||||
|
hooks = (wups_loader_hook_t*) Module_ListAllocate(
|
||||||
|
&module_hooks, sizeof(wups_loader_hook_t),
|
||||||
|
hooks_count, &module_hooks_capacity,
|
||||||
|
&module_hooks_count, MODULE_HOOKS_CAPACITY_DEFAULT);
|
||||||
|
|
||||||
|
if (hooks == NULL)
|
||||||
|
goto exit_error;
|
||||||
|
|
||||||
|
destinations[elf_ndxscn(scn)] = (uint8_t *)hooks;
|
||||||
|
if (!Module_ElfLoadSection(elf, scn, shdr, hooks))
|
||||||
|
goto exit_error;
|
||||||
|
Module_ElfLoadSymbols(elf_ndxscn(scn), hooks, symtab, symtab_count);
|
||||||
|
|
||||||
|
int hook_offset = module_hooks_count - hooks_count;
|
||||||
|
|
||||||
|
for(int i = 0;i< hooks_count;i++){
|
||||||
|
gbl_replacement_data.module_data[index].hooks[i].hook_index = hook_offset +i;
|
||||||
|
gbl_replacement_data.module_data[index].number_used_hooks++;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
*space -= shdr->sh_size;
|
*space -= shdr->sh_size;
|
||||||
|
|
||||||
@ -244,6 +277,20 @@ bool Module_ListLinkFinal() {
|
|||||||
for(int module_index=0;module_index<gbl_replacement_data.number_used_modules;module_index++){
|
for(int module_index=0;module_index<gbl_replacement_data.number_used_modules;module_index++){
|
||||||
replacement_data_module_t * module_data = &gbl_replacement_data.module_data[module_index];
|
replacement_data_module_t * module_data = &gbl_replacement_data.module_data[module_index];
|
||||||
DEBUG_FUNCTION_LINE("Module name: %s\n",module_data->module_name);
|
DEBUG_FUNCTION_LINE("Module name: %s\n",module_data->module_name);
|
||||||
|
for(int j=0;j<module_data->number_used_hooks;j++){
|
||||||
|
replacement_data_hook_t * hook_data = &module_data->hooks[j];
|
||||||
|
if(hook_data->hook_index > module_entries_count-1){
|
||||||
|
DEBUG_FUNCTION_LINE("Error. hook_index was too high: %d. maximum is %d\n",hook_data->hook_index,module_entries_count-1);
|
||||||
|
goto exit_error;
|
||||||
|
}
|
||||||
|
wups_loader_hook_t * hook = &module_hooks[hook_data->hook_index];
|
||||||
|
DEBUG_FUNCTION_LINE("Set hook %d of module \"%s\" of type %08X\n",hook_data->hook_index,module_data->module_name,hook->type);
|
||||||
|
hook_data->func_pointer = (void*) hook->target;
|
||||||
|
hook_data->type = hook->type;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
DEBUG_FUNCTION_LINE("number of used function: %d\n",module_data->number_used_functions);
|
DEBUG_FUNCTION_LINE("number of used function: %d\n",module_data->number_used_functions);
|
||||||
for(int j=0;j<module_data->number_used_functions;j++){
|
for(int j=0;j<module_data->number_used_functions;j++){
|
||||||
replacement_data_function_t * function_data = &module_data->functions[j];
|
replacement_data_function_t * function_data = &module_data->functions[j];
|
||||||
|
@ -7,7 +7,9 @@
|
|||||||
|
|
||||||
#include <dynamic_libs/os_functions.h>
|
#include <dynamic_libs/os_functions.h>
|
||||||
#include <dynamic_libs/socket_functions.h>
|
#include <dynamic_libs/socket_functions.h>
|
||||||
|
#include <dynamic_libs/sys_functions.h>
|
||||||
#include <dynamic_libs/fs_functions.h>
|
#include <dynamic_libs/fs_functions.h>
|
||||||
|
#include <dynamic_libs/vpad_functions.h>
|
||||||
#include <utils/logger.h>
|
#include <utils/logger.h>
|
||||||
#include <fs/FSUtils.h>
|
#include <fs/FSUtils.h>
|
||||||
#include <fs/sd_fat_devoptab.h>
|
#include <fs/sd_fat_devoptab.h>
|
||||||
@ -27,13 +29,23 @@
|
|||||||
#include "patcher/function_patcher.h"
|
#include "patcher/function_patcher.h"
|
||||||
|
|
||||||
static void printModuleInfos();
|
static void printModuleInfos();
|
||||||
|
static void loadSamplePlugin();
|
||||||
static void printInfos();
|
static void printInfos();
|
||||||
static void printReplacementInfos();
|
static void printReplacementInfos();
|
||||||
|
static void ApplyPatches();
|
||||||
|
void CallHook(wups_loader_hook_type_t hook_type);
|
||||||
|
static void RestorePatches();
|
||||||
|
s32 isInMiiMakerHBL();
|
||||||
|
|
||||||
|
|
||||||
|
u8 isFirstBoot __attribute__((section(".data"))) = 1;
|
||||||
|
|
||||||
|
|
||||||
/* Entry point */
|
/* Entry point */
|
||||||
extern "C" int Menu_Main(int argc, char **argv){
|
extern "C" int Menu_Main(int argc, char **argv){
|
||||||
InitOSFunctionPointers();
|
InitOSFunctionPointers();
|
||||||
InitSocketFunctionPointers(); //For logging
|
InitSocketFunctionPointers(); //For logging
|
||||||
|
InitSysFunctionPointers();
|
||||||
InitFSFunctionPointers();
|
InitFSFunctionPointers();
|
||||||
|
|
||||||
log_init();
|
log_init();
|
||||||
@ -42,20 +54,104 @@ extern "C" int Menu_Main(int argc, char **argv){
|
|||||||
|
|
||||||
setup_os_exceptions();
|
setup_os_exceptions();
|
||||||
|
|
||||||
DEBUG_FUNCTION_LINE("End address of loader %08X\n",getApplicationEndAddr());
|
if(isFirstBoot){
|
||||||
|
|
||||||
memset((void*)&gbl_replacement_data,0,sizeof(gbl_replacement_data));
|
memset((void*)&gbl_replacement_data,0,sizeof(gbl_replacement_data));
|
||||||
|
loadSamplePlugin();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
CallHook(WUPS_LOADER_HOOK_INIT_FUNCTION);
|
||||||
|
|
||||||
|
DEBUG_FUNCTION_LINE("Apply patches.\n");
|
||||||
|
ApplyPatches();
|
||||||
|
|
||||||
|
|
||||||
|
//Reset everything when were going back to the Mii Maker
|
||||||
|
if(!isFirstBoot && isInMiiMakerHBL()){
|
||||||
|
DEBUG_FUNCTION_LINE("Returing to the Homebrew Launcher!\n");
|
||||||
|
isFirstBoot = 0;
|
||||||
|
RestorePatches();
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!isInMiiMakerHBL()){ //Starting the application
|
||||||
|
|
||||||
|
return EXIT_RELAUNCH_ON_LOAD;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(isFirstBoot){ // First boot back to SysMenu
|
||||||
|
DEBUG_FUNCTION_LINE("Loading the System Menu\n");
|
||||||
|
isFirstBoot = 0;
|
||||||
|
SYSLaunchMenu();
|
||||||
|
return EXIT_RELAUNCH_ON_LOAD;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUG_FUNCTION_LINE("Application is ending now.\n");
|
||||||
|
|
||||||
|
RestorePatches();
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ApplyPatches(){
|
||||||
|
for(int module_index=0;module_index<gbl_replacement_data.number_used_modules;module_index++){
|
||||||
|
new_PatchInvidualMethodHooks(&gbl_replacement_data.module_data[module_index]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CallHook(wups_loader_hook_type_t hook_type){
|
||||||
|
for(int module_index=0;module_index<gbl_replacement_data.number_used_modules;module_index++){
|
||||||
|
replacement_data_module_t * module_data = &gbl_replacement_data.module_data[module_index];
|
||||||
|
DEBUG_FUNCTION_LINE("Checking hook functions for %s.\n",module_data->module_name);
|
||||||
|
DEBUG_FUNCTION_LINE("Found hooks: %d\n",module_data->number_used_hooks);
|
||||||
|
for(int j=0;j<module_data->number_used_hooks;j++){
|
||||||
|
replacement_data_hook_t * hook_data = &module_data->hooks[j];
|
||||||
|
if(hook_data->type == hook_type){
|
||||||
|
DEBUG_FUNCTION_LINE("Calling hook of type %d\n",hook_data->type);
|
||||||
|
void * func_ptr = hook_data->func_pointer;
|
||||||
|
//TODO: Switch cases depending on arguments etc.
|
||||||
|
if(func_ptr != NULL){
|
||||||
|
DEBUG_FUNCTION_LINE("Calling it! %08X\n",func_ptr);
|
||||||
|
( (void (*)(void))((unsigned int*)func_ptr) )();
|
||||||
|
}else{
|
||||||
|
DEBUG_FUNCTION_LINE("Was not defined\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RestorePatches(){
|
||||||
|
for(int module_index=0;module_index<gbl_replacement_data.number_used_modules;module_index++){
|
||||||
|
new_RestoreInvidualInstructions(&gbl_replacement_data.module_data[module_index]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
s32 isInMiiMakerHBL(){
|
||||||
|
if (OSGetTitleID != 0 && (
|
||||||
|
OSGetTitleID() == 0x000500101004A200 || // mii maker eur
|
||||||
|
OSGetTitleID() == 0x000500101004A100 || // mii maker usa
|
||||||
|
OSGetTitleID() == 0x000500101004A000 ||// mii maker jpn
|
||||||
|
OSGetTitleID() == 0x0005000013374842))
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void loadSamplePlugin(){
|
||||||
DEBUG_FUNCTION_LINE("Mount SD partition\n");
|
DEBUG_FUNCTION_LINE("Mount SD partition\n");
|
||||||
|
|
||||||
int res = 0;
|
int res = 0;
|
||||||
if((res = mount_sd_fat("sd")) >= 0){
|
if((res = mount_sd_fat("sd")) >= 0){
|
||||||
DEBUG_FUNCTION_LINE("Mounting successful\n");
|
DEBUG_FUNCTION_LINE("Mounting successful\n");
|
||||||
loadElf("sd:/wiiu/plugins/example_plugin.mod");
|
loadElf("sd:/wiiu/plugins/example_plugin.mod");
|
||||||
|
loadElf("sd:/wiiu/plugins/padcon.mod");
|
||||||
|
|
||||||
if(module_list_count == 0){
|
if(module_list_count == 0){
|
||||||
DEBUG_FUNCTION_LINE("Found no valid modules! =( Exiting\n");
|
DEBUG_FUNCTION_LINE("Found no valid modules! =( Exiting\n");
|
||||||
return EXIT_SUCCESS;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG_FUNCTION_LINE("Found %d modules!\n",module_list_count);
|
DEBUG_FUNCTION_LINE("Found %d modules!\n",module_list_count);
|
||||||
@ -81,12 +177,6 @@ extern "C" int Menu_Main(int argc, char **argv){
|
|||||||
|
|
||||||
printReplacementInfos();
|
printReplacementInfos();
|
||||||
|
|
||||||
for(int module_index=0;module_index<gbl_replacement_data.number_used_modules;module_index++){
|
|
||||||
new_PatchInvidualMethodHooks(&gbl_replacement_data.module_data[module_index]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// The example plugin should override the message.
|
|
||||||
OSFatal("We should never see this message.");
|
|
||||||
/*
|
/*
|
||||||
test code for calling the loaded functions.
|
test code for calling the loaded functions.
|
||||||
|
|
||||||
@ -105,10 +195,6 @@ extern "C" int Menu_Main(int argc, char **argv){
|
|||||||
}*/
|
}*/
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG_FUNCTION_LINE("Application is ending now.\n");
|
|
||||||
|
|
||||||
return EXIT_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void loadElf(const char * elfPath){
|
void loadElf(const char * elfPath){
|
||||||
|
@ -220,7 +220,10 @@ static void Module_LoadElf(const char *path, Elf *elf) {
|
|||||||
continue;
|
continue;
|
||||||
} else if (strcmp(name, ".wups.load") == 0) {
|
} else if (strcmp(name, ".wups.load") == 0) {
|
||||||
metadata->size +=
|
metadata->size +=
|
||||||
shdr->sh_size / sizeof(wups_loader_entry_t) * 12;
|
shdr->sh_size / sizeof(wups_loader_entry_t) * 6*4;
|
||||||
|
} else if (strcmp(name, ".wups.hooks") == 0) {
|
||||||
|
metadata->size +=
|
||||||
|
shdr->sh_size / sizeof(wups_loader_hook_t) * 2*4;
|
||||||
} else {
|
} else {
|
||||||
metadata->size += shdr->sh_size;
|
metadata->size += shdr->sh_size;
|
||||||
/* add alignment padding to size */
|
/* add alignment padding to size */
|
||||||
|
@ -55,6 +55,14 @@ struct replacement_data_function_t{
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct replacement_data_hook_t{
|
||||||
|
void * func_pointer = NULL; /* [will be filled] */
|
||||||
|
wups_loader_hook_type_t type; /* [will be filled] */
|
||||||
|
u32 hook_index; /* [needs to be filled] name of the function we want to replace */
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#define MAXIMUM_HOOKS_PER_MODULE 4
|
||||||
#define MAXIMUM_FUNCTION_PER_MODULE 100
|
#define MAXIMUM_FUNCTION_PER_MODULE 100
|
||||||
|
|
||||||
struct replacement_data_module_t{
|
struct replacement_data_module_t{
|
||||||
@ -62,6 +70,9 @@ struct replacement_data_module_t{
|
|||||||
int priority; // Priority of this module
|
int priority; // Priority of this module
|
||||||
int number_used_functions; // Number of used function. Maximum is MAXIMUM_FUNCTION_PER_MODULE
|
int number_used_functions; // Number of used function. Maximum is MAXIMUM_FUNCTION_PER_MODULE
|
||||||
replacement_data_function_t functions[MAXIMUM_FUNCTION_PER_MODULE]; // Replacement information for each function.
|
replacement_data_function_t functions[MAXIMUM_FUNCTION_PER_MODULE]; // Replacement information for each function.
|
||||||
|
|
||||||
|
int number_used_hooks; // Number of used hooks. Maximum is MAXIMUM_HOOKS_PER_MODULE
|
||||||
|
replacement_data_hook_t hooks[MAXIMUM_HOOKS_PER_MODULE]; // Replacement information for each function.
|
||||||
};
|
};
|
||||||
|
|
||||||
#define MAXIMUM_MODULES 32
|
#define MAXIMUM_MODULES 32
|
||||||
|
Loading…
Reference in New Issue
Block a user