From 6cb4f4e358177eb5a13747cc040b851a5646ab85 Mon Sep 17 00:00:00 2001 From: Maschell Date: Fri, 29 May 2020 17:36:10 +0200 Subject: [PATCH] Add initial support for storing and loadings hooks of modules (but not calling them) --- relocator/src/ModuleDataPersistence.cpp | 9 ++++++++ source/common/module_defines.h | 7 +++++++ source/main.cpp | 1 + source/module/HookData.h | 23 ++++++++++++++++++++ source/module/ModuleData.h | 9 ++++++++ source/module/ModuleDataFactory.cpp | 15 +++++++++++++ source/module/ModuleDataPersistence.cpp | 28 ++++++++++++++++++++++++- 7 files changed, 91 insertions(+), 1 deletion(-) create mode 100644 source/module/HookData.h diff --git a/relocator/src/ModuleDataPersistence.cpp b/relocator/src/ModuleDataPersistence.cpp index c707d40..47821d5 100644 --- a/relocator/src/ModuleDataPersistence.cpp +++ b/relocator/src/ModuleDataPersistence.cpp @@ -43,6 +43,15 @@ std::vector ModuleDataPersistence::loadModuleData(module_information } moduleData.addExportData(ExportData(static_cast(export_entry->type), export_entry->name, reinterpret_cast(export_entry->address))); } + + for (uint32_t j = 0; j < HOOK_ENTRY_LIST_LENGTH; j++) { + hook_data_t *hook_entry = &(module_data->hook_entries[j]); + if (hook_entry->target == NULL) { + continue; + } + moduleData.addHookData(HookData(static_cast(hook_entry->type), reinterpret_cast(hook_entry->target))); + } + for (uint32_t j = 0; j < DYN_LINK_RELOCATION_LIST_LENGTH; j++) { dyn_linking_relocation_entry_t *linking_entry = &(module_data->linking_entries[j]); if (linking_entry->destination == NULL) { diff --git a/source/common/module_defines.h b/source/common/module_defines.h index ac2a7d1..219742d 100644 --- a/source/common/module_defines.h +++ b/source/common/module_defines.h @@ -32,12 +32,19 @@ extern "C" { #define DYN_LINK_RELOCATION_LIST_LENGTH 500 #define EXPORT_ENTRY_LIST_LENGTH 100 +#define HOOK_ENTRY_LIST_LENGTH 10 + +typedef struct hook_data_t { + uint32_t type; + uint32_t target = 0; +} hook_data_t; struct module_information_single_t { char path[MAXIMUM_MODULE_PATH_NAME_LENGTH] = ""; // Path where the module is stored dyn_linking_relocation_entry_t linking_entries[DYN_LINK_RELOCATION_LIST_LENGTH]; char module_export_name[MAXIMUM_EXPORT_MODULE_NAME_LENGTH]; export_data_t export_entries[EXPORT_ENTRY_LIST_LENGTH]; + hook_data_t hook_entries[HOOK_ENTRY_LIST_LENGTH]; int32_t priority; // Priority of this module uint32_t bssAddr; uint32_t bssSize; diff --git a/source/main.cpp b/source/main.cpp index 4bf97a9..3440c68 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -118,6 +118,7 @@ int main(int argc, char **argv) { DirList modules("fs:/vol/external01/wiiu/modules", ".wms", DirList::Files, 1); modules.SortList(); uint32_t destination_address = 0x00900000; + for (int i = 0; i < modules.GetFilecount(); i++) { DEBUG_FUNCTION_LINE("Loading module %s", modules.GetFilepath(i)); diff --git a/source/module/HookData.h b/source/module/HookData.h new file mode 100644 index 0000000..cf90a3c --- /dev/null +++ b/source/module/HookData.h @@ -0,0 +1,23 @@ +#pragma once + +#include + +class HookData { +public: + HookData(wums_hook_type_t type, const void *target) { + this->type = type; + this->target = target; + } + + const wums_hook_type_t getType() const { + return type; + } + + const void *getTarget() const { + return target; + } + +private: + wums_hook_type_t type; + const void *target; +}; \ No newline at end of file diff --git a/source/module/ModuleData.h b/source/module/ModuleData.h index c5f193e..ceb17d6 100644 --- a/source/module/ModuleData.h +++ b/source/module/ModuleData.h @@ -23,6 +23,7 @@ #include "RelocationData.h" #include "SectionInfo.h" #include "ExportData.h" +#include "HookData.h" class ModuleData { public: @@ -69,6 +70,13 @@ public: const std::vector &getExportDataList() const { return export_data_list; } + void addHookData(const HookData &data) { + hook_data_list.push_back(data); + } + + const std::vector &getHookDataList() const { + return hook_data_list; + } void addSectionInfo(const SectionInfo §ionInfo) { section_info_list[sectionInfo.getName()] = sectionInfo; @@ -126,6 +134,7 @@ public: private: std::vector relocation_data_list; std::vector export_data_list; + std::vector hook_data_list; std::map section_info_list; std::string export_name; diff --git a/source/module/ModuleDataFactory.cpp b/source/module/ModuleDataFactory.cpp index 6c74bdb..abcf3e4 100644 --- a/source/module/ModuleDataFactory.cpp +++ b/source/module/ModuleDataFactory.cpp @@ -26,6 +26,7 @@ #include "ElfUtils.h" #include "SectionInfo.h" #include "ExportData.h" +#include "HookData.h" using namespace ELFIO; @@ -148,6 +149,20 @@ std::optional ModuleDataFactory::load(std::string path, uint32_t* de } } + secInfo = moduleData.getSectionInfo(".wums.hooks"); + if (secInfo && secInfo->getSize() > 0) { + size_t entries_count = secInfo->getSize() / sizeof(wums_hook_t); + wums_hook_t *hooks = (wums_hook_t *) secInfo->getAddress(); + if (hooks != NULL) { + for (size_t j = 0; j < entries_count; j++) { + wums_hook_t * hook = &hooks[j]; + DEBUG_FUNCTION_LINE("Saving hook of type %08X, target: %08X"/*,pluginData.getPluginInformation()->getName().c_str()*/, hook->type, hook->target); + HookData hook_data(hook->type, hook->target); + moduleData.addHookData(hook_data); + } + } + } + secInfo = moduleData.getSectionInfo(".wums.meta"); if (secInfo && secInfo->getSize() > 0) { wums_entry_t *entries = (wums_entry_t *) secInfo->getAddress(); diff --git a/source/module/ModuleDataPersistence.cpp b/source/module/ModuleDataPersistence.cpp index edd73d6..c473f44 100644 --- a/source/module/ModuleDataPersistence.cpp +++ b/source/module/ModuleDataPersistence.cpp @@ -27,7 +27,6 @@ bool ModuleDataPersistence::saveModuleData(module_information_t *moduleInformati } std::vector exportData = module.getExportDataList(); - for (auto const &curExport : exportData) { bool found = false; for (uint32_t j = 0; j < EXPORT_ENTRY_LIST_LENGTH; j++) { @@ -42,6 +41,25 @@ bool ModuleDataPersistence::saveModuleData(module_information_t *moduleInformati } if (!found) { DEBUG_FUNCTION_LINE("Failed to found enough exports slots"); + break; + } + } + + std::vector hookData = module.getHookDataList(); + for (auto const &curHook : hookData) { + bool found = false; + for (uint32_t j = 0; j < HOOK_ENTRY_LIST_LENGTH; j++) { + hook_data_t *hook_entry = &(module_data->hook_entries[j]); + if (hook_entry->target == NULL) { + hook_entry->type = curHook.getType(); + hook_entry->target = (uint32_t) curHook.getTarget(); + found = true; + break; + } + } + if (!found) { + DEBUG_FUNCTION_LINE("Failed to found enough hook slots"); + break; } } @@ -98,6 +116,14 @@ std::vector ModuleDataPersistence::loadModuleData(module_information moduleData.addExportData(ExportData(static_cast(export_entry->type), export_entry->name, reinterpret_cast(export_entry->address))); } + for (uint32_t j = 0; j < HOOK_ENTRY_LIST_LENGTH; j++) { + hook_data_t *hook_entry = &(module_data->hook_entries[j]); + if (hook_entry->target == NULL) { + continue; + } + moduleData.addHookData(HookData(static_cast(hook_entry->type), reinterpret_cast(hook_entry->target))); + } + for (uint32_t j = 0; j < DYN_LINK_RELOCATION_LIST_LENGTH; j++) { dyn_linking_relocation_entry_t *linking_entry = &(module_data->linking_entries[j]); if (linking_entry->destination == NULL) {