From 460c235430090a99d4da01dfbbd3d279023c2bb1 Mon Sep 17 00:00:00 2001 From: Maschell Date: Tue, 7 Dec 2021 18:23:18 +0100 Subject: [PATCH] Use std::shared_ptr --- relocator/src/DynamicLinkingHelper.cpp | 14 ++-- relocator/src/DynamicLinkingHelper.h | 5 +- relocator/src/ModuleDataMinimal.h | 13 ++-- relocator/src/ModuleDataPersistence.cpp | 20 +++--- relocator/src/ModuleDataPersistence.h | 2 +- relocator/src/entry.cpp | 61 ++++++++--------- relocator/src/hooks.cpp | 19 +++--- relocator/src/hooks.h | 4 +- source/main.cpp | 29 ++++---- source/module/DynamicLinkingHelper.cpp | 50 +++++++------- source/module/DynamicLinkingHelper.h | 6 +- source/module/ImportRPLInformation.h | 7 +- source/module/ModuleData.cpp | 2 +- source/module/ModuleData.h | 42 +++++++----- source/module/ModuleDataFactory.cpp | 80 +++++++++++----------- source/module/ModuleDataFactory.h | 4 +- source/module/ModuleDataPersistence.cpp | 88 +++++++++++++------------ source/module/ModuleDataPersistence.h | 4 +- source/module/RelocationData.cpp | 4 +- source/module/RelocationData.h | 10 +-- 20 files changed, 241 insertions(+), 223 deletions(-) diff --git a/relocator/src/DynamicLinkingHelper.cpp b/relocator/src/DynamicLinkingHelper.cpp index ff44f7b..4daad55 100644 --- a/relocator/src/DynamicLinkingHelper.cpp +++ b/relocator/src/DynamicLinkingHelper.cpp @@ -61,17 +61,17 @@ dyn_linking_import_t *DynamicLinkingHelper::getOrAddImport(dyn_linking_relocatio } bool DynamicLinkingHelper::addRelocationEntry(dyn_linking_relocation_data_t *linking_data, dyn_linking_relocation_entry_t *linking_entries, uint32_t linking_entry_length, - const RelocationData &relocationData) { - return addRelocationEntry(linking_data, linking_entries, linking_entry_length, relocationData.getType(), - relocationData.getOffset(), relocationData.getAddend(), relocationData.getDestination(), - relocationData.getName(), - relocationData.getImportRPLInformation()); + const std::shared_ptr &relocationData) { + return addRelocationEntry(linking_data, linking_entries, linking_entry_length, relocationData->getType(), + relocationData->getOffset(), relocationData->getAddend(), relocationData->getDestination(), + relocationData->getName(), + relocationData->getImportRPLInformation()); } bool DynamicLinkingHelper::addRelocationEntry(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, void *destination, - const std::string &name, const ImportRPLInformation &rplInfo) { - dyn_linking_import_t *importInfoGbl = DynamicLinkingHelper::getOrAddImport(linking_data, rplInfo.getName().c_str(), rplInfo.isData()); + const std::string &name, const std::shared_ptr &rplInfo) { + dyn_linking_import_t *importInfoGbl = DynamicLinkingHelper::getOrAddImport(linking_data, rplInfo->getName().c_str(), rplInfo->isData()); if (importInfoGbl == nullptr) { DEBUG_FUNCTION_LINE("Getting import info failed. Probably maximum of %d rpl files to import reached.\n", DYN_LINK_IMPORT_LIST_LENGTH); return false; diff --git a/relocator/src/DynamicLinkingHelper.h b/relocator/src/DynamicLinkingHelper.h index ce64b30..d03969f 100644 --- a/relocator/src/DynamicLinkingHelper.h +++ b/relocator/src/DynamicLinkingHelper.h @@ -47,12 +47,13 @@ public: **/ static dyn_linking_import_t *getOrAddImport(dyn_linking_relocation_data_t *data, const char *importName, bool isData); - static bool addRelocationEntry(dyn_linking_relocation_data_t *linking_data, dyn_linking_relocation_entry_t *linking_entries, uint32_t linking_entry_length, const RelocationData &relocationData); + static bool addRelocationEntry(dyn_linking_relocation_data_t *linking_data, dyn_linking_relocation_entry_t *linking_entries, uint32_t linking_entry_length, + const std::shared_ptr &relocationData); static bool addRelocationEntry(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, void *destination, const std::string &name, - const ImportRPLInformation &rplInfo); + const std::shared_ptr &rplInfo); static bool addRelocationEntry(dyn_linking_relocation_entry_t *linking_entries, uint32_t linking_entry_length, char type, size_t offset, int32_t addend, void *destination, diff --git a/relocator/src/ModuleDataMinimal.h b/relocator/src/ModuleDataMinimal.h index d12f405..96f160e 100644 --- a/relocator/src/ModuleDataMinimal.h +++ b/relocator/src/ModuleDataMinimal.h @@ -34,19 +34,19 @@ public: return this->export_name; } - void addRelocationData(const RelocationData &relocation_data) { + void addRelocationData(const std::shared_ptr &relocation_data) { relocation_data_list.push_back(relocation_data); } - [[nodiscard]] const std::vector &getRelocationDataList() const { + [[nodiscard]] const std::vector> &getRelocationDataList() const { return relocation_data_list; } - void addHookData(const HookData &data) { + void addHookData(const std::shared_ptr &data) { hook_data_list.push_back(data); } - [[nodiscard]] const std::vector &getHookDataList() const { + [[nodiscard]] const std::vector> &getHookDataList() const { return hook_data_list; } @@ -68,10 +68,9 @@ public: bool relocationsDone = false; private: - std::vector relocation_data_list; - std::vector hook_data_list; + std::vector> relocation_data_list; + std::vector> hook_data_list; std::string export_name; uint32_t entrypoint = 0; bool initBeforeRelocationDoneHook = false; - }; diff --git a/relocator/src/ModuleDataPersistence.cpp b/relocator/src/ModuleDataPersistence.cpp index 5af0764..6d4eecc 100644 --- a/relocator/src/ModuleDataPersistence.cpp +++ b/relocator/src/ModuleDataPersistence.cpp @@ -3,8 +3,8 @@ #include #include -std::vector ModuleDataPersistence::loadModuleData(module_information_t *moduleInformation) { - std::vector result; +std::vector> ModuleDataPersistence::loadModuleData(module_information_t *moduleInformation) { + std::vector> result; if (moduleInformation == nullptr) { DEBUG_FUNCTION_LINE("moduleInformation == NULL\n"); return result; @@ -22,17 +22,17 @@ std::vector ModuleDataPersistence::loadModuleData(module_info for (int32_t i = 0; i < module_count; i++) { // Copy data from struct. module_information_single_t *module_data = &(moduleInformation->module_data[i]); - ModuleDataMinimal moduleData; + auto moduleData = std::make_shared(); - moduleData.setEntrypoint(module_data->entrypoint); - moduleData.setInitBeforeRelocationDoneHook(module_data->initBeforeRelocationDoneHook); - moduleData.setExportName(module_data->module_export_name); + moduleData->setEntrypoint(module_data->entrypoint); + moduleData->setInitBeforeRelocationDoneHook(module_data->initBeforeRelocationDoneHook); + moduleData->setExportName(module_data->module_export_name); for (auto &hook_entry: module_data->hook_entries) { if (hook_entry.target == 0) { continue; } - moduleData.addHookData(HookData(static_cast(hook_entry.type), reinterpret_cast(hook_entry.target))); + moduleData->addHookData(std::make_shared(static_cast(hook_entry.type), reinterpret_cast(hook_entry.target))); } for (auto &linking_entry: module_data->linking_entries) { @@ -58,10 +58,10 @@ std::vector ModuleDataPersistence::loadModuleData(module_info DEBUG_FUNCTION_LINE("functionEntry->functionName was NULL, skipping relocation entry\n"); continue; } - ImportRPLInformation rplInfo(importEntry->importName, importEntry->isData); - RelocationData reloc(linking_entry.type, linking_entry.offset, linking_entry.addend, linking_entry.destination, functionEntry->functionName, rplInfo); + auto rplInfo = std::make_shared(importEntry->importName, importEntry->isData); + auto reloc = std::make_shared(linking_entry.type, linking_entry.offset, linking_entry.addend, linking_entry.destination, functionEntry->functionName, rplInfo); - moduleData.addRelocationData(reloc); + moduleData->addRelocationData(reloc); } result.push_back(moduleData); diff --git a/relocator/src/ModuleDataPersistence.h b/relocator/src/ModuleDataPersistence.h index c0d811e..624bf45 100644 --- a/relocator/src/ModuleDataPersistence.h +++ b/relocator/src/ModuleDataPersistence.h @@ -6,5 +6,5 @@ class ModuleDataPersistence { public: - static std::vector loadModuleData(module_information_t *moduleInformation); + static std::vector> loadModuleData(module_information_t *moduleInformation); }; diff --git a/relocator/src/entry.cpp b/relocator/src/entry.cpp index 3059435..80edde2 100644 --- a/relocator/src/entry.cpp +++ b/relocator/src/entry.cpp @@ -21,7 +21,7 @@ uint8_t gInitCalled __attribute__((section(".data"))) = 0; extern "C" void socket_lib_init(); -std::vector OrderModulesByDependencies(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. @@ -46,11 +46,11 @@ extern "C" int _start(int argc, char **argv) { return ((int (*)(int, char **)) (*(unsigned int *) 0x1005E040))(argc, argv); } -bool doRelocation(std::vector &relocData, relocation_trampolin_entry_t *tramp_data, uint32_t tramp_length, bool skipAllocReplacement) { +bool doRelocation(std::vector> &relocData, relocation_trampolin_entry_t *tramp_data, uint32_t tramp_length, bool skipAllocReplacement) { std::map moduleCache; for (auto const &curReloc: relocData) { - std::string functionName = curReloc.getName(); - std::string rplName = curReloc.getImportRPLInformation().getName(); + std::string functionName = curReloc->getName(); + std::string rplName = curReloc->getImportRPLInformation()->getName(); uint32_t functionAddress = 0; for (uint32_t i = 0; i < MAXIMUM_MODULES; i++) { @@ -75,7 +75,7 @@ bool doRelocation(std::vector &relocData, relocation_trampolin_e } if (functionAddress == 0) { - int32_t isData = curReloc.getImportRPLInformation().isData(); + int32_t isData = curReloc->getImportRPLInformation()->isData(); OSDynLoad_Module rplHandle = nullptr; if (moduleCache.count(rplName) == 0) { OSDynLoad_Error err = OSDynLoad_IsModuleLoaded(rplName.c_str(), &rplHandle); @@ -98,7 +98,8 @@ bool doRelocation(std::vector &relocData, relocation_trampolin_e return false; } } - if (!ElfUtils::elfLinkOne(curReloc.getType(), curReloc.getOffset(), curReloc.getAddend(), (uint32_t) curReloc.getDestination(), functionAddress, tramp_data, tramp_length, RELOC_TYPE_IMPORT)) { + if (!ElfUtils::elfLinkOne(curReloc->getType(), curReloc->getOffset(), curReloc->getAddend(), (uint32_t) curReloc->getDestination(), functionAddress, tramp_data, tramp_length, + RELOC_TYPE_IMPORT)) { DEBUG_FUNCTION_LINE("Relocation failed\n"); return false; } @@ -109,26 +110,26 @@ bool doRelocation(std::vector &relocData, relocation_trampolin_e return true; } -bool ResolveRelocations(std::vector &loadedModules, bool skipMemoryMappingModule) { +bool ResolveRelocations(std::vector> &loadedModules, bool skipMemoryMappingModule) { bool wasSuccessful = true; for (auto &curModule: loadedModules) { - DEBUG_FUNCTION_LINE_VERBOSE("Let's do the relocations for %s\n", curModule.getExportName().c_str()); + DEBUG_FUNCTION_LINE_VERBOSE("Let's do the relocations for %s\n", curModule->getExportName().c_str()); if (wasSuccessful) { - std::vector relocData = curModule.getRelocationDataList(); + auto relocData = curModule->getRelocationDataList(); // On first usage we can't redirect the alloc functions to our custom heap // because threads can't run it on it. In order to patch the kernel // to fully support our memory region, we have to run the FunctionPatcher and MemoryMapping // once with the default heap. Afterwards we can just rely on the custom heap. - bool skipAllocFunction = skipMemoryMappingModule && (curModule.getExportName() == "homebrew_memorymapping" || curModule.getExportName() == "homebrew_functionpatcher"); + bool skipAllocFunction = skipMemoryMappingModule && (curModule->getExportName() == "homebrew_memorymapping" || curModule->getExportName() == "homebrew_functionpatcher"); DEBUG_FUNCTION_LINE_VERBOSE("Skip alloc replace? %d\n", skipAllocFunction); if (!doRelocation(relocData, gModuleData->trampolines, DYN_LINK_TRAMPOLIN_LIST_LENGTH, skipAllocFunction)) { DEBUG_FUNCTION_LINE("FAIL\n"); wasSuccessful = false; - curModule.relocationsDone = false; + curModule->relocationsDone = false; } - curModule.relocationsDone = true; + curModule->relocationsDone = true; } } @@ -147,7 +148,7 @@ extern "C" void doStart(int argc, char **argv) { bool applicationEndHookLoaded = false; for (auto &curModule: loadedModules) { - if (curModule.getExportName() == "homebrew_applicationendshook") { + if (curModule->getExportName() == "homebrew_applicationendshook") { DEBUG_FUNCTION_LINE_VERBOSE("We have ApplicationEndsHook Module!\n"); applicationEndHookLoaded = true; break; @@ -156,10 +157,10 @@ extern "C" void doStart(int argc, char **argv) { // Make sure WUMS_HOOK_APPLICATION_ENDS and WUMS_HOOK_FINI_WUT are called for (auto &curModule: loadedModules) { - for (auto &curHook: curModule.getHookDataList()) { - if (curHook.getType() == WUMS_HOOK_APPLICATION_ENDS || curHook.getType() == WUMS_HOOK_FINI_WUT_DEVOPTAB) { + for (auto &curHook: curModule->getHookDataList()) { + if (curHook->getType() == WUMS_HOOK_APPLICATION_ENDS || curHook->getType() == WUMS_HOOK_FINI_WUT_DEVOPTAB) { if (!applicationEndHookLoaded) { - OSFatal_printf("%s requires module homebrew_applicationendshook", curModule.getExportName().c_str()); + OSFatal_printf("%s requires module homebrew_applicationendshook", curModule->getExportName().c_str()); } } } @@ -173,7 +174,7 @@ extern "C" void doStart(int argc, char **argv) { ResolveRelocations(loadedModules, true); for (auto &curModule: loadedModules) { - if (curModule.isInitBeforeRelocationDoneHook()) { + if (curModule->isInitBeforeRelocationDoneHook()) { CallHook(curModule, WUMS_HOOK_INIT_WUT_MALLOC); CallHook(curModule, WUMS_HOOK_INIT_WUT_NEWLIB); CallHook(curModule, WUMS_HOOK_INIT_WUT_STDCPP); @@ -191,7 +192,6 @@ extern "C" void doStart(int argc, char **argv) { DEBUG_FUNCTION_LINE_VERBOSE("Relocations done\n"); CallHook(loadedModules, WUMS_HOOK_RELOCATIONS_DONE); - for (int i = 0; i < gModuleData->number_used_modules; i++) { if (!gModuleData->module_data[i].skipEntrypoint) { DEBUG_FUNCTION_LINE_VERBOSE("About to call %08X\n", gModuleData->module_data[i].entrypoint); @@ -201,7 +201,7 @@ extern "C" void doStart(int argc, char **argv) { } for (auto &curModule: loadedModules) { - if (!curModule.isInitBeforeRelocationDoneHook()) { + if (!curModule->isInitBeforeRelocationDoneHook()) { CallHook(curModule, WUMS_HOOK_INIT_WUT_MALLOC); CallHook(curModule, WUMS_HOOK_INIT_WUT_NEWLIB); CallHook(curModule, WUMS_HOOK_INIT_WUT_STDCPP); @@ -220,6 +220,7 @@ extern "C" void doStart(int argc, char **argv) { ResolveRelocations(loadedModules, false); CallHook(loadedModules, WUMS_HOOK_RELOCATIONS_DONE); } + CallHook(loadedModules, WUMS_HOOK_INIT_WUT_MALLOC); CallHook(loadedModules, WUMS_HOOK_INIT_WUT_NEWLIB); CallHook(loadedModules, WUMS_HOOK_INIT_WUT_STDCPP); @@ -229,8 +230,8 @@ extern "C" void doStart(int argc, char **argv) { //CallHook(loadedModules, WUMS_HOOK_FINI_WUT); } -std::vector OrderModulesByDependencies(const std::vector &loadedModules) { - std::vector finalOrder; +std::vector> OrderModulesByDependencies(const std::vector> &loadedModules) { + std::vector> finalOrder; std::vector loadedModulesExportNames; std::vector loadedModulesEntrypoints; @@ -238,20 +239,20 @@ std::vector OrderModulesByDependencies(const std::vectorgetEntrypoint()) != loadedModulesEntrypoints.end()) { + // DEBUG_FUNCTION_LINE("%s [%08X] is already loaded\n", curModule->getExportName().c_str(), curModule->getEntrypoint()); continue; } canBreak = false; - DEBUG_FUNCTION_LINE_VERBOSE("Check if we can load %s\n", curModule.getExportName().c_str()); + DEBUG_FUNCTION_LINE_VERBOSE("Check if we can load %s\n", curModule->getExportName().c_str()); std::vector importsFromOtherModules; - for (const auto &curReloc: curModule.getRelocationDataList()) { - std::string curRPL = curReloc.getImportRPLInformation().getName(); + for (const auto &curReloc: curModule->getRelocationDataList()) { + std::string curRPL = curReloc->getImportRPLInformation()->getName(); if (curRPL.rfind("homebrew", 0) == 0) { if (std::find(importsFromOtherModules.begin(), importsFromOtherModules.end(), curRPL) != importsFromOtherModules.end()) { // is already in vector } else { - DEBUG_FUNCTION_LINE_VERBOSE("%s is importing from %s\n", curModule.getExportName().c_str(), curRPL.c_str()); + DEBUG_FUNCTION_LINE_VERBOSE("%s is importing from %s\n", curModule->getExportName().c_str(), curRPL.c_str()); importsFromOtherModules.push_back(curRPL); } } @@ -268,10 +269,10 @@ std::vector OrderModulesByDependencies(const std::vectorgetExportName().c_str()); finalOrder.push_back(curModule); - loadedModulesExportNames.push_back(curModule.getExportName()); - loadedModulesEntrypoints.push_back(curModule.getEntrypoint()); + loadedModulesExportNames.push_back(curModule->getExportName()); + loadedModulesEntrypoints.push_back(curModule->getEntrypoint()); } } if (canBreak) { diff --git a/relocator/src/hooks.cpp b/relocator/src/hooks.cpp index ef18988..becf6c3 100644 --- a/relocator/src/hooks.cpp +++ b/relocator/src/hooks.cpp @@ -18,29 +18,30 @@ static const char **hook_names = (const char *[]) { "WUMS_HOOK_APPLICATION_STARTS", "WUMS_HOOK_APPLICATION_ENDS", "WUMS_HOOK_RELOCATIONS_DONE", - "WUMS_HOOK_APPLICATION_REQUESTS_EXI"}; + "WUMS_HOOK_APPLICATION_REQUESTS_EXIT" +}; -void CallHook(const std::vector &modules, wums_hook_type_t type) { +void CallHook(const std::vector> &modules, wums_hook_type_t type) { DEBUG_FUNCTION_LINE_VERBOSE("Calling hook of type %s [%d] for all modules\n", hook_names[type], type); for (auto &curModule: modules) { CallHook(curModule, type); } } -void CallHook(const ModuleDataMinimal &module, wums_hook_type_t type) { - if (!module.relocationsDone) { +void CallHook(const std::shared_ptr &module, wums_hook_type_t type) { + if (!module->relocationsDone) { DEBUG_FUNCTION_LINE("Hook not called because the relocations failed\n"); return; } - for (auto &curHook: module.getHookDataList()) { - auto func_ptr = (uint32_t) curHook.getTarget(); + for (auto &curHook: module->getHookDataList()) { + auto func_ptr = (uint32_t) curHook->getTarget(); if (func_ptr == 0) { DEBUG_FUNCTION_LINE("Hook ptr was NULL\n"); break; } - if (type == curHook.getType()) { + if (type == curHook->getType()) { if ((type == WUMS_HOOK_APPLICATION_STARTS || type == WUMS_HOOK_APPLICATION_ENDS || type == WUMS_HOOK_INIT_WUT_MALLOC || @@ -54,12 +55,12 @@ void CallHook(const ModuleDataMinimal &module, wums_hook_type_t type) { type == WUMS_HOOK_INIT_WUT_SOCKETS || type == WUMS_HOOK_FINI_WUT_SOCKETS )) { - DEBUG_FUNCTION_LINE_VERBOSE("Calling hook of type %s [%d] %d for %s: %08X\n", hook_names[type], type, curHook.getType(), module.getExportName().c_str(), curHook.getTarget()); + DEBUG_FUNCTION_LINE_VERBOSE("Calling hook of type %s [%d] %d for %s: %08X\n", hook_names[type], type, curHook->getType(), module->getExportName().c_str(), curHook->getTarget()); ((void (*)()) ((uint32_t *) func_ptr))(); break; } else if (type == WUMS_HOOK_INIT || type == WUMS_HOOK_RELOCATIONS_DONE) { - DEBUG_FUNCTION_LINE_VERBOSE("Calling hook of type %s [%d] %d for %s: %08X\n", hook_names[type], type, curHook.getType(), module.getExportName().c_str(), curHook.getTarget()); + DEBUG_FUNCTION_LINE_VERBOSE("Calling hook of type %s [%d] %d for %s: %08X\n", hook_names[type], type, curHook->getType(), module->getExportName().c_str(), curHook->getTarget()); wums_app_init_args_t args; args.module_information = gModuleData; ((void (*)(wums_app_init_args_t *)) ((uint32_t *) func_ptr))(&args); diff --git a/relocator/src/hooks.h b/relocator/src/hooks.h index 320a162..40a04f3 100644 --- a/relocator/src/hooks.h +++ b/relocator/src/hooks.h @@ -5,6 +5,6 @@ #include #include "ModuleDataMinimal.h" -void CallHook(const std::vector &modules, wums_hook_type_t type); +void CallHook(const std::vector> &modules, wums_hook_type_t type); -void CallHook(const ModuleDataMinimal &module, wums_hook_type_t type); \ No newline at end of file +void CallHook(const std::shared_ptr &module, wums_hook_type_t type); \ No newline at end of file diff --git a/source/main.cpp b/source/main.cpp index 0e01ac9..32589e4 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include "fs/DirList.h" #include "module/ModuleDataPersistence.h" @@ -42,11 +43,11 @@ extern "C" uint32_t textStart(); extern "C" void _SYSLaunchMenuWithCheckingAccount(nn::act::SlotNo slot); -bool doRelocation(std::vector &relocData, relocation_trampolin_entry_t *tramp_data, uint32_t tramp_length) { +bool doRelocation(std::vector> &relocData, relocation_trampolin_entry_t *tramp_data, uint32_t tramp_length) { for (auto const &curReloc: relocData) { - std::string functionName = curReloc.getName(); - std::string rplName = curReloc.getImportRPLInformation().getName(); - int32_t isData = curReloc.getImportRPLInformation().isData(); + std::string functionName = curReloc->getName(); + std::string rplName = curReloc->getImportRPLInformation()->getName(); + int32_t isData = curReloc->getImportRPLInformation()->isData(); OSDynLoad_Module rplHandle = nullptr; if (OSDynLoad_IsModuleLoaded(rplName.c_str(), &rplHandle) != OS_DYNLOAD_OK) { @@ -59,7 +60,8 @@ bool doRelocation(std::vector &relocData, relocation_trampolin_e if (functionAddress == 0) { return false; } - if (!ElfUtils::elfLinkOne(curReloc.getType(), curReloc.getOffset(), curReloc.getAddend(), (uint32_t) curReloc.getDestination(), functionAddress, tramp_data, tramp_length, RELOC_TYPE_IMPORT)) { + if (!ElfUtils::elfLinkOne(curReloc->getType(), curReloc->getOffset(), curReloc->getAddend(), (uint32_t) curReloc->getDestination(), functionAddress, tramp_data, tramp_length, + RELOC_TYPE_IMPORT)) { DEBUG_FUNCTION_LINE("Relocation failed\n"); return false; } @@ -87,21 +89,22 @@ int main(int argc, char **argv) { uint32_t destination_address = ((uint32_t) gModuleData + (sizeof(module_information_t) + 0x0000FFFF)) & 0xFFFF0000; memset((void *) gModuleData, 0, sizeof(module_information_t)); DEBUG_FUNCTION_LINE("Trying to run %s", setupModules.GetFilepath(i)); - std::optional moduleData = ModuleDataFactory::load(setupModules.GetFilepath(i), &destination_address, textSectionStart - destination_address, gModuleData->trampolines, - DYN_LINK_TRAMPOLIN_LIST_LENGTH); + auto moduleData = ModuleDataFactory::load(setupModules.GetFilepath(i), &destination_address, textSectionStart - destination_address, gModuleData->trampolines, + DYN_LINK_TRAMPOLIN_LIST_LENGTH); if (!moduleData) { DEBUG_FUNCTION_LINE("Failed to load %s", setupModules.GetFilepath(i)); continue; } DEBUG_FUNCTION_LINE("Loaded module data"); - std::vector relocData = moduleData->getRelocationDataList(); + auto relocData = moduleData.value()->getRelocationDataList(); if (!doRelocation(relocData, gModuleData->trampolines, DYN_LINK_TRAMPOLIN_LIST_LENGTH)) { DEBUG_FUNCTION_LINE("relocations failed\n"); } - DCFlushRange((void *) moduleData->getStartAddress(), moduleData->getEndAddress() - moduleData->getStartAddress()); - ICInvalidateRange((void *) moduleData->getStartAddress(), moduleData->getEndAddress() - moduleData->getStartAddress()); - DEBUG_FUNCTION_LINE("Calling entrypoint @%08X", moduleData->getEntrypoint()); - ((int (*)(int, char **)) moduleData->getEntrypoint())(argc, argv); + + DCFlushRange((void *) moduleData.value()->getStartAddress(), moduleData.value()->getEndAddress() - moduleData.value()->getStartAddress()); + ICInvalidateRange((void *) moduleData.value()->getStartAddress(), moduleData.value()->getEndAddress() - moduleData.value()->getStartAddress()); + DEBUG_FUNCTION_LINE("Calling entrypoint @%08X", moduleData.value()->getEntrypoint()); + ((int (*)(int, char **)) moduleData.value()->getEntrypoint())(argc, argv); DEBUG_FUNCTION_LINE("Back from module"); } @@ -115,7 +118,7 @@ int main(int argc, char **argv) { for (int i = 0; i < modules.GetFilecount(); i++) { DEBUG_FUNCTION_LINE("Loading module %s", modules.GetFilepath(i)); auto moduleData = ModuleDataFactory::load(modules.GetFilepath(i), &destination_address, MEMORY_REGION_USABLE_END - destination_address, gModuleData->trampolines, - DYN_LINK_TRAMPOLIN_LIST_LENGTH); + DYN_LINK_TRAMPOLIN_LIST_LENGTH); if (moduleData) { DEBUG_FUNCTION_LINE("Successfully loaded %s", modules.GetFilepath(i)); diff --git a/source/module/DynamicLinkingHelper.cpp b/source/module/DynamicLinkingHelper.cpp index 73899cd..26b26ac 100644 --- a/source/module/DynamicLinkingHelper.cpp +++ b/source/module/DynamicLinkingHelper.cpp @@ -1,24 +1,24 @@ #include "DynamicLinkingHelper.h" -#include -#include +#include +#include #include #include #include "utils/logger.h" dyn_linking_function_t *DynamicLinkingHelper::getOrAddFunctionEntryByName(dyn_linking_relocation_data_t *data, const char *functionName) { - if (data == NULL) { - return NULL; + if (data == nullptr) { + return nullptr; } - if (functionName == NULL) { - return NULL; + if (functionName == nullptr) { + return nullptr; } - dyn_linking_function_t *result = NULL; - for (int32_t i = 0; i < DYN_LINK_FUNCTION_LIST_LENGTH; i++) { - dyn_linking_function_t *curEntry = &(data->functions[i]); + dyn_linking_function_t *result = nullptr; + for (auto &function: data->functions) { + dyn_linking_function_t *curEntry = &function; if (strlen(curEntry->functionName) == 0) { if (strlen(functionName) > DYN_LINK_FUNCTION_NAME_LENGTH) { DEBUG_FUNCTION_LINE("Failed to add function name, it's too long.\n"); - return NULL; + return nullptr; } strncpy(curEntry->functionName, functionName, DYN_LINK_FUNCTION_NAME_LENGTH); result = curEntry; @@ -41,16 +41,16 @@ dyn_linking_import_t *DynamicLinkingHelper::getOrAddDataImportByName(dyn_linking } dyn_linking_import_t *DynamicLinkingHelper::getOrAddImport(dyn_linking_relocation_data_t *data, const char *importName, bool isData) { - if (importName == NULL || data == NULL) { - return NULL; + if (importName == nullptr || data == nullptr) { + return nullptr; } - dyn_linking_import_t *result = NULL; - for (int32_t i = 0; i < DYN_LINK_IMPORT_LIST_LENGTH; i++) { - dyn_linking_import_t *curEntry = &(data->imports[i]); + dyn_linking_import_t *result = nullptr; + for (auto &import: data->imports) { + dyn_linking_import_t *curEntry = &import; if (strlen(curEntry->importName) == 0) { if (strlen(importName) > DYN_LINK_IMPORT_NAME_LENGTH) { DEBUG_FUNCTION_LINE("Failed to add Import, it's too long.\n"); - return NULL; + return nullptr; } strncpy(curEntry->importName, importName, DYN_LINK_IMPORT_NAME_LENGTH); curEntry->isData = isData; @@ -65,23 +65,23 @@ dyn_linking_import_t *DynamicLinkingHelper::getOrAddImport(dyn_linking_relocatio } bool DynamicLinkingHelper::addRelocationEntry(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()); + const std::shared_ptr &relocationData) { + 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, void *destination, - std::string name, const ImportRPLInformation &rplInfo) { - dyn_linking_import_t *importInfoGbl = DynamicLinkingHelper::getOrAddImport(linking_data, rplInfo.getName().c_str(), rplInfo.isData()); - if (importInfoGbl == NULL) { + const std::string &name, const std::shared_ptr &rplInfo) { + dyn_linking_import_t *importInfoGbl = DynamicLinkingHelper::getOrAddImport(linking_data, rplInfo->getName().c_str(), rplInfo->isData()); + if (importInfoGbl == nullptr) { DEBUG_FUNCTION_LINE("Getting import info failed. Probably maximum of %d rpl files to import reached.\n", DYN_LINK_IMPORT_LIST_LENGTH); return false; } dyn_linking_function_t *functionInfo = DynamicLinkingHelper::getOrAddFunctionEntryByName(linking_data, name.c_str()); - if (functionInfo == NULL) { + if (functionInfo == nullptr) { DEBUG_FUNCTION_LINE("Getting import info failed. Probably maximum of %d function to be relocated reached.\n", DYN_LINK_FUNCTION_LIST_LENGTH); return false; } @@ -95,7 +95,7 @@ bool DynamicLinkingHelper::addRelocationEntry(dyn_linking_relocation_entry_t *li dyn_linking_import_t *importInfo) { for (uint32_t i = 0; i < linking_entry_length; i++) { dyn_linking_relocation_entry_t *curEntry = &(linking_entries[i]); - if (curEntry->functionEntry != NULL) { + if (curEntry->functionEntry != nullptr) { continue; } curEntry->type = type; diff --git a/source/module/DynamicLinkingHelper.h b/source/module/DynamicLinkingHelper.h index 1ca1afd..3bd8b4f 100644 --- a/source/module/DynamicLinkingHelper.h +++ b/source/module/DynamicLinkingHelper.h @@ -47,11 +47,11 @@ public: **/ static dyn_linking_import_t *getOrAddImport(dyn_linking_relocation_data_t *data, const char *importName, bool isData); - static bool addRelocationEntry(dyn_linking_relocation_data_t *linking_data, dyn_linking_relocation_entry_t *linking_entries, uint32_t linking_entry_length, const RelocationData &relocationData); + static bool addRelocationEntry(dyn_linking_relocation_data_t *linking_data, dyn_linking_relocation_entry_t *linking_entries, uint32_t linking_entry_length, const std::shared_ptr &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, - void *destination, std::string name, - const ImportRPLInformation &rplInfo); + void *destination, const std::string& name, + const std::shared_ptr &rplInfo); static bool addRelocationEntry(dyn_linking_relocation_entry_t *linking_entries, uint32_t linking_entry_length, char type, size_t offset, int32_t addend, void *destination, diff --git a/source/module/ImportRPLInformation.h b/source/module/ImportRPLInformation.h index b75ce4f..49d1d54 100644 --- a/source/module/ImportRPLInformation.h +++ b/source/module/ImportRPLInformation.h @@ -19,19 +19,20 @@ #include #include +#include #include "utils/logger.h" class ImportRPLInformation { public: explicit ImportRPLInformation(std::string name, bool isData = false) { - this->name = name; + this->name = std::move(name); this->_isData = isData; } ~ImportRPLInformation() = default; - static std::optional createImportRPLInformation(std::string rawSectionName) { + static std::optional> createImportRPLInformation(std::string rawSectionName) { std::string fimport = ".fimport_"; std::string dimport = ".dimport_"; @@ -50,7 +51,7 @@ public: DEBUG_FUNCTION_LINE("invalid section name\n"); return std::nullopt; } - return ImportRPLInformation(rplName, data); + return std::make_shared(rplName, data); } [[nodiscard]] std::string getName() const { diff --git a/source/module/ModuleData.cpp b/source/module/ModuleData.cpp index bf648d4..11f252b 100644 --- a/source/module/ModuleData.cpp +++ b/source/module/ModuleData.cpp @@ -4,7 +4,7 @@ std::string ModuleData::toString() const { std::string res = StringTools::strfmt("Entrypoint %08X, bss: %08X (%d), bss: %08X (%d)\n", getEntrypoint(), getBSSAddr(), getBSSSize(), getSBSSAddr(), getSBSSSize()); for (auto const &reloc: relocation_data_list) { - res += reloc.toString(); + res += reloc->toString(); } return res; } diff --git a/source/module/ModuleData.h b/source/module/ModuleData.h index e1b9bc3..af3f941 100644 --- a/source/module/ModuleData.h +++ b/source/module/ModuleData.h @@ -27,6 +27,14 @@ #include "HookData.h" #include "FunctionSymbolData.h" +struct FunctionSymbolDataComparator { + bool operator()(const std::shared_ptr& lhs, + const std::shared_ptr& rhs) const + { + return (uint32_t) lhs->getAddress() < (uint32_t) rhs->getAddress(); + } +}; + class ModuleData { public: ModuleData() = default; @@ -55,47 +63,47 @@ public: this->endAddress = _endAddress; } - void addRelocationData(const RelocationData &relocation_data) { + void addRelocationData(const std::shared_ptr &relocation_data) { relocation_data_list.push_back(relocation_data); } - [[nodiscard]] const std::vector &getRelocationDataList() const { + [[nodiscard]] const std::vector> &getRelocationDataList() const { return relocation_data_list; } - void addExportData(const ExportData &data) { + void addExportData(const std::shared_ptr &data) { export_data_list.push_back(data); } - [[nodiscard]] const std::vector &getExportDataList() const { + [[nodiscard]] const std::vector> &getExportDataList() const { return export_data_list; } - void addHookData(const HookData &data) { + void addHookData(const std::shared_ptr &data) { hook_data_list.push_back(data); } - [[nodiscard]] const std::vector &getHookDataList() const { + [[nodiscard]] const std::vector> &getHookDataList() const { return hook_data_list; } - void addSectionInfo(const SectionInfo §ionInfo) { - section_info_list[sectionInfo.getName()] = sectionInfo; + void addSectionInfo(const std::shared_ptr §ionInfo) { + section_info_list[sectionInfo->getName()] = sectionInfo; } - void addFunctionSymbolData(const FunctionSymbolData &symbol_data) { + void addFunctionSymbolData(const std::shared_ptr &symbol_data) { symbol_data_list.insert(symbol_data); } - [[nodiscard]] const std::set &getFunctionSymbolDataList() const { + [[nodiscard]] const std::set, FunctionSymbolDataComparator> &getFunctionSymbolDataList() const { return symbol_data_list; } - [[nodiscard]] const std::map &getSectionInfoList() const { + [[nodiscard]] const std::map> &getSectionInfoList() const { return section_info_list; } - [[nodiscard]] std::optional getSectionInfo(const std::string §ionName) const { + [[nodiscard]] std::optional> getSectionInfo(const std::string §ionName) const { if (getSectionInfoList().count(sectionName) > 0) { return section_info_list.at(sectionName); } @@ -158,11 +166,11 @@ public: bool relocationsDone = false; private: - std::vector relocation_data_list; - std::vector export_data_list; - std::vector hook_data_list; - std::set symbol_data_list; - std::map section_info_list; + std::vector> relocation_data_list; + std::vector> export_data_list; + std::vector> hook_data_list; + std::set, FunctionSymbolDataComparator> symbol_data_list; + std::map> section_info_list; std::string export_name; diff --git a/source/module/ModuleDataFactory.cpp b/source/module/ModuleDataFactory.cpp index 7da5868..a1c8285 100644 --- a/source/module/ModuleDataFactory.cpp +++ b/source/module/ModuleDataFactory.cpp @@ -27,10 +27,10 @@ using namespace ELFIO; -std::optional +std::optional> ModuleDataFactory::load(const std::string &path, uint32_t *destination_address_ptr, uint32_t maximum_size, relocation_trampolin_entry_t *trampolin_data, uint32_t trampolin_data_length) { elfio reader; - ModuleData moduleData; + std::shared_ptr moduleData = std::make_shared(); // Load ELF data if (!reader.load(path)) { @@ -101,14 +101,14 @@ ModuleDataFactory::load(const std::string &path, uint32_t *destination_address_p //nextAddress = ROUNDUP(destination + sectionSize, 0x100); if (psec->get_name() == ".bss") { - moduleData.setBSSLocation(destination, sectionSize); + moduleData->setBSSLocation(destination, sectionSize); memset(reinterpret_cast(destination), 0, sectionSize); } else if (psec->get_name() == ".sbss") { - moduleData.setSBSSLocation(destination, sectionSize); + moduleData->setSBSSLocation(destination, sectionSize); memset(reinterpret_cast(destination), 0, sectionSize); } - - moduleData.addSectionInfo(SectionInfo(psec->get_name(), destination, sectionSize)); + auto sectionInfo = std::make_shared(psec->get_name(), destination, sectionSize); + moduleData->addSectionInfo(sectionInfo); DEBUG_FUNCTION_LINE("Saved %s section info. Location: %08X size: %08X", psec->get_name().c_str(), destination, sectionSize); if (endAddress < destination + sectionSize) { @@ -131,47 +131,47 @@ ModuleDataFactory::load(const std::string &path, uint32_t *destination_address_p } } } - std::vector relocationData = getImportRelocationData(reader, destinations); + auto relocationData = getImportRelocationData(reader, destinations); for (auto const &reloc: relocationData) { - moduleData.addRelocationData(reloc); + moduleData->addRelocationData(reloc); } - std::optional secInfo = moduleData.getSectionInfo(".wums.exports"); - if (secInfo && secInfo->getSize() > 0) { - size_t entries_count = secInfo->getSize() / sizeof(wums_entry_t); - auto *entries = (wums_entry_t *) secInfo->getAddress(); + auto secInfo = moduleData->getSectionInfo(".wums.exports"); + if (secInfo && secInfo.value()->getSize() > 0) { + size_t entries_count = secInfo.value()->getSize() / sizeof(wums_entry_t); + auto *entries = (wums_entry_t *) secInfo.value()->getAddress(); if (entries != nullptr) { for (size_t j = 0; j < entries_count; j++) { wums_entry_t *exp = &entries[j]; DEBUG_FUNCTION_LINE("Saving export of type %08X, name %s, target: %08X"/*,pluginData.getPluginInformation()->getName().c_str()*/, exp->type, exp->name, (void *) exp->address); - ExportData export_data(exp->type, exp->name, exp->address); - moduleData.addExportData(export_data); + auto exportData = std::make_shared(exp->type, exp->name, exp->address); + moduleData->addExportData(exportData); } } } - secInfo = moduleData.getSectionInfo(".wums.hooks"); - if (secInfo && secInfo->getSize() > 0) { - size_t entries_count = secInfo->getSize() / sizeof(wums_hook_t); - auto *hooks = (wums_hook_t *) secInfo->getAddress(); + secInfo = moduleData->getSectionInfo(".wums.hooks"); + if (secInfo && secInfo.value()->getSize() > 0) { + size_t entries_count = secInfo.value()->getSize() / sizeof(wums_hook_t); + auto *hooks = (wums_hook_t *) secInfo.value()->getAddress(); if (hooks != nullptr) { 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); + auto hookData = std::make_shared(hook->type, hook->target); + moduleData->addHookData(hookData); } } } - secInfo = moduleData.getSectionInfo(".wums.meta"); - if (secInfo && secInfo->getSize() > 0) { - auto *entries = (wums_entry_t *) secInfo->getAddress(); + secInfo = moduleData->getSectionInfo(".wums.meta"); + if (secInfo && secInfo.value()->getSize() > 0) { + auto *entries = (wums_entry_t *) secInfo.value()->getAddress(); if (entries != nullptr) { - char *curEntry = (char *) secInfo->getAddress(); - while ((uint32_t) curEntry < (uint32_t) secInfo->getAddress() + secInfo->getSize()) { + char *curEntry = (char *) secInfo.value()->getAddress(); + while ((uint32_t) curEntry < (uint32_t) secInfo.value()->getAddress() + secInfo.value()->getSize()) { if (*curEntry == '\0') { curEntry++; continue; @@ -185,20 +185,20 @@ ModuleDataFactory::load(const std::string &path, uint32_t *destination_address_p if (key == "export_name") { DEBUG_FUNCTION_LINE("export_name = %s", value.c_str()); - moduleData.setExportName(value); + moduleData->setExportName(value); } else if (key == "skipEntrypoint") { if (value == "true") { DEBUG_FUNCTION_LINE("skipEntrypoint = %s", value.c_str()); - moduleData.setSkipEntrypoint(true); + moduleData->setSkipEntrypoint(true); } else { - moduleData.setSkipEntrypoint(false); + moduleData->setSkipEntrypoint(false); } } else if (key == "initBeforeRelocationDoneHook") { if (value == "true") { DEBUG_FUNCTION_LINE("initBeforeRelocationDoneHook = %s", value.c_str()); - moduleData.setInitBeforeRelocationDoneHook(true); + moduleData->setInitBeforeRelocationDoneHook(true); } else { - moduleData.setInitBeforeRelocationDoneHook(false); + moduleData->setInitBeforeRelocationDoneHook(false); } } else if (key == "wums") { if (value != "0.3") { @@ -235,15 +235,15 @@ ModuleDataFactory::load(const std::string &path, uint32_t *destination_address_p if (type == STT_FUNC) { // We only care about functions. auto sectionVal = reader.sections[section]; auto offsetVal = value - sectionVal->get_address(); - auto sectionOpt = moduleData.getSectionInfo(sectionVal->get_name()); + auto sectionOpt = moduleData->getSectionInfo(sectionVal->get_name()); if (!sectionOpt.has_value()) { continue; } - auto finalAddress = offsetVal + sectionOpt->getAddress(); + auto finalAddress = offsetVal + sectionOpt.value()->getAddress(); uint32_t stringSize = name.size() + 1; memcpy(strTable + strOffset, name.c_str(), stringSize); - moduleData.addFunctionSymbolData(FunctionSymbolData(strTable + strOffset, (void *) finalAddress, (uint32_t) size)); + moduleData->addFunctionSymbolData(std::make_shared(strTable + strOffset, (void *) finalAddress, (uint32_t) size)); strOffset += stringSize; totalSize += stringSize; endAddress += stringSize; @@ -260,9 +260,9 @@ ModuleDataFactory::load(const std::string &path, uint32_t *destination_address_p free(destinations); - moduleData.setEntrypoint(entrypoint); - moduleData.setStartAddress(*destination_address_ptr); - moduleData.setEndAddress(endAddress); + moduleData->setEntrypoint(entrypoint); + moduleData->setStartAddress(*destination_address_ptr); + moduleData->setEndAddress(endAddress); DEBUG_FUNCTION_LINE("Saved entrypoint as %08X", entrypoint); DEBUG_FUNCTION_LINE("Saved startAddress as %08X", *destination_address_ptr); DEBUG_FUNCTION_LINE("Saved endAddress as %08X", endAddress); @@ -272,8 +272,8 @@ ModuleDataFactory::load(const std::string &path, uint32_t *destination_address_p return moduleData; } -std::vector ModuleDataFactory::getImportRelocationData(elfio &reader, uint8_t **destinations) { - std::vector result; +std::vector> ModuleDataFactory::getImportRelocationData(elfio &reader, uint8_t **destinations) { + std::vector> result; std::map infoMap; uint32_t sec_num = reader.sections.size(); @@ -307,7 +307,7 @@ std::vector ModuleDataFactory::getImportRelocationData(elfio &re if (infoMap.count(sym_section_index) == 0) { continue; } - std::optional rplInfo = ImportRPLInformation::createImportRPLInformation(infoMap[sym_section_index]); + auto rplInfo = ImportRPLInformation::createImportRPLInformation(infoMap[sym_section_index]); if (!rplInfo) { DEBUG_FUNCTION_LINE("Failed to create import information"); break; @@ -316,7 +316,7 @@ std::vector ModuleDataFactory::getImportRelocationData(elfio &re uint32_t section_index = psec->get_info(); // When these relocations are performed, we don't need the 0xC0000000 offset anymore. - RelocationData relocationData(type, offset - 0x02000000, addend, (void *) (destinations[section_index] + 0x02000000), sym_name, rplInfo.value()); + auto relocationData = std::make_shared(type, offset - 0x02000000, addend, (void *) (destinations[section_index] + 0x02000000), sym_name, rplInfo.value()); //relocationData->printInformation(); result.push_back(relocationData); } diff --git a/source/module/ModuleDataFactory.h b/source/module/ModuleDataFactory.h index 206a55b..d0a48ae 100644 --- a/source/module/ModuleDataFactory.h +++ b/source/module/ModuleDataFactory.h @@ -26,11 +26,11 @@ class ModuleDataFactory { public: - static std::optional + static std::optional> load(const std::string &path, uint32_t *destination_address_ptr, uint32_t maximum_size, relocation_trampolin_entry_t *trampolin_data, uint32_t trampolin_data_length); static bool linkSection(ELFIO::elfio &reader, 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); - static std::vector getImportRelocationData(ELFIO::elfio &reader, uint8_t **destinations); + static std::vector> getImportRelocationData(ELFIO::elfio &reader, uint8_t **destinations); }; diff --git a/source/module/ModuleDataPersistence.cpp b/source/module/ModuleDataPersistence.cpp index 577e902..d4ec391 100644 --- a/source/module/ModuleDataPersistence.cpp +++ b/source/module/ModuleDataPersistence.cpp @@ -1,9 +1,8 @@ #include - #include "ModuleDataPersistence.h" #include "DynamicLinkingHelper.h" -bool ModuleDataPersistence::saveModuleData(module_information_t *moduleInformation, const ModuleData &module) { +bool ModuleDataPersistence::saveModuleData(module_information_t *moduleInformation, const std::shared_ptr &module) { int32_t module_count = moduleInformation->number_used_modules; if (module_count >= MAXIMUM_MODULES) { @@ -13,9 +12,9 @@ bool ModuleDataPersistence::saveModuleData(module_information_t *moduleInformati // Copy data to global struct. module_information_single_t *module_data = &(moduleInformation->module_data[module_count]); - DEBUG_FUNCTION_LINE("Saving relocation data for module at %08X", module.getEntrypoint()); + DEBUG_FUNCTION_LINE("Saving relocation data for module at %08X", module->getEntrypoint()); // Relocation - std::vector relocationData = module.getRelocationDataList(); + auto relocationData = module->getRelocationDataList(); for (auto const &reloc: relocationData) { if (!DynamicLinkingHelper::addRelocationEntry(&(moduleInformation->linking_data), module_data->linking_entries, DYN_LINK_RELOCATION_LIST_LENGTH, reloc)) { @@ -24,15 +23,15 @@ bool ModuleDataPersistence::saveModuleData(module_information_t *moduleInformati } } - std::vector exportData = module.getExportDataList(); + auto exportData = module->getExportDataList(); for (auto const &curExport: exportData) { bool found = false; for (auto &export_entry: module_data->export_entries) { if (export_entry.address == 0) { - export_entry.type = curExport.getType(); + export_entry.type = curExport->getType(); export_entry.name[0] = '\0'; - strncat(export_entry.name, curExport.getName().c_str(), sizeof(export_entry.name) - 1); - export_entry.address = (uint32_t) curExport.getAddress(); + strncat(export_entry.name, curExport->getName().c_str(), sizeof(export_entry.name) - 1); + export_entry.address = (uint32_t) curExport->getAddress(); found = true; break; } @@ -43,13 +42,13 @@ bool ModuleDataPersistence::saveModuleData(module_information_t *moduleInformati } } - std::vector hookData = module.getHookDataList(); + auto hookData = module->getHookDataList(); for (auto const &curHook: hookData) { bool found = false; for (auto &hook_entry: module_data->hook_entries) { if (hook_entry.target == 0) { - hook_entry.type = curHook.getType(); - hook_entry.target = (uint32_t) curHook.getTarget(); + hook_entry.type = curHook->getType(); + hook_entry.target = (uint32_t) curHook->getTarget(); found = true; break; } @@ -60,22 +59,22 @@ bool ModuleDataPersistence::saveModuleData(module_information_t *moduleInformati } } - strncpy(module_data->module_export_name, module.getExportName().c_str(), MAXIMUM_EXPORT_MODULE_NAME_LENGTH); + strncpy(module_data->module_export_name, module->getExportName().c_str(), MAXIMUM_EXPORT_MODULE_NAME_LENGTH); - uint32_t entryCount = module.getFunctionSymbolDataList().size(); + uint32_t entryCount = module->getFunctionSymbolDataList().size(); if (entryCount > 0) { auto ptr = &moduleInformation->function_symbols[moduleInformation->number_used_function_symbols]; module_data->function_symbol_entries = ptr; uint32_t sym_offset = 0; - for (auto &curFuncSym: module.getFunctionSymbolDataList()) { + for (auto &curFuncSym: module->getFunctionSymbolDataList()) { if (moduleInformation->number_used_function_symbols >= FUNCTION_SYMBOL_LIST_LENGTH) { DEBUG_FUNCTION_LINE("Function symbol list is full"); break; } - module_data->function_symbol_entries[sym_offset].address = curFuncSym.getAddress(); - module_data->function_symbol_entries[sym_offset].name = (char *) curFuncSym.getName(); - module_data->function_symbol_entries[sym_offset].size = curFuncSym.getSize(); + module_data->function_symbol_entries[sym_offset].address = curFuncSym->getAddress(); + module_data->function_symbol_entries[sym_offset].name = (char *) curFuncSym->getName(); + module_data->function_symbol_entries[sym_offset].size = curFuncSym->getSize(); sym_offset++; moduleInformation->number_used_function_symbols++; @@ -86,15 +85,15 @@ bool ModuleDataPersistence::saveModuleData(module_information_t *moduleInformati module_data->number_used_function_symbols = 0; } - module_data->bssAddr = module.getBSSAddr(); - module_data->bssSize = module.getBSSSize(); - module_data->sbssAddr = module.getSBSSAddr(); - module_data->sbssSize = module.getSBSSSize(); - module_data->startAddress = module.getStartAddress(); - module_data->endAddress = module.getEndAddress(); - module_data->entrypoint = module.getEntrypoint(); - module_data->skipEntrypoint = module.isSkipEntrypoint(); - module_data->initBeforeRelocationDoneHook = module.isInitBeforeRelocationDoneHook(); + module_data->bssAddr = module->getBSSAddr(); + module_data->bssSize = module->getBSSSize(); + module_data->sbssAddr = module->getSBSSAddr(); + module_data->sbssSize = module->getSBSSSize(); + module_data->startAddress = module->getStartAddress(); + module_data->endAddress = module->getEndAddress(); + module_data->entrypoint = module->getEntrypoint(); + module_data->skipEntrypoint = module->isSkipEntrypoint(); + module_data->initBeforeRelocationDoneHook = module->isInitBeforeRelocationDoneHook(); moduleInformation->number_used_modules++; @@ -104,8 +103,8 @@ bool ModuleDataPersistence::saveModuleData(module_information_t *moduleInformati return true; } -std::vector ModuleDataPersistence::loadModuleData(module_information_t *moduleInformation) { - std::vector result; +std::vector> ModuleDataPersistence::loadModuleData(module_information_t *moduleInformation) { + std::vector> result; if (moduleInformation == nullptr) { DEBUG_FUNCTION_LINE("moduleInformation == NULL\n"); return result; @@ -121,29 +120,31 @@ std::vector ModuleDataPersistence::loadModuleData(module_information for (int32_t i = 0; i < module_count; i++) { // Copy data from struct. module_information_single_t *module_data = &(moduleInformation->module_data[i]); - ModuleData moduleData; - moduleData.setBSSLocation(module_data->bssAddr, module_data->bssSize); - moduleData.setSBSSLocation(module_data->sbssAddr, module_data->sbssSize); - moduleData.setEntrypoint(module_data->entrypoint); - moduleData.setStartAddress(module_data->startAddress); - moduleData.setEndAddress(module_data->endAddress); - moduleData.setExportName(module_data->module_export_name); - moduleData.setSkipEntrypoint(module_data->skipEntrypoint); - moduleData.setInitBeforeRelocationDoneHook(module_data->initBeforeRelocationDoneHook); + auto moduleData = std::make_shared(); + moduleData->setBSSLocation(module_data->bssAddr, module_data->bssSize); + moduleData->setSBSSLocation(module_data->sbssAddr, module_data->sbssSize); + moduleData->setEntrypoint(module_data->entrypoint); + moduleData->setStartAddress(module_data->startAddress); + moduleData->setEndAddress(module_data->endAddress); + moduleData->setExportName(module_data->module_export_name); + moduleData->setSkipEntrypoint(module_data->skipEntrypoint); + moduleData->setInitBeforeRelocationDoneHook(module_data->initBeforeRelocationDoneHook); for (auto &export_entrie: module_data->export_entries) { export_data_t *export_entry = &export_entrie; if (export_entry->address == 0) { continue; } - moduleData.addExportData(ExportData(static_cast(export_entry->type), export_entry->name, reinterpret_cast(export_entry->address))); + auto exportData = std::make_shared(static_cast(export_entry->type), export_entry->name, reinterpret_cast(export_entry->address)); + moduleData->addExportData(exportData); } for (auto &hook_entry: module_data->hook_entries) { if (hook_entry.target == 0) { continue; } - moduleData.addHookData(HookData(static_cast(hook_entry.type), reinterpret_cast(hook_entry.target))); + auto hookData = std::make_shared(static_cast(hook_entry.type), reinterpret_cast(hook_entry.target)); + moduleData->addHookData(hookData); } for (auto &linking_entry: module_data->linking_entries) { @@ -161,16 +162,17 @@ std::vector ModuleDataPersistence::loadModuleData(module_information DEBUG_FUNCTION_LINE("functionEntry was NULL, skipping relocation entry\n"); continue; } - ImportRPLInformation rplInfo(importEntry->importName, importEntry->isData); - RelocationData reloc(linking_entry.type, linking_entry.offset, linking_entry.addend, linking_entry.destination, functionEntry->functionName, rplInfo); + auto rplInfo = std::make_shared(importEntry->importName, importEntry->isData); + auto reloc = std::make_shared(linking_entry.type, linking_entry.offset, linking_entry.addend, linking_entry.destination, functionEntry->functionName, rplInfo); - moduleData.addRelocationData(reloc); + moduleData->addRelocationData(reloc); } if (module_data->function_symbol_entries != nullptr && module_data->number_used_function_symbols > 0) { for (uint32_t j = 0; j < module_data->number_used_function_symbols; j++) { auto symbol = &module_data->function_symbol_entries[j]; - moduleData.addFunctionSymbolData(FunctionSymbolData(symbol->name, symbol->address, symbol->size)); + auto functionSymbolData = std::make_shared(symbol->name, symbol->address, symbol->size); + moduleData->addFunctionSymbolData(functionSymbolData); } } result.push_back(moduleData); diff --git a/source/module/ModuleDataPersistence.h b/source/module/ModuleDataPersistence.h index 85959c7..ef830d8 100644 --- a/source/module/ModuleDataPersistence.h +++ b/source/module/ModuleDataPersistence.h @@ -5,7 +5,7 @@ class ModuleDataPersistence { public: - static bool saveModuleData(module_information_t *moduleInformation, const ModuleData &module); + static bool saveModuleData(module_information_t *moduleInformation, const std::shared_ptr &module); - static std::vector loadModuleData(module_information_t *moduleInformation); + static std::vector> loadModuleData(module_information_t *moduleInformation); }; diff --git a/source/module/RelocationData.cpp b/source/module/RelocationData.cpp index ce7b008..5d91c68 100644 --- a/source/module/RelocationData.cpp +++ b/source/module/RelocationData.cpp @@ -2,6 +2,6 @@ #include "utils/StringTools.h" std::string RelocationData::toString() const { - return StringTools::strfmt("%s destination: %08X offset: %08X type: %02X addend: %d rplName: %s isData: %d \n", name.c_str(), destination, offset, type, addend, rplInfo.getName().c_str(), - rplInfo.isData()); + return StringTools::strfmt("%s destination: %08X offset: %08X type: %02X addend: %d rplName: %s isData: %d \n", name.c_str(), destination, offset, type, addend, rplInfo->getName().c_str(), + rplInfo->isData()); } diff --git a/source/module/RelocationData.h b/source/module/RelocationData.h index d062e2a..cbf4b8c 100644 --- a/source/module/RelocationData.h +++ b/source/module/RelocationData.h @@ -18,17 +18,19 @@ #pragma once #include +#include +#include #include "ImportRPLInformation.h" class RelocationData { public: - RelocationData(char type, size_t offset, int32_t addend, void *destination, std::string name, const ImportRPLInformation &rplInfo) : rplInfo(rplInfo) { + RelocationData(char type, size_t offset, int32_t addend, void *destination, std::string name, std::shared_ptr rplInfo) : rplInfo(std::move(rplInfo)) { this->type = type; this->offset = offset; this->addend = addend; this->destination = destination; - this->name = name; + this->name = std::move(name); } ~RelocationData() = default; @@ -53,7 +55,7 @@ public: return name; } - [[nodiscard]] ImportRPLInformation getImportRPLInformation() const { + [[nodiscard]] std::shared_ptr getImportRPLInformation() const { return rplInfo; } @@ -65,5 +67,5 @@ private: int32_t addend; void *destination; std::string name; - const ImportRPLInformation rplInfo; + const std::shared_ptr rplInfo; };