mirror of
https://github.com/wiiu-env/WiiUPluginSystem.git
synced 2024-12-24 00:51:59 +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 <dynamic_libs/os_functions.h>
|
||||
|
||||
//TODO: Adjust this.
|
||||
#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;
|
||||
size_t module_entries_count = 0;
|
||||
size_t module_entries_capacity = 0;
|
||||
@ -106,10 +114,11 @@ exit_error:
|
||||
|
||||
bool Module_LinkModuleElf(size_t index, Elf *elf, uint8_t **space) {
|
||||
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;
|
||||
uint8_t **destinations = NULL;
|
||||
wups_loader_entry_t *entries = NULL;
|
||||
wups_loader_hook_t *hooks = NULL;
|
||||
bool result = false;
|
||||
|
||||
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].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 {
|
||||
*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++){
|
||||
replacement_data_module_t * module_data = &gbl_replacement_data.module_data[module_index];
|
||||
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);
|
||||
for(int j=0;j<module_data->number_used_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/socket_functions.h>
|
||||
#include <dynamic_libs/sys_functions.h>
|
||||
#include <dynamic_libs/fs_functions.h>
|
||||
#include <dynamic_libs/vpad_functions.h>
|
||||
#include <utils/logger.h>
|
||||
#include <fs/FSUtils.h>
|
||||
#include <fs/sd_fat_devoptab.h>
|
||||
@ -27,13 +29,23 @@
|
||||
#include "patcher/function_patcher.h"
|
||||
|
||||
static void printModuleInfos();
|
||||
static void loadSamplePlugin();
|
||||
static void printInfos();
|
||||
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 */
|
||||
extern "C" int Menu_Main(int argc, char **argv){
|
||||
InitOSFunctionPointers();
|
||||
InitSocketFunctionPointers(); //For logging
|
||||
InitSysFunctionPointers();
|
||||
InitFSFunctionPointers();
|
||||
|
||||
log_init();
|
||||
@ -42,20 +54,104 @@ extern "C" int Menu_Main(int argc, char **argv){
|
||||
|
||||
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));
|
||||
loadSamplePlugin();
|
||||
}
|
||||
|
||||
memset((void*)&gbl_replacement_data,0,sizeof(gbl_replacement_data));
|
||||
|
||||
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");
|
||||
|
||||
int res = 0;
|
||||
if((res = mount_sd_fat("sd")) >= 0){
|
||||
DEBUG_FUNCTION_LINE("Mounting successful\n");
|
||||
loadElf("sd:/wiiu/plugins/example_plugin.mod");
|
||||
loadElf("sd:/wiiu/plugins/padcon.mod");
|
||||
|
||||
if(module_list_count == 0){
|
||||
DEBUG_FUNCTION_LINE("Found no valid modules! =( Exiting\n");
|
||||
return EXIT_SUCCESS;
|
||||
return;
|
||||
}
|
||||
|
||||
DEBUG_FUNCTION_LINE("Found %d modules!\n",module_list_count);
|
||||
@ -81,12 +177,6 @@ extern "C" int Menu_Main(int argc, char **argv){
|
||||
|
||||
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.
|
||||
|
||||
@ -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){
|
||||
|
@ -220,7 +220,10 @@ static void Module_LoadElf(const char *path, Elf *elf) {
|
||||
continue;
|
||||
} else if (strcmp(name, ".wups.load") == 0) {
|
||||
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 {
|
||||
metadata->size += shdr->sh_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
|
||||
|
||||
struct replacement_data_module_t{
|
||||
@ -62,6 +70,9 @@ struct replacement_data_module_t{
|
||||
int priority; // Priority of this 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.
|
||||
|
||||
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
|
||||
|
Loading…
Reference in New Issue
Block a user