From 09d6b9f756a31bccd97ca001cbe5892d9c5cdffa Mon Sep 17 00:00:00 2001 From: Maschell Date: Sun, 23 Aug 2020 13:06:32 +0200 Subject: [PATCH] Allocate objects on stack instead of heap --- src/main.cpp | 22 +++++++-------- src/module/ImportRPLInformation.h | 17 +++++------ src/module/ModuleData.cpp | 8 ++---- src/module/ModuleData.h | 25 +++++++--------- src/module/ModuleDataFactory.cpp | 47 +++++++++++++------------------ src/module/ModuleDataFactory.h | 6 ++-- src/module/RelocationData.cpp | 4 +-- src/module/RelocationData.h | 22 ++++++--------- 8 files changed, 66 insertions(+), 85 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 9559e44..619d954 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -35,10 +35,9 @@ #include "dynamic.h" #include "utils/logger.h" -bool doRelocation(std::vector &relocData, relocation_trampolin_entry_t *tramp_data, uint32_t tramp_length); +bool doRelocation(const std::vector &relocData, relocation_trampolin_entry_t *tramp_data, uint32_t tramp_length); bool CheckRunning() { - switch (ProcUIProcessMessages(true)) { case PROCUI_STATUS_EXITING: { return false; @@ -82,10 +81,10 @@ extern "C" int _start(int argc, char **argv) { uint32_t moduleDataStartAddress = ((uint32_t) gModuleData + sizeof(module_information_t)); moduleDataStartAddress = (moduleDataStartAddress + 0x10000) & 0xFFFF0000; - ModuleData *moduleData = ModuleDataFactory::load("fs:/vol/external01/wiiu/payload.rpx", 0x00FFF000, 0x00FFF000 - ApplicationMemoryEnd, gModuleData->trampolines, DYN_LINK_TRAMPOLIN_LIST_LENGTH); - if (moduleData != NULL) { + std::optional moduleData = ModuleDataFactory::load("fs:/vol/external01/wiiu/payload.rpx", 0x00FFF000, 0x00FFF000 - ApplicationMemoryEnd - (sizeof(module_information_t)), gModuleData->trampolines, DYN_LINK_TRAMPOLIN_LIST_LENGTH); + if (!moduleData) { DEBUG_FUNCTION_LINE("Loaded module data"); - std::vector relocData = moduleData->getRelocationDataList(); + std::vector relocData = moduleData->getRelocationDataList(); if (!doRelocation(relocData, gModuleData->trampolines, DYN_LINK_TRAMPOLIN_LIST_LENGTH)) { DEBUG_FUNCTION_LINE("relocations failed"); } @@ -101,7 +100,6 @@ extern "C" int _start(int argc, char **argv) { ICInvalidateRange((void *) 0x00800000, 0x00800000); DEBUG_FUNCTION_LINE("New entrypoint: %08X", moduleData->getEntrypoint()); ((int (*)(int, char **)) moduleData->getEntrypoint())(argc, argv); - delete moduleData; } else { DEBUG_FUNCTION_LINE("Failed to load module"); } @@ -120,12 +118,12 @@ extern "C" int _start(int argc, char **argv) { return 0; } -bool doRelocation(std::vector &relocData, relocation_trampolin_entry_t *tramp_data, uint32_t tramp_length) { +bool doRelocation(const std::vector &relocData, relocation_trampolin_entry_t *tramp_data, uint32_t tramp_length) { for (auto const &curReloc : relocData) { - RelocationData *cur = curReloc; - std::string functionName = cur->getName(); - std::string rplName = cur->getImportRPLInformation()->getName(); - int32_t isData = cur->getImportRPLInformation()->isData(); + RelocationData cur = curReloc; + std::string functionName = cur.getName(); + std::string rplName = cur.getImportRPLInformation().getName(); + int32_t isData = cur.getImportRPLInformation().isData(); OSDynLoad_Module rplHandle = 0; OSDynLoad_Acquire(rplName.c_str(), &rplHandle); @@ -134,7 +132,7 @@ bool doRelocation(std::vector &relocData, relocation_trampolin if (functionAddress == 0) { return false; } - if (!ElfUtils::elfLinkOne(cur->getType(), cur->getOffset(), cur->getAddend(), (uint32_t) cur->getDestination(), functionAddress, tramp_data, tramp_length, RELOC_TYPE_IMPORT)) { + if (!ElfUtils::elfLinkOne(cur.getType(), cur.getOffset(), cur.getAddend(), (uint32_t) cur.getDestination(), functionAddress, tramp_data, tramp_length, RELOC_TYPE_IMPORT)) { DEBUG_FUNCTION_LINE("Relocation failed"); return false; } diff --git a/src/module/ImportRPLInformation.h b/src/module/ImportRPLInformation.h index 97733b2..152087f 100644 --- a/src/module/ImportRPLInformation.h +++ b/src/module/ImportRPLInformation.h @@ -18,6 +18,7 @@ #pragma once #include +#include #include "utils/logger.h" class ImportRPLInformation { @@ -31,7 +32,7 @@ public: ~ImportRPLInformation() { } - static ImportRPLInformation *createImportRPLInformation(std::string rawSectionName) { + static std::optional createImportRPLInformation(std::string rawSectionName) { std::string fimport = ".fimport_"; std::string dimport = ".dimport_"; @@ -40,28 +41,28 @@ public: std::string rplName = ""; if (rawSectionName.size() < fimport.size()) { - return NULL; + return {}; } else if (std::equal(fimport.begin(), fimport.end(), rawSectionName.begin())) { rplName = rawSectionName.substr(fimport.size()); } else if (std::equal(dimport.begin(), dimport.end(), rawSectionName.begin())) { rplName = rawSectionName.substr(dimport.size()); data = true; } else { - DEBUG_FUNCTION_LINE("invalid section name"); - return NULL; + DEBUG_FUNCTION_LINE("invalid section name\n"); + return {}; } - return new ImportRPLInformation(rplName, data); + return ImportRPLInformation(rplName, data); } - std::string getName() { + std::string getName() const { return name; } - bool isData() { + bool isData() const { return _isData; } private: std::string name; bool _isData = false; -}; +}; \ No newline at end of file diff --git a/src/module/ModuleData.cpp b/src/module/ModuleData.cpp index 60fcdcd..78bba7a 100644 --- a/src/module/ModuleData.cpp +++ b/src/module/ModuleData.cpp @@ -18,12 +18,10 @@ #include "ModuleData.h" #include "utils/StringTools.h" -std::string ModuleData::toString() { +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) { - if (reloc != NULL) { - res += reloc->toString(); - } + res += reloc.toString(); } return res; -} +} \ No newline at end of file diff --git a/src/module/ModuleData.h b/src/module/ModuleData.h index 7ca5f38..b726f55 100644 --- a/src/module/ModuleData.h +++ b/src/module/ModuleData.h @@ -27,11 +27,6 @@ public: } ~ModuleData() { - for (auto const &reloc : relocation_data_list) { - if (reloc != NULL) { - delete reloc; - } - } } void setBSSLocation(uint32_t addr, uint32_t size) { @@ -48,42 +43,42 @@ public: this->entrypoint = addr; } - void addRelocationData(RelocationData *relocation_data) { + void addRelocationData(const RelocationData &relocation_data) { relocation_data_list.push_back(relocation_data); } - std::vector getRelocationDataList() { + const std::vector &getRelocationDataList() const { return relocation_data_list; } - uint32_t getBSSAddr() { + uint32_t getBSSAddr() const { return bssAddr; } - uint32_t getBSSSize() { + uint32_t getBSSSize() const { return bssSize; } - uint32_t getSBSSAddr() { + uint32_t getSBSSAddr() const { return sbssAddr; } - uint32_t getSBSSSize() { + uint32_t getSBSSSize() const { return sbssSize; } - uint32_t getEntrypoint() { + uint32_t getEntrypoint() const { return entrypoint; } - std::string toString(); + std::string toString() const; private: - std::vector relocation_data_list; + std::vector relocation_data_list; uint32_t bssAddr = 0; uint32_t bssSize = 0; uint32_t sbssAddr = 0; uint32_t sbssSize = 0; uint32_t entrypoint = 0; -}; +}; \ No newline at end of file diff --git a/src/module/ModuleDataFactory.cpp b/src/module/ModuleDataFactory.cpp index edb0a6f..cbd02fd 100644 --- a/src/module/ModuleDataFactory.cpp +++ b/src/module/ModuleDataFactory.cpp @@ -25,25 +25,20 @@ using namespace ELFIO; -ModuleData *ModuleDataFactory::load(std::string path, uint32_t destination_address, uint32_t maximum_size, relocation_trampolin_entry_t *trampolin_data, uint32_t trampolin_data_length) { +std::optional ModuleDataFactory::load(const std::string &path, uint32_t destination_address, uint32_t maximum_size, relocation_trampolin_entry_t *trampolin_data, uint32_t trampolin_data_length) { elfio reader; - ModuleData *moduleData = new ModuleData(); - if (moduleData == NULL) { - return NULL; - } + ModuleData moduleData; // Load ELF data if (!reader.load(path)) { - DEBUG_FUNCTION_LINE("Can't find or process ELF file"); - delete moduleData; - return NULL; + DEBUG_FUNCTION_LINE("Can't find or process %s", path.c_str()); + return {}; } uint32_t sec_num = reader.sections.size(); uint8_t **destinations = (uint8_t **) malloc(sizeof(uint8_t *) * sec_num); - uint32_t sizeOfModule = 0; for (uint32_t i = 0; i < sec_num; ++i) { section *psec = reader.sections[i]; @@ -58,7 +53,7 @@ ModuleData *ModuleDataFactory::load(std::string path, uint32_t destination_addre if (sizeOfModule > maximum_size) { DEBUG_FUNCTION_LINE("Module is too big."); - return NULL; + return {}; } uint32_t baseOffset = (destination_address - sizeOfModule) & 0xFFFFFF00; @@ -97,8 +92,7 @@ ModuleData *ModuleDataFactory::load(std::string path, uint32_t destination_addre } else { DEBUG_FUNCTION_LINE("Unhandled case"); free(destinations); - delete moduleData; - return NULL; + return {}; } const char *p = reader.sections[i]->get_data(); @@ -113,10 +107,10 @@ ModuleData *ModuleDataFactory::load(std::string path, uint32_t destination_addre //nextAddress = ROUNDUP(destination + sectionSize,0x100); if (psec->get_name().compare(".bss") == 0) { - moduleData->setBSSLocation(destination, sectionSize); + moduleData.setBSSLocation(destination, sectionSize); DEBUG_FUNCTION_LINE("Saved %s section info. Location: %08X size: %08X", psec->get_name().c_str(), destination, sectionSize); } else if (psec->get_name().compare(".sbss") == 0) { - moduleData->setSBSSLocation(destination, sectionSize); + moduleData.setSBSSLocation(destination, sectionSize); DEBUG_FUNCTION_LINE("Saved %s section info. Location: %08X size: %08X", psec->get_name().c_str(), destination, sectionSize); } totalSize += sectionSize; @@ -133,31 +127,30 @@ ModuleData *ModuleDataFactory::load(std::string path, uint32_t destination_addre if (!linkSection(reader, psec->get_index(), (uint32_t) destinations[psec->get_index()], offset_text, offset_data, trampolin_data, trampolin_data_length)) { DEBUG_FUNCTION_LINE("elfLink failed"); free(destinations); - delete moduleData; - return NULL; + return {}; } } } - std::vector relocationData = getImportRelocationData(reader, destinations); + std::vector relocationData = getImportRelocationData(reader, destinations); for (auto const &reloc : relocationData) { - moduleData->addRelocationData(reloc); + moduleData.addRelocationData(reloc); } - DCFlushRange((void *) destination_address, totalSize); - ICInvalidateRange((void *) destination_address, totalSize); + DCFlushRange((void *) baseOffset, totalSize); + ICInvalidateRange((void *) baseOffset, totalSize); free(destinations); - moduleData->setEntrypoint(entrypoint); + moduleData.setEntrypoint(entrypoint); DEBUG_FUNCTION_LINE("Saved entrypoint as %08X", entrypoint); return moduleData; } -std::vector ModuleDataFactory::getImportRelocationData(elfio &reader, uint8_t **destinations) { - std::vector result; +std::vector ModuleDataFactory::getImportRelocationData(const elfio &reader, uint8_t **destinations) { + std::vector result; std::map infoMap; uint32_t sec_num = reader.sections.size(); @@ -191,8 +184,8 @@ std::vector ModuleDataFactory::getImportRelocationData(elfio & if (adjusted_sym_value < 0xC0000000) { continue; } - ImportRPLInformation *rplInfo = ImportRPLInformation::createImportRPLInformation(infoMap[sym_section_index]); - if (rplInfo == NULL) { + std::optional rplInfo = ImportRPLInformation::createImportRPLInformation(infoMap[sym_section_index]); + if (!rplInfo) { DEBUG_FUNCTION_LINE("Failed to create import information"); break; } @@ -200,7 +193,7 @@ std::vector ModuleDataFactory::getImportRelocationData(elfio & uint32_t section_index = psec->get_info(); // When these relocations are performed, we don't need the 0xC0000000 offset anymore. - RelocationData *relocationData = new RelocationData(type, offset - 0x02000000, addend, (void *) (destinations[section_index] + 0x02000000), sym_name, rplInfo); + RelocationData relocationData(type, offset - 0x02000000, addend, (void *) (destinations[section_index] + 0x02000000), sym_name, rplInfo.value()); //relocationData->printInformation(); result.push_back(relocationData); } @@ -209,7 +202,7 @@ std::vector ModuleDataFactory::getImportRelocationData(elfio & return result; } -bool ModuleDataFactory::linkSection(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) { +bool ModuleDataFactory::linkSection(const 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) { uint32_t sec_num = reader.sections.size(); for (uint32_t i = 0; i < sec_num; ++i) { diff --git a/src/module/ModuleDataFactory.h b/src/module/ModuleDataFactory.h index 55edb5f..4d758ba 100644 --- a/src/module/ModuleDataFactory.h +++ b/src/module/ModuleDataFactory.h @@ -26,9 +26,9 @@ class ModuleDataFactory { public: - static ModuleData *load(std::string path, uint32_t destination_address, uint32_t maximum_size, relocation_trampolin_entry_t *trampolin_data, uint32_t trampolin_data_length); + static std::optional load(const std::string &path, uint32_t destination_address, 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 bool linkSection(const 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(const ELFIO::elfio &reader, uint8_t **destinations); }; diff --git a/src/module/RelocationData.cpp b/src/module/RelocationData.cpp index b7425d7..be713fb 100644 --- a/src/module/RelocationData.cpp +++ b/src/module/RelocationData.cpp @@ -18,6 +18,6 @@ #include "RelocationData.h" #include "utils/StringTools.h" -std::string RelocationData::toString() { - return StringTools::strfmt("%s destination: %08X offset: %08X type: %02X addend: %d rplName: %s isData: %d", name.c_str(), destination, offset, type, addend, rplInfo->getName().c_str(), rplInfo->isData()); +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()); } diff --git a/src/module/RelocationData.h b/src/module/RelocationData.h index 25e3bdf..bef1d79 100644 --- a/src/module/RelocationData.h +++ b/src/module/RelocationData.h @@ -23,46 +23,42 @@ class RelocationData { public: - RelocationData(char type, size_t offset, int32_t addend, void *destination, std::string name, ImportRPLInformation *rplInfo) { + RelocationData(char type, size_t offset, int32_t addend, void *destination, const std::string &name, const ImportRPLInformation &rplInfo) : rplInfo(rplInfo) { this->type = type; this->offset = offset; this->addend = addend; this->destination = destination; this->name = name; - this->rplInfo = rplInfo; } ~RelocationData() { - if (rplInfo != NULL) { - delete rplInfo; - } } - char getType() { + char getType() const { return type; } - size_t getOffset() { + size_t getOffset() const { return offset; } - int32_t getAddend() { + int32_t getAddend() const { return addend; } - void *getDestination() { + void *getDestination() const { return destination; } - std::string getName() { + std::string getName() const { return name; } - ImportRPLInformation *getImportRPLInformation() { + ImportRPLInformation getImportRPLInformation() const { return rplInfo; } - std::string toString(); + std::string toString() const; private: char type; @@ -70,5 +66,5 @@ private: int32_t addend; void *destination; std::string name; - ImportRPLInformation *rplInfo; + const ImportRPLInformation rplInfo; };