From 40359e121184bca2e9f808db40edf5819f5eb968 Mon Sep 17 00:00:00 2001 From: Maschell Date: Mon, 1 Jun 2020 16:35:34 +0200 Subject: [PATCH] relocator: Save ordered list of modules based on dependencies, move hook calling into a new file --- relocator/src/entry.cpp | 27 +++++++++++---------------- relocator/src/hooks.cpp | 32 ++++++++++++++++++++++++++++++++ relocator/src/hooks.h | 8 ++++++++ 3 files changed, 51 insertions(+), 16 deletions(-) create mode 100644 relocator/src/hooks.cpp create mode 100644 relocator/src/hooks.h diff --git a/relocator/src/entry.cpp b/relocator/src/entry.cpp index 2a6efa1..d7d4682 100644 --- a/relocator/src/entry.cpp +++ b/relocator/src/entry.cpp @@ -21,13 +21,14 @@ #include "utils/logger.h" #include "utils/dynamic.h" #include "globals.h" +#include "hooks.h" #define gModuleData ((module_information_t *) (0x00880000)) uint8_t gFunctionsPatched __attribute__((section(".data"))) = 0; uint8_t gInitCalled __attribute__((section(".data"))) = 0; -void CallInitHook(const std::vector &loadedModules); +std::vector OrderModulesByDependencies(const std::vector &loadedModules); extern "C" void doStart(int argc, char **argv); // We need to wrap it to make sure the main function is called AFTER our code. @@ -135,18 +136,21 @@ extern "C" void doStart(int argc, char **argv) { PatchInvidualMethodHooks(method_hooks_hooks_static, method_hooks_size_hooks_static, method_calls_hooks_static); } DEBUG_FUNCTION_LINE("Loading module data\n"); - std::vector loadedModules = ModuleDataPersistence::loadModuleData(gModuleData); + std::vector loadedModulesUnordered = ModuleDataPersistence::loadModuleData(gModuleData); + std::vector loadedModules = OrderModulesByDependencies(loadedModulesUnordered); DEBUG_FUNCTION_LINE("Number of modules %d\n", gModuleData->number_used_modules); if (!gInitCalled) { gInitCalled = 1; DEBUG_FUNCTION_LINE("Resolve relocations without replacing alloc functions\n"); ResolveRelocations(loadedModules, false); - CallInitHook(loadedModules); for(auto& curModule : loadedModules){ if(curModule.getExportName().compare("homebrew_memorymapping") == 0){ for(auto& curExport : curModule.getExportDataList()){ if(curExport.getName().compare("MemoryMappingEffectiveToPhysical") == 0){ + + CallHook(loadedModules, WUMS_HOOK_INIT); + DEBUG_FUNCTION_LINE("Setting MemoryMappingEffectiveToPhysicalPTR to %08X\n", curExport.getAddress()); MemoryMappingEffectiveToPhysicalPTR = (uint32_t) curExport.getAddress(); }else if(curExport.getName().compare("MemoryMappingPhysicalToEffective") == 0){ @@ -180,7 +184,8 @@ extern "C" void doStart(int argc, char **argv) { } } -void CallInitHook(const std::vector &loadedModules) { +std::vector OrderModulesByDependencies(const std::vector &loadedModules) { + std::vector finalOrder; std::vector loadedModulesExportNames; std::vector loadedModulesEntrypoints; @@ -218,18 +223,7 @@ void CallInitHook(const std::vector &loadedModules) { } if (canLoad) { weDidSomething = true; - DEBUG_FUNCTION_LINE("We can load %s\n", curModule.getExportName().c_str()); - for (auto &curHook : curModule.getHookDataList()) { - if (curHook.getType() == WUMS_HOOK_INIT) { - uint32_t func_ptr = (uint32_t) curHook.getTarget(); - if (func_ptr == NULL) { - DEBUG_FUNCTION_LINE("Hook ptr was NULL\n"); - } else { - DEBUG_FUNCTION_LINE("Calling init of %s\n", curModule.getExportName().c_str()); - ((void (*)(void)) ((uint32_t *) func_ptr))(); - } - } - } + finalOrder.push_back(curModule); loadedModulesExportNames.push_back(curModule.getExportName()); loadedModulesEntrypoints.push_back(curModule.getEntrypoint()); } @@ -240,4 +234,5 @@ void CallInitHook(const std::vector &loadedModules) { OSFatal_printf("Failed to resolve dependencies."); } } + return finalOrder; } diff --git a/relocator/src/hooks.cpp b/relocator/src/hooks.cpp new file mode 100644 index 0000000..9415b8b --- /dev/null +++ b/relocator/src/hooks.cpp @@ -0,0 +1,32 @@ +#include "../../source/common/module_defines.h" +#include +#include "hooks.h" +#include "utils/logger.h" + +static const char **hook_names = (const char *[]) { + "WUMS_HOOK_INIT", + "WUMS_HOOK_APPLICATION_STARTS", + "WUMS_HOOK_APPLICATION_ENDS", + "WUMS_HOOK_INIT_WUT", + "WUMS_HOOK_FINI_WUT"}; + +void CallHook(const std::vector &modules, wums_hook_type_t type) { + DEBUG_FUNCTION_LINE("Calling hook of type %s [%d]", hook_names[type], type); + for (auto &curModule: modules) { + for (auto &curHook : curModule.getHookDataList()) { + if (curHook.getType() == WUMS_HOOK_INIT || + curHook.getType() == WUMS_HOOK_APPLICATION_STARTS || + curHook.getType() == WUMS_HOOK_APPLICATION_ENDS || + curHook.getType() == WUMS_HOOK_INIT_WUT || + curHook.getType() == WUMS_HOOK_FINI_WUT) { + uint32_t func_ptr = (uint32_t) curHook.getTarget(); + if (func_ptr == NULL) { + DEBUG_FUNCTION_LINE("Hook ptr was NULL\n"); + } else { + DEBUG_FUNCTION_LINE("Calling for module [%s]\n", curModule.getExportName().c_str()); + ((void (*)(void)) ((uint32_t *) func_ptr))(); + } + } + } + } +} diff --git a/relocator/src/hooks.h b/relocator/src/hooks.h new file mode 100644 index 0000000..689ca50 --- /dev/null +++ b/relocator/src/hooks.h @@ -0,0 +1,8 @@ +#pragma once + +#include + +#include +#include "../../source/module/ModuleData.h" + +void CallHook(const std::vector& modules, wums_hook_type_t type); \ No newline at end of file