Use std::shared_ptr

This commit is contained in:
Maschell 2021-12-15 17:09:30 +01:00
parent 64f78ccec4
commit 79eb5758b7
19 changed files with 297 additions and 269 deletions

View File

@ -1,6 +1,8 @@
#include <memory.h>
#include <coreinit/cache.h> #include <coreinit/cache.h>
#include <coreinit/dynload.h> #include <coreinit/dynload.h>
#include <coreinit/memdefaultheap.h> #include <coreinit/memdefaultheap.h>
#include <memory>
#include "patcher/hooks_patcher_static.h" #include "patcher/hooks_patcher_static.h"
#include "plugin/PluginContainer.h" #include "plugin/PluginContainer.h"
@ -12,11 +14,11 @@
#include "hooks.h" #include "hooks.h"
#include "globals.h" #include "globals.h"
bool PluginManagement::doRelocation(const std::vector<RelocationData> &relocData, relocation_trampolin_entry_t *tramp_data, uint32_t tramp_length, uint32_t trampolinID) { bool PluginManagement::doRelocation(const std::vector<std::shared_ptr<RelocationData>> &relocData, relocation_trampolin_entry_t *tramp_data, uint32_t tramp_length, uint32_t trampolinID) {
std::map<std::string, OSDynLoad_Module> moduleHandleCache; std::map<std::string, OSDynLoad_Module> moduleHandleCache;
for (auto const &cur: relocData) { for (auto const &cur: relocData) {
uint32_t functionAddress = 0; uint32_t functionAddress = 0;
const std::string &functionName = cur.getName(); const std::string &functionName = cur->getName();
if (functionName == "MEMAllocFromDefaultHeap") { if (functionName == "MEMAllocFromDefaultHeap") {
OSDynLoad_Module rplHandle; OSDynLoad_Module rplHandle;
@ -33,8 +35,8 @@ bool PluginManagement::doRelocation(const std::vector<RelocationData> &relocData
} }
if (functionAddress == 0) { if (functionAddress == 0) {
std::string rplName = cur.getImportRPLInformation().getName(); std::string rplName = cur->getImportRPLInformation()->getName();
int32_t isData = cur.getImportRPLInformation().isData(); int32_t isData = cur->getImportRPLInformation()->isData();
OSDynLoad_Module rplHandle = nullptr; OSDynLoad_Module rplHandle = nullptr;
if (moduleHandleCache.count(rplName) > 0) { if (moduleHandleCache.count(rplName) > 0) {
rplHandle = moduleHandleCache[rplName]; rplHandle = moduleHandleCache[rplName];
@ -51,7 +53,7 @@ bool PluginManagement::doRelocation(const std::vector<RelocationData> &relocData
} else { } else {
//DEBUG_FUNCTION_LINE("Found export for %s %s", rplName.c_str(), functionName.c_str()); //DEBUG_FUNCTION_LINE("Found export for %s %s", rplName.c_str(), functionName.c_str());
} }
if (!ElfUtils::elfLinkOne(cur.getType(), cur.getOffset(), cur.getAddend(), (uint32_t) cur.getDestination(), functionAddress, tramp_data, tramp_length, RELOC_TYPE_IMPORT, trampolinID)) { if (!ElfUtils::elfLinkOne(cur->getType(), cur->getOffset(), cur->getAddend(), (uint32_t) cur->getDestination(), functionAddress, tramp_data, tramp_length, RELOC_TYPE_IMPORT, trampolinID)) {
DEBUG_FUNCTION_LINE("Relocation failed"); DEBUG_FUNCTION_LINE("Relocation failed");
return false; return false;
} }
@ -63,27 +65,27 @@ bool PluginManagement::doRelocation(const std::vector<RelocationData> &relocData
} }
void PluginManagement::doRelocations(const std::vector<PluginContainer> &plugins, relocation_trampolin_entry_t *trampData, uint32_t tramp_size) { void PluginManagement::doRelocations(const std::vector<std::shared_ptr<PluginContainer>> &plugins, relocation_trampolin_entry_t *trampData, uint32_t tramp_size) {
for (auto &pluginContainer: plugins) { for (auto &pluginContainer: plugins) {
DEBUG_FUNCTION_LINE_VERBOSE("Doing relocations for plugin: %s", pluginContainer.getMetaInformation().getName().c_str()); DEBUG_FUNCTION_LINE_VERBOSE("Doing relocations for plugin: %s", pluginContainer->getMetaInformation()->getName().c_str());
if (!PluginManagement::doRelocation(pluginContainer.getPluginInformation().getRelocationDataList(), trampData, tramp_size, pluginContainer.getPluginInformation().getTrampolinId())) { if (!PluginManagement::doRelocation(pluginContainer->getPluginInformation()->getRelocationDataList(), trampData, tramp_size, pluginContainer->getPluginInformation()->getTrampolinId())) {
DEBUG_FUNCTION_LINE("Relocation failed"); DEBUG_FUNCTION_LINE("Relocation failed");
} }
} }
} }
void PluginManagement::memsetBSS(const std::vector<PluginContainer> &plugins) { void PluginManagement::memsetBSS(const std::vector<std::shared_ptr<PluginContainer>> &plugins) {
for (auto &pluginContainer: plugins) { for (auto &pluginContainer: plugins) {
auto sbssSection = pluginContainer.getPluginInformation().getSectionInfo(".sbss"); auto sbssSection = pluginContainer->getPluginInformation()->getSectionInfo(".sbss");
if (sbssSection) { if (sbssSection) {
DEBUG_FUNCTION_LINE_VERBOSE("memset .sbss %08X (%d)", sbssSection->getAddress(), sbssSection->getSize()); DEBUG_FUNCTION_LINE_VERBOSE("memset .sbss %08X (%d)", sbssSection.value()->getAddress(), sbssSection.value()->getSize());
memset((void *) sbssSection->getAddress(), 0, sbssSection->getSize()); memset((void *) sbssSection.value()->getAddress(), 0, sbssSection.value()->getSize());
} }
auto bssSection = pluginContainer.getPluginInformation().getSectionInfo(".bss"); auto bssSection = pluginContainer->getPluginInformation()->getSectionInfo(".bss");
if (bssSection) { if (bssSection) {
DEBUG_FUNCTION_LINE_VERBOSE("memset .bss %08X (%d)", bssSection->getAddress(), bssSection->getSize()); DEBUG_FUNCTION_LINE_VERBOSE("memset .bss %08X (%d)", bssSection.value()->getAddress(), bssSection.value()->getSize());
memset((void *) bssSection->getAddress(), 0, bssSection->getSize()); memset((void *) bssSection.value()->getAddress(), 0, bssSection.value()->getSize());
} }
} }
} }
@ -186,17 +188,17 @@ void PluginManagement::PatchFunctionsAndCallHooks(plugin_information_t *pluginIn
OSDynLoad_AddNotifyCallback(module_callback, pluginInformation); OSDynLoad_AddNotifyCallback(module_callback, pluginInformation);
} }
std::vector<PluginContainer> std::vector<std::shared_ptr<PluginContainer>>
PluginManagement::loadPlugins(const std::vector<PluginData> &pluginList, MEMHeapHandle heapHandle, relocation_trampolin_entry_t *trampolin_data, uint32_t trampolin_data_length) { PluginManagement::loadPlugins(const std::vector<std::shared_ptr<PluginData>> &pluginList, MEMHeapHandle heapHandle, relocation_trampolin_entry_t *trampolin_data, uint32_t trampolin_data_length) {
std::vector<PluginContainer> plugins; std::vector<std::shared_ptr<PluginContainer>> plugins;
for (auto &pluginData: pluginList) { for (auto &pluginData: pluginList) {
DEBUG_FUNCTION_LINE_VERBOSE("Load meta information"); DEBUG_FUNCTION_LINE_VERBOSE("Load meta information");
auto metaInfo = PluginMetaInformationFactory::loadPlugin(pluginData); auto metaInfo = PluginMetaInformationFactory::loadPlugin(pluginData);
if (metaInfo) { if (metaInfo) {
PluginContainer container; auto container = std::make_shared<PluginContainer>();
container.setMetaInformation(metaInfo.value()); container->setMetaInformation(metaInfo.value());
container.setPluginData(pluginData); container->setPluginData(pluginData);
plugins.push_back(container); plugins.push_back(container);
} else { } else {
DEBUG_FUNCTION_LINE("Failed to get meta information"); DEBUG_FUNCTION_LINE("Failed to get meta information");
@ -204,12 +206,12 @@ PluginManagement::loadPlugins(const std::vector<PluginData> &pluginList, MEMHeap
} }
uint32_t trampolineID = 0; uint32_t trampolineID = 0;
for (auto &pluginContainer: plugins) { for (auto &pluginContainer: plugins) {
std::optional<PluginInformation> info = PluginInformationFactory::load(pluginContainer.getPluginData(), heapHandle, trampolin_data, trampolin_data_length, trampolineID++); auto info = PluginInformationFactory::load(pluginContainer->getPluginData(), heapHandle, trampolin_data, trampolin_data_length, trampolineID++);
if (!info) { if (!info) {
DEBUG_FUNCTION_LINE("Failed to load Plugin %s", pluginContainer.getMetaInformation().getName().c_str()); DEBUG_FUNCTION_LINE("Failed to load Plugin %s", pluginContainer->getMetaInformation()->getName().c_str());
continue; continue;
} }
pluginContainer.setPluginInformation(info.value()); pluginContainer->setPluginInformation(info.value());
} }
return plugins; return plugins;
} }

View File

@ -6,19 +6,19 @@
class PluginManagement { class PluginManagement {
public: public:
static void doRelocations(const std::vector<PluginContainer> &plugins, relocation_trampolin_entry_t *trampData, uint32_t tramp_size); static void doRelocations(const std::vector<std::shared_ptr<PluginContainer>> &plugins, relocation_trampolin_entry_t *trampData, uint32_t tramp_size);
static void memsetBSS(const std::vector<PluginContainer> &plugins); static void memsetBSS(const std::vector<std::shared_ptr<PluginContainer>> &plugins);
static void callInitHooks(plugin_information_t *pluginInformation); static void callInitHooks(plugin_information_t *pluginInformation);
static void PatchFunctionsAndCallHooks(plugin_information_t *gPluginInformation); static void PatchFunctionsAndCallHooks(plugin_information_t *gPluginInformation);
static bool doRelocation(const std::vector<RelocationData> &relocData, relocation_trampolin_entry_t *tramp_data, uint32_t tramp_length, uint32_t trampolinID); static bool doRelocation(const std::vector<std::shared_ptr<RelocationData>> &relocData, relocation_trampolin_entry_t *tramp_data, uint32_t tramp_length, uint32_t trampolinID);
static void unloadPlugins(plugin_information_t *pluginInformation, MEMHeapHandle pluginHeap, BOOL freePluginData); static void unloadPlugins(plugin_information_t *pluginInformation, MEMHeapHandle pluginHeap, BOOL freePluginData);
static std::vector<PluginContainer> loadPlugins(const std::vector<PluginData> &pluginList, MEMHeapHandle pHeader, relocation_trampolin_entry_t *trampolin_data, uint32_t trampolin_data_length); static std::vector<std::shared_ptr<PluginContainer>> loadPlugins(const std::vector<std::shared_ptr<PluginData>> &pluginList, MEMHeapHandle pHeader, relocation_trampolin_entry_t *trampolin_data, uint32_t trampolin_data_length);
static void RestorePatches(plugin_information_t *pluginInformation, BOOL pluginOnly); static void RestorePatches(plugin_information_t *pluginInformation, BOOL pluginOnly);
}; };

View File

@ -6,6 +6,7 @@
#include <coreinit/cache.h> #include <coreinit/cache.h>
#include <coreinit/dynload.h> #include <coreinit/dynload.h>
#include <coreinit/memdefaultheap.h> #include <coreinit/memdefaultheap.h>
#include <memory>
#include "plugin/PluginContainer.h" #include "plugin/PluginContainer.h"
#include "globals.h" #include "globals.h"
#include "plugin/PluginDataFactory.h" #include "plugin/PluginDataFactory.h"
@ -120,14 +121,14 @@ WUMS_APPLICATION_STARTS() {
memset((void *) gTrampolineData, 0, sizeof(relocation_trampolin_entry_t) * NUMBER_OF_TRAMPS); memset((void *) gTrampolineData, 0, sizeof(relocation_trampolin_entry_t) * NUMBER_OF_TRAMPS);
} }
DEBUG_FUNCTION_LINE("Available memory for storing plugins: %d kb", MEMGetAllocatableSizeForExpHeapEx(gPluginDataHeap, 4) / 1024); DEBUG_FUNCTION_LINE("Available memory for storing plugins: %d kb", MEMGetAllocatableSizeForExpHeapEx(gPluginDataHeap, 4) / 1024);
std::vector<PluginData> pluginList = PluginDataFactory::loadDir("fs:/vol/external01/wiiu/plugins/", gPluginDataHeap); std::vector<std::shared_ptr<PluginData>> pluginList = PluginDataFactory::loadDir("fs:/vol/external01/wiiu/plugins/", gPluginDataHeap);
DEBUG_FUNCTION_LINE("Loaded data for %d plugins.", pluginList.size()); DEBUG_FUNCTION_LINE("Loaded data for %d plugins.", pluginList.size());
std::vector<PluginContainer> plugins = PluginManagement::loadPlugins(pluginList, gPluginDataHeap, gTrampolineData, gTrampolineDataSize); auto plugins = PluginManagement::loadPlugins(pluginList, gPluginDataHeap, gTrampolineData, gTrampolineDataSize);
for (auto &pluginContainer: plugins) { for (auto &pluginContainer: plugins) {
for (const auto &kv: pluginContainer.getPluginInformation().getSectionInfoList()) { for (const auto &kv: pluginContainer->getPluginInformation()->getSectionInfoList()) {
DEBUG_FUNCTION_LINE_VERBOSE("%s = %s %08X %d", kv.first.c_str(), kv.second.getName().c_str(), kv.second.getAddress(), kv.second.getSize()); DEBUG_FUNCTION_LINE_VERBOSE("%s = %s %08X %d", kv.first.c_str(), kv.second->getName().c_str(), kv.second->getAddress(), kv.second->getSize());
} }
if (!PluginContainerPersistence::savePlugin(gPluginInformation, pluginContainer, gPluginDataHeap)) { if (!PluginContainerPersistence::savePlugin(gPluginInformation, pluginContainer, gPluginDataHeap)) {
DEBUG_FUNCTION_LINE("Failed to save plugin"); DEBUG_FUNCTION_LINE("Failed to save plugin");
@ -138,7 +139,7 @@ WUMS_APPLICATION_STARTS() {
} }
if (gLinkOnReload.loadOnReload) { if (gLinkOnReload.loadOnReload) {
DEBUG_FUNCTION_LINE("Reload with new plugin list."); DEBUG_FUNCTION_LINE("Reload with new plugin list.");
std::vector<PluginData> pluginDataList; std::vector<std::shared_ptr<PluginData>> pluginDataList;
for (int32_t i = 0; i < gLinkOnReload.number_used_plugins; i++) { for (int32_t i = 0; i < gLinkOnReload.number_used_plugins; i++) {
auto pluginData = PluginDataPersistence::load(&gLinkOnReload.plugin_data[i]); auto pluginData = PluginDataPersistence::load(&gLinkOnReload.plugin_data[i]);
pluginDataList.push_back(pluginData); pluginDataList.push_back(pluginData);
@ -148,7 +149,7 @@ WUMS_APPLICATION_STARTS() {
plugin_information_single_t *plugin = &(gPluginInformation->plugin_data[plugin_index]); plugin_information_single_t *plugin = &(gPluginInformation->plugin_data[plugin_index]);
BOOL doDelete = true; BOOL doDelete = true;
for (auto &pluginData: pluginDataList) { for (auto &pluginData: pluginDataList) {
if (pluginData.buffer == plugin->data.buffer) { if (pluginData->buffer == plugin->data.buffer) {
doDelete = false; doDelete = false;
break; break;
} }
@ -177,10 +178,10 @@ WUMS_APPLICATION_STARTS() {
PluginManagement::unloadPlugins(gPluginInformation, gPluginDataHeap, false); PluginManagement::unloadPlugins(gPluginInformation, gPluginDataHeap, false);
std::vector<PluginContainer> plugins = PluginManagement::loadPlugins(pluginDataList, gPluginDataHeap, gTrampolineData, gTrampolineDataSize); auto plugins = PluginManagement::loadPlugins(pluginDataList, gPluginDataHeap, gTrampolineData, gTrampolineDataSize);
for (auto &pluginContainer: plugins) { for (auto &pluginContainer: plugins) {
DEBUG_FUNCTION_LINE("Stored information for plugin %s ; %s", pluginContainer.getMetaInformation().getName().c_str(), pluginContainer.getMetaInformation().getAuthor().c_str()); DEBUG_FUNCTION_LINE("Stored information for plugin %s ; %s", pluginContainer->getMetaInformation()->getName().c_str(), pluginContainer->getMetaInformation()->getAuthor().c_str());
if (!PluginContainerPersistence::savePlugin(gPluginInformation, pluginContainer, gPluginDataHeap)) { if (!PluginContainerPersistence::savePlugin(gPluginInformation, pluginContainer, gPluginDataHeap)) {
DEBUG_FUNCTION_LINE("Failed to save plugin"); DEBUG_FUNCTION_LINE("Failed to save plugin");
} }
@ -190,7 +191,7 @@ WUMS_APPLICATION_STARTS() {
} }
if (gPluginDataHeap != nullptr) { if (gPluginDataHeap != nullptr) {
std::vector<PluginContainer> plugins = PluginContainerPersistence::loadPlugins(gPluginInformation); auto plugins = PluginContainerPersistence::loadPlugins(gPluginInformation);
PluginManagement::doRelocations(plugins, gTrampolineData, DYN_LINK_TRAMPOLIN_LIST_LENGTH); PluginManagement::doRelocations(plugins, gTrampolineData, DYN_LINK_TRAMPOLIN_LIST_LENGTH);
// PluginManagement::memsetBSS(plugins); // PluginManagement::memsetBSS(plugins);

View File

@ -1,5 +1,6 @@
#include "DynamicLinkingHelper.h" #include "DynamicLinkingHelper.h"
#include <cstring> #include <cstring>
#include <memory>
dyn_linking_function_t *DynamicLinkingHelper::getOrAddFunctionEntryByName(dyn_linking_relocation_data_t *data, const char *functionName) { dyn_linking_function_t *DynamicLinkingHelper::getOrAddFunctionEntryByName(dyn_linking_relocation_data_t *data, const char *functionName) {
if (data == nullptr) { if (data == nullptr) {
@ -59,16 +60,16 @@ dyn_linking_import_t *DynamicLinkingHelper::getOrAddImport(dyn_linking_relocatio
} }
bool DynamicLinkingHelper::addReloationEntry(dyn_linking_relocation_data_t *linking_data, dyn_linking_relocation_entry_t *linking_entries, uint32_t linking_entry_length, bool DynamicLinkingHelper::addReloationEntry(dyn_linking_relocation_data_t *linking_data, dyn_linking_relocation_entry_t *linking_entries, uint32_t linking_entry_length,
const RelocationData &relocationData) { const std::shared_ptr<RelocationData> &relocationData) {
return addReloationEntry(linking_data, linking_entries, linking_entry_length, relocationData.getType(), relocationData.getOffset(), relocationData.getAddend(), relocationData.getDestination(), return addReloationEntry(linking_data, linking_entries, linking_entry_length, relocationData->getType(), relocationData->getOffset(), relocationData->getAddend(), relocationData->getDestination(),
relocationData.getName(), relocationData->getName(),
relocationData.getImportRPLInformation()); 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, 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, const void *destination, int32_t addend, const void *destination,
const std::string &name, const ImportRPLInformation &rplInfo) { const std::string &name, const std::shared_ptr<ImportRPLInformation> &rplInfo) {
dyn_linking_import_t *importInfoGbl = DynamicLinkingHelper::getOrAddImport(linking_data, rplInfo.getName().c_str(), rplInfo.isData()); dyn_linking_import_t *importInfoGbl = DynamicLinkingHelper::getOrAddImport(linking_data, rplInfo->getName().c_str(), rplInfo->isData());
if (importInfoGbl == nullptr) { if (importInfoGbl == nullptr) {
DEBUG_FUNCTION_LINE("Getting import info failed. Probably maximum of %d rpl files to import reached.", DYN_LINK_IMPORT_LIST_LENGTH); DEBUG_FUNCTION_LINE("Getting import info failed. Probably maximum of %d rpl files to import reached.", DYN_LINK_IMPORT_LIST_LENGTH);
return false; return false;

View File

@ -3,6 +3,7 @@
#include <wums/defines/dynamic_linking_defines.h> #include <wums/defines/dynamic_linking_defines.h>
#include <string> #include <string>
#include <vector> #include <vector>
#include <memory>
#include "RelocationData.h" #include "RelocationData.h"
class DynamicLinkingHelper { class DynamicLinkingHelper {
@ -46,12 +47,12 @@ public:
**/ **/
static dyn_linking_import_t *getOrAddImport(dyn_linking_relocation_data_t *data, const char *importName, bool isData); static dyn_linking_import_t *getOrAddImport(dyn_linking_relocation_data_t *data, const char *importName, bool isData);
static bool addReloationEntry(dyn_linking_relocation_data_t *linking_data, dyn_linking_relocation_entry_t *linking_entries, uint32_t linking_entry_length, const RelocationData &relocationData); static bool addReloationEntry(dyn_linking_relocation_data_t *linking_data, dyn_linking_relocation_entry_t *linking_entries, uint32_t linking_entry_length, const std::shared_ptr<RelocationData> &relocationData);
static bool 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, 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,
const void *destination, const std::string &name, const void *destination, const std::string &name,
const ImportRPLInformation &rplInfo); const std::shared_ptr<ImportRPLInformation> &rplInfo);
static bool addReloationEntry(dyn_linking_relocation_entry_t *linking_entries, uint32_t linking_entry_length, char type, size_t offset, int32_t addend, const void *destination, static bool addReloationEntry(dyn_linking_relocation_entry_t *linking_entries, uint32_t linking_entry_length, char type, size_t offset, int32_t addend, const void *destination,
dyn_linking_function_t *functionName, dyn_linking_function_t *functionName,

View File

@ -17,6 +17,7 @@
#pragma once #pragma once
#include <memory>
#include "PluginData.h" #include "PluginData.h"
#include "PluginMetaInformation.h" #include "PluginMetaInformation.h"
#include "PluginInformation.h" #include "PluginInformation.h"
@ -31,31 +32,31 @@ public:
PluginContainer() = default; PluginContainer() = default;
[[nodiscard]] const PluginMetaInformation &getMetaInformation() const { [[nodiscard]] const std::shared_ptr<PluginMetaInformation> &getMetaInformation() const {
return this->metaInformation; return this->metaInformation;
} }
void setMetaInformation(const PluginMetaInformation &metaInfo) { void setMetaInformation(const std::shared_ptr<PluginMetaInformation> &metaInfo) {
this->metaInformation = metaInfo; this->metaInformation = metaInfo;
} }
[[nodiscard]] const PluginInformation &getPluginInformation() const { [[nodiscard]] const std::shared_ptr<PluginInformation> &getPluginInformation() const {
return pluginInformation; return pluginInformation;
} }
void setPluginInformation(const PluginInformation &_pluginInformation) { void setPluginInformation(const std::shared_ptr<PluginInformation> &_pluginInformation) {
this->pluginInformation = _pluginInformation; this->pluginInformation = _pluginInformation;
} }
[[nodiscard]] const PluginData &getPluginData() const { [[nodiscard]] const std::shared_ptr<PluginData> &getPluginData() const {
return pluginData; return pluginData;
} }
void setPluginData(const PluginData &_pluginData) { void setPluginData(const std::shared_ptr<PluginData> &_pluginData) {
this->pluginData = _pluginData; this->pluginData = _pluginData;
} }
PluginData pluginData; std::shared_ptr<PluginData> pluginData;
PluginMetaInformation metaInformation; std::shared_ptr<PluginMetaInformation> metaInformation;
PluginInformation pluginInformation; std::shared_ptr<PluginInformation> pluginInformation;
}; };

View File

@ -1,5 +1,7 @@
#include <coreinit/cache.h> #include <coreinit/cache.h>
#include <memory>
#include "PluginContainer.h" #include "PluginContainer.h"
#include "PluginInformationFactory.h" #include "PluginInformationFactory.h"
#include "PluginMetaInformationFactory.h" #include "PluginMetaInformationFactory.h"
@ -7,10 +9,10 @@
#include "PluginDataPersistence.h" #include "PluginDataPersistence.h"
#include "DynamicLinkingHelper.h" #include "DynamicLinkingHelper.h"
bool PluginContainerPersistence::savePlugin(plugin_information_t *pluginInformation, PluginContainer &plugin, MEMHeapHandle heapHandle) { bool PluginContainerPersistence::savePlugin(plugin_information_t *pluginInformation, const std::shared_ptr<PluginContainer> &plugin, MEMHeapHandle heapHandle) {
int32_t plugin_count = pluginInformation->number_used_plugins; int32_t plugin_count = pluginInformation->number_used_plugins;
auto pluginName = plugin.getMetaInformation().getName(); auto pluginName = plugin->getMetaInformation()->getName();
if (plugin_count >= MAXIMUM_PLUGINS - 1) { if (plugin_count >= MAXIMUM_PLUGINS - 1) {
DEBUG_FUNCTION_LINE("Maximum of %d plugins reached. %s won't be loaded!", MAXIMUM_PLUGINS, pluginName.c_str()); DEBUG_FUNCTION_LINE("Maximum of %d plugins reached. %s won't be loaded!", MAXIMUM_PLUGINS, pluginName.c_str());
@ -22,50 +24,50 @@ bool PluginContainerPersistence::savePlugin(plugin_information_t *pluginInformat
// Make sure everything is reset. // Make sure everything is reset.
memset((void *) plugin_data, 0, sizeof(plugin_information_single_t)); memset((void *) plugin_data, 0, sizeof(plugin_information_single_t));
const auto &pluginMetaInfo = plugin.getMetaInformation(); const auto &pluginMetaInfo = plugin->getMetaInformation();
auto plugin_meta_data = &plugin_data->meta; auto plugin_meta_data = &plugin_data->meta;
if (pluginMetaInfo.getName().size() >= MAXIMUM_PLUGIN_META_FIELD_LENGTH) { if (pluginMetaInfo->getName().size() >= MAXIMUM_PLUGIN_META_FIELD_LENGTH) {
DEBUG_FUNCTION_LINE("Warning: name will be truncated."); DEBUG_FUNCTION_LINE("Warning: name will be truncated.");
} }
strncpy(plugin_meta_data->name, pluginMetaInfo.getName().c_str(), MAXIMUM_PLUGIN_META_FIELD_LENGTH - 1); strncpy(plugin_meta_data->name, pluginMetaInfo->getName().c_str(), MAXIMUM_PLUGIN_META_FIELD_LENGTH - 1);
if (pluginMetaInfo.getAuthor().size() >= MAXIMUM_PLUGIN_META_FIELD_LENGTH) { if (pluginMetaInfo->getAuthor().size() >= MAXIMUM_PLUGIN_META_FIELD_LENGTH) {
DEBUG_FUNCTION_LINE("Warning: author will be truncated."); DEBUG_FUNCTION_LINE("Warning: author will be truncated.");
} }
strncpy(plugin_meta_data->author, pluginMetaInfo.getAuthor().c_str(), MAXIMUM_PLUGIN_META_FIELD_LENGTH - 1); strncpy(plugin_meta_data->author, pluginMetaInfo->getAuthor().c_str(), MAXIMUM_PLUGIN_META_FIELD_LENGTH - 1);
if (pluginMetaInfo.getVersion().size() >= MAXIMUM_PLUGIN_META_FIELD_LENGTH) { if (pluginMetaInfo->getVersion().size() >= MAXIMUM_PLUGIN_META_FIELD_LENGTH) {
DEBUG_FUNCTION_LINE("Warning: version will be truncated."); DEBUG_FUNCTION_LINE("Warning: version will be truncated.");
} }
strncpy(plugin_meta_data->version, pluginMetaInfo.getVersion().c_str(), MAXIMUM_PLUGIN_META_FIELD_LENGTH - 1); strncpy(plugin_meta_data->version, pluginMetaInfo->getVersion().c_str(), MAXIMUM_PLUGIN_META_FIELD_LENGTH - 1);
if (pluginMetaInfo.getLicense().size() >= MAXIMUM_PLUGIN_META_FIELD_LENGTH) { if (pluginMetaInfo->getLicense().size() >= MAXIMUM_PLUGIN_META_FIELD_LENGTH) {
DEBUG_FUNCTION_LINE("Warning: license will be truncated."); DEBUG_FUNCTION_LINE("Warning: license will be truncated.");
} }
strncpy(plugin_meta_data->license, pluginMetaInfo.getLicense().c_str(), MAXIMUM_PLUGIN_META_FIELD_LENGTH - 1); strncpy(plugin_meta_data->license, pluginMetaInfo->getLicense().c_str(), MAXIMUM_PLUGIN_META_FIELD_LENGTH - 1);
if (pluginMetaInfo.getBuildTimestamp().size() >= MAXIMUM_PLUGIN_META_FIELD_LENGTH) { if (pluginMetaInfo->getBuildTimestamp().size() >= MAXIMUM_PLUGIN_META_FIELD_LENGTH) {
DEBUG_FUNCTION_LINE("Warning: build timestamp will be truncated."); DEBUG_FUNCTION_LINE("Warning: build timestamp will be truncated.");
} }
strncpy(plugin_meta_data->buildTimestamp, pluginMetaInfo.getBuildTimestamp().c_str(), MAXIMUM_PLUGIN_META_FIELD_LENGTH - 1); strncpy(plugin_meta_data->buildTimestamp, pluginMetaInfo->getBuildTimestamp().c_str(), MAXIMUM_PLUGIN_META_FIELD_LENGTH - 1);
if (pluginMetaInfo.getDescription().size() >= MAXIMUM_PLUGIN_DESCRIPTION_LENGTH) { if (pluginMetaInfo->getDescription().size() >= MAXIMUM_PLUGIN_DESCRIPTION_LENGTH) {
DEBUG_FUNCTION_LINE("Warning: description will be truncated."); DEBUG_FUNCTION_LINE("Warning: description will be truncated.");
DEBUG_FUNCTION_LINE("%s", pluginMetaInfo.getDescription().c_str()); DEBUG_FUNCTION_LINE("%s", pluginMetaInfo->getDescription().c_str());
} }
strncpy(plugin_meta_data->descripion, pluginMetaInfo.getDescription().c_str(), MAXIMUM_PLUGIN_DESCRIPTION_LENGTH - 1); strncpy(plugin_meta_data->descripion, pluginMetaInfo->getDescription().c_str(), MAXIMUM_PLUGIN_DESCRIPTION_LENGTH - 1);
if (pluginMetaInfo.getStorageId().length() >= MAXIMUM_PLUGIN_META_FIELD_LENGTH) { if (pluginMetaInfo->getStorageId().length() >= MAXIMUM_PLUGIN_META_FIELD_LENGTH) {
DEBUG_FUNCTION_LINE("Warning: plugin storage id will be truncated."); DEBUG_FUNCTION_LINE("Warning: plugin storage id will be truncated.");
} }
strncpy(plugin_meta_data->storageId, pluginMetaInfo.getStorageId().c_str(), MAXIMUM_PLUGIN_META_FIELD_LENGTH - 1); strncpy(plugin_meta_data->storageId, pluginMetaInfo->getStorageId().c_str(), MAXIMUM_PLUGIN_META_FIELD_LENGTH - 1);
plugin_meta_data->size = pluginMetaInfo.getSize(); plugin_meta_data->size = pluginMetaInfo->getSize();
auto pluginInfo = plugin.getPluginInformation(); auto pluginInfo = plugin->getPluginInformation();
// Relocation // Relocation
std::vector<RelocationData> relocationData = pluginInfo.getRelocationDataList(); auto relocationData = pluginInfo->getRelocationDataList();
for (auto &reloc: relocationData) { for (auto &reloc: relocationData) {
if (!DynamicLinkingHelper::addReloationEntry(&(pluginInformation->linking_data), plugin_data->info.linking_entries, PLUGIN_DYN_LINK_RELOCATION_LIST_LENGTH, reloc)) { if (!DynamicLinkingHelper::addReloationEntry(&(pluginInformation->linking_data), plugin_data->info.linking_entries, PLUGIN_DYN_LINK_RELOCATION_LIST_LENGTH, reloc)) {
DEBUG_FUNCTION_LINE("Failed to add a relocation entry"); DEBUG_FUNCTION_LINE("Failed to add a relocation entry");
@ -73,8 +75,8 @@ bool PluginContainerPersistence::savePlugin(plugin_information_t *pluginInformat
} }
} }
std::vector<FunctionData> function_data_list = pluginInfo.getFunctionDataList(); auto function_data_list = pluginInfo->getFunctionDataList();
std::vector<HookData> hook_data_list = pluginInfo.getHookDataList(); auto hook_data_list = pluginInfo->getHookDataList();
if (function_data_list.size() > MAXIMUM_FUNCTION_PER_PLUGIN) { if (function_data_list.size() > MAXIMUM_FUNCTION_PER_PLUGIN) {
DEBUG_FUNCTION_LINE("Plugin %s would replace to many function (%d, maximum is %d). It won't be loaded.", pluginName.c_str(), function_data_list.size(), MAXIMUM_FUNCTION_PER_PLUGIN); DEBUG_FUNCTION_LINE("Plugin %s would replace to many function (%d, maximum is %d). It won't be loaded.", pluginName.c_str(), function_data_list.size(), MAXIMUM_FUNCTION_PER_PLUGIN);
@ -92,48 +94,48 @@ bool PluginContainerPersistence::savePlugin(plugin_information_t *pluginInformat
/* Store function replacement information */ /* Store function replacement information */
uint32_t i = 0; uint32_t i = 0;
for (auto &curFunction: pluginInfo.getFunctionDataList()) { for (auto &curFunction: pluginInfo->getFunctionDataList()) {
function_replacement_data_t *function_data = &plugin_data->info.functions[i]; function_replacement_data_t *function_data = &plugin_data->info.functions[i];
if (strlen(curFunction.getName().c_str()) > MAXIMUM_FUNCTION_NAME_LENGTH - 1) { if (strlen(curFunction->getName().c_str()) > MAXIMUM_FUNCTION_NAME_LENGTH - 1) {
DEBUG_FUNCTION_LINE("Could not add function \"%s\" for plugin \"%s\" function name is too long.", curFunction.getName().c_str(), pluginName.c_str()); DEBUG_FUNCTION_LINE("Could not add function \"%s\" for plugin \"%s\" function name is too long.", curFunction->getName().c_str(), pluginName.c_str());
continue; continue;
} }
DEBUG_FUNCTION_LINE_VERBOSE("Adding function \"%s\" for plugin \"%s\"", curFunction.getName().c_str(), pluginName.c_str()); DEBUG_FUNCTION_LINE_VERBOSE("Adding function \"%s\" for plugin \"%s\"", curFunction->getName().c_str(), pluginName.c_str());
strncpy(function_data->function_name, curFunction.getName().c_str(), MAXIMUM_FUNCTION_NAME_LENGTH - 1); strncpy(function_data->function_name, curFunction->getName().c_str(), MAXIMUM_FUNCTION_NAME_LENGTH - 1);
function_data->VERSION = FUNCTION_REPLACEMENT_DATA_STRUCT_VERSION; function_data->VERSION = FUNCTION_REPLACEMENT_DATA_STRUCT_VERSION;
function_data->library = (function_replacement_library_type_t) curFunction.getLibrary(); function_data->library = (function_replacement_library_type_t) curFunction->getLibrary();
function_data->replaceAddr = (uint32_t) curFunction.getReplaceAddress(); function_data->replaceAddr = (uint32_t) curFunction->getReplaceAddress();
function_data->replaceCall = (uint32_t) curFunction.getReplaceCall(); function_data->replaceCall = (uint32_t) curFunction->getReplaceCall();
function_data->physicalAddr = (uint32_t) curFunction.getPhysicalAddress(); function_data->physicalAddr = (uint32_t) curFunction->getPhysicalAddress();
function_data->virtualAddr = (uint32_t) curFunction.getVirtualAddress(); function_data->virtualAddr = (uint32_t) curFunction->getVirtualAddress();
function_data->targetProcess = curFunction.getTargetProcess(); function_data->targetProcess = curFunction->getTargetProcess();
plugin_data->info.number_used_functions++; plugin_data->info.number_used_functions++;
i++; i++;
} }
i = 0; i = 0;
for (auto &curHook: pluginInfo.getHookDataList()) { for (auto &curHook: pluginInfo->getHookDataList()) {
replacement_data_hook_t *hook_data = &plugin_data->info.hooks[i]; replacement_data_hook_t *hook_data = &plugin_data->info.hooks[i];
DEBUG_FUNCTION_LINE_VERBOSE("Set hook for plugin \"%s\" of type %08X to target %08X", plugin_data->meta.name, curHook.getType(), (void *) curHook.getFunctionPointer()); DEBUG_FUNCTION_LINE_VERBOSE("Set hook for plugin \"%s\" of type %08X to target %08X", plugin_data->meta.name, curHook->getType(), (void *) curHook->getFunctionPointer());
hook_data->func_pointer = (void *) curHook.getFunctionPointer(); hook_data->func_pointer = (void *) curHook->getFunctionPointer();
hook_data->type = curHook.getType(); hook_data->type = curHook->getType();
plugin_data->info.number_used_hooks++; plugin_data->info.number_used_hooks++;
i++; i++;
} }
/* Saving SectionInfos */ /* Saving SectionInfos */
for (auto &curSection: pluginInfo.getSectionInfoList()) { for (auto &curSection: pluginInfo->getSectionInfoList()) {
bool foundFreeSlot = false; bool foundFreeSlot = false;
uint32_t slot = 0; uint32_t slot = 0;
for (uint32_t j = 0; j < MAXIMUM_PLUGIN_SECTION_LENGTH; j++) { for (uint32_t j = 0; j < MAXIMUM_PLUGIN_SECTION_LENGTH; j++) {
plugin_section_info_t *sectionInfo = &(plugin_data->info.sectionInfos[j]); auto *sectionInfo = &(plugin_data->info.sectionInfos[j]);
if (sectionInfo->addr == 0 && sectionInfo->size == 0) { if (sectionInfo->addr == 0 && sectionInfo->size == 0) {
foundFreeSlot = true; foundFreeSlot = true;
slot = j; slot = j;
@ -141,31 +143,30 @@ bool PluginContainerPersistence::savePlugin(plugin_information_t *pluginInformat
} }
} }
if (foundFreeSlot) { if (foundFreeSlot) {
plugin_section_info_t *sectionInfo = &(plugin_data->info.sectionInfos[slot]); auto *sectionInfo = &(plugin_data->info.sectionInfos[slot]);
if (curSection.first.length() > MAXIMUM_PLUGIN_SECTION_NAME_LENGTH - 1) { if (curSection.first.length() > MAXIMUM_PLUGIN_SECTION_NAME_LENGTH - 1) {
DEBUG_FUNCTION_LINE("Could not add section info \"%s\" for plugin \"%s\" section name is too long.", curSection.first.c_str(), pluginName.c_str()); DEBUG_FUNCTION_LINE("Could not add section info \"%s\" for plugin \"%s\" section name is too long.", curSection.first.c_str(), pluginName.c_str());
break; break;
} }
strncpy(sectionInfo->name, curSection.first.c_str(), MAXIMUM_PLUGIN_SECTION_NAME_LENGTH - 1); strncpy(sectionInfo->name, curSection.first.c_str(), MAXIMUM_PLUGIN_SECTION_NAME_LENGTH - 1);
sectionInfo->addr = curSection.second.getAddress(); sectionInfo->addr = curSection.second->getAddress();
sectionInfo->size = curSection.second.getSize(); sectionInfo->size = curSection.second->getSize();
} else { } else {
DEBUG_FUNCTION_LINE("Failed to store SectionInfos"); DEBUG_FUNCTION_LINE("Failed to store SectionInfos");
return false; return false;
} }
} }
plugin_data->info.trampolinId = pluginInfo.getTrampolinId(); plugin_data->info.trampolinId = pluginInfo->getTrampolinId();
plugin_data->info.allocatedTextMemoryAddress = pluginInfo.allocatedTextMemoryAddress; plugin_data->info.allocatedTextMemoryAddress = pluginInfo->allocatedTextMemoryAddress;
plugin_data->info.allocatedDataMemoryAddress = pluginInfo.allocatedDataMemoryAddress; plugin_data->info.allocatedDataMemoryAddress = pluginInfo->allocatedDataMemoryAddress;
uint32_t entryCount = pluginInfo->getFunctionSymbolDataList().size();
uint32_t entryCount = pluginInfo.getFunctionSymbolDataList().size();
if (entryCount > 0) { if (entryCount > 0) {
/* Saving SectionInfos */ // Saving SectionInfos
uint32_t funcSymStringLen = 1; uint32_t funcSymStringLen = 1;
for (auto &curFuncSym: pluginInfo.getFunctionSymbolDataList()) { for (auto &curFuncSym: pluginInfo->getFunctionSymbolDataList()) {
funcSymStringLen += curFuncSym.getName().length() + 1; funcSymStringLen += curFuncSym->getName().length() + 1;
} }
char *stringTable = (char *) MEMAllocFromExpHeapEx(heapHandle, funcSymStringLen, 0x4); char *stringTable = (char *) MEMAllocFromExpHeapEx(heapHandle, funcSymStringLen, 0x4);
@ -186,12 +187,12 @@ bool PluginContainerPersistence::savePlugin(plugin_information_t *pluginInformat
uint32_t curStringOffset = 0; uint32_t curStringOffset = 0;
uint32_t curEntryIndex = 0; uint32_t curEntryIndex = 0;
for (auto &curFuncSym: pluginInfo.getFunctionSymbolDataList()) { for (auto &curFuncSym: pluginInfo->getFunctionSymbolDataList()) {
entryTable[curEntryIndex].address = curFuncSym.getAddress(); entryTable[curEntryIndex].address = curFuncSym->getAddress();
entryTable[curEntryIndex].name = &stringTable[curStringOffset]; entryTable[curEntryIndex].name = &stringTable[curStringOffset];
entryTable[curEntryIndex].size = curFuncSym.getSize(); entryTable[curEntryIndex].size = curFuncSym->getSize();
auto len = curFuncSym.getName().length() + 1; auto len = curFuncSym->getName().length() + 1;
memcpy(stringTable + curStringOffset, curFuncSym.getName().c_str(), len); memcpy(stringTable + curStringOffset, curFuncSym->getName().c_str(), len);
curStringOffset += len; curStringOffset += len;
curEntryIndex++; curEntryIndex++;
} }
@ -203,7 +204,7 @@ bool PluginContainerPersistence::savePlugin(plugin_information_t *pluginInformat
plugin_data->info.number_function_symbol_data = entryCount; plugin_data->info.number_function_symbol_data = entryCount;
/* Copy plugin data */ /* Copy plugin data */
auto pluginData = plugin.getPluginData(); auto pluginData = plugin->getPluginData();
auto plugin_data_data = &plugin_data->data; auto plugin_data_data = &plugin_data->data;
PluginDataPersistence::save(plugin_data_data, pluginData); PluginDataPersistence::save(plugin_data_data, pluginData);
@ -216,8 +217,8 @@ bool PluginContainerPersistence::savePlugin(plugin_information_t *pluginInformat
return true; return true;
} }
std::vector<PluginContainer> PluginContainerPersistence::loadPlugins(plugin_information_t *pluginInformation) { std::vector<std::shared_ptr<PluginContainer>> PluginContainerPersistence::loadPlugins(plugin_information_t *pluginInformation) {
std::vector<PluginContainer> result; std::vector<std::shared_ptr<PluginContainer>> result;
if (pluginInformation == nullptr) { if (pluginInformation == nullptr) {
DEBUG_FUNCTION_LINE("pluginInformation == nullptr"); DEBUG_FUNCTION_LINE("pluginInformation == nullptr");
return result; return result;
@ -234,27 +235,27 @@ std::vector<PluginContainer> PluginContainerPersistence::loadPlugins(plugin_info
// Copy data from struct. // Copy data from struct.
plugin_information_single_t *plugin_data = &(pluginInformation->plugin_data[i]); plugin_information_single_t *plugin_data = &(pluginInformation->plugin_data[i]);
PluginMetaInformation metaInformation; auto metaInformation = std::shared_ptr<PluginMetaInformation>(new PluginMetaInformation);
plugin_meta_info_t *meta = &(plugin_data->meta); plugin_meta_info_t *meta = &(plugin_data->meta);
metaInformation.setAuthor(meta->author); metaInformation->setAuthor(meta->author);
metaInformation.setVersion(meta->version); metaInformation->setVersion(meta->version);
metaInformation.setBuildTimestamp(meta->buildTimestamp); metaInformation->setBuildTimestamp(meta->buildTimestamp);
metaInformation.setLicense(meta->license); metaInformation->setLicense(meta->license);
metaInformation.setDescription(meta->descripion); metaInformation->setDescription(meta->descripion);
metaInformation.setSize(meta->size); metaInformation->setSize(meta->size);
metaInformation.setName(meta->name); metaInformation->setName(meta->name);
metaInformation.setStorageId(meta->storageId); metaInformation->setStorageId(meta->storageId);
plugin_data_t *data = &(plugin_data->data); plugin_data_t *data = &(plugin_data->data);
PluginData pluginData = PluginDataPersistence::load(data); auto pluginData = PluginDataPersistence::load(data);
PluginInformation curPluginInformation; auto curPluginInformation = std::make_shared<PluginInformation>();
curPluginInformation.setTrampolinId(plugin_data->info.trampolinId); curPluginInformation->setTrampolinId(plugin_data->info.trampolinId);
curPluginInformation.allocatedTextMemoryAddress = plugin_data->info.allocatedTextMemoryAddress; curPluginInformation->allocatedTextMemoryAddress = plugin_data->info.allocatedTextMemoryAddress;
curPluginInformation.allocatedDataMemoryAddress = plugin_data->info.allocatedDataMemoryAddress; curPluginInformation->allocatedDataMemoryAddress = plugin_data->info.allocatedDataMemoryAddress;
for (auto &curItem: plugin_data->info.sectionInfos) { for (auto &curItem: plugin_data->info.sectionInfos) {
plugin_section_info_t *sectionInfo = &curItem; plugin_section_info_t *sectionInfo = &curItem;
@ -263,7 +264,7 @@ std::vector<PluginContainer> PluginContainerPersistence::loadPlugins(plugin_info
} }
DEBUG_FUNCTION_LINE_VERBOSE("Add SectionInfo %s", sectionInfo->name); DEBUG_FUNCTION_LINE_VERBOSE("Add SectionInfo %s", sectionInfo->name);
std::string name(sectionInfo->name); std::string name(sectionInfo->name);
curPluginInformation.addSectionInfo(SectionInfo(name, sectionInfo->addr, sectionInfo->size)); curPluginInformation->addSectionInfo(std::make_shared<SectionInfo>(name, sectionInfo->addr, sectionInfo->size));
} }
/* load hook data */ /* load hook data */
@ -276,14 +277,13 @@ std::vector<PluginContainer> PluginContainerPersistence::loadPlugins(plugin_info
for (uint32_t j = 0; j < hookCount; j++) { for (uint32_t j = 0; j < hookCount; j++) {
replacement_data_hook_t *hook_entry = &(plugin_data->info.hooks[j]); replacement_data_hook_t *hook_entry = &(plugin_data->info.hooks[j]);
HookData curHook(hook_entry->func_pointer, hook_entry->type); curPluginInformation->addHookData(std::make_shared<HookData>(hook_entry->func_pointer, hook_entry->type));
curPluginInformation.addHookData(curHook);
} }
bool storageHasId = true; bool storageHasId = true;
for (auto const &value: curPluginInformation.getHookDataList()) { for (auto const &value: curPluginInformation->getHookDataList()) {
if (value.getType() == WUPS_LOADER_HOOK_INIT_STORAGE && if (value->getType() == WUPS_LOADER_HOOK_INIT_STORAGE &&
metaInformation.getStorageId().empty()) { metaInformation->getStorageId().empty()) {
storageHasId = false; storageHasId = false;
} }
} }
@ -302,9 +302,10 @@ std::vector<PluginContainer> PluginContainerPersistence::loadPlugins(plugin_info
for (uint32_t j = 0; j < functionReplaceCount; j++) { for (uint32_t j = 0; j < functionReplaceCount; j++) {
function_replacement_data_t *entry = &(plugin_data->info.functions[j]); function_replacement_data_t *entry = &(plugin_data->info.functions[j]);
FunctionData func((void *) entry->physicalAddr, (void *) entry->virtualAddr, entry->function_name, (function_replacement_library_type_t) entry->library, (void *) entry->replaceAddr, auto func = std::make_shared<FunctionData>((void *) entry->physicalAddr, (void *) entry->virtualAddr, entry->function_name, (function_replacement_library_type_t) entry->library,
(void *) entry->replaceCall, entry->targetProcess); (void *) entry->replaceAddr,
curPluginInformation.addFunctionData(func); (void *) entry->replaceCall, entry->targetProcess);
curPluginInformation->addFunctionData(func);
} }
/* load relocation data */ /* load relocation data */
@ -323,24 +324,24 @@ std::vector<PluginContainer> PluginContainerPersistence::loadPlugins(plugin_info
DEBUG_FUNCTION_LINE("functionEntry was nullptr, skipping relocation entry"); DEBUG_FUNCTION_LINE("functionEntry was nullptr, skipping relocation entry");
continue; continue;
} }
ImportRPLInformation rplInfo(importEntry->importName, importEntry->isData); auto rplInfo = std::make_shared<ImportRPLInformation>(importEntry->importName, importEntry->isData);
std::string functionName(functionEntry->functionName); std::string functionName(functionEntry->functionName);
RelocationData reloc(linking_entry.type, linking_entry.offset, linking_entry.addend, linking_entry.destination, functionName, rplInfo); auto reloc = std::make_shared<RelocationData>(linking_entry.type, linking_entry.offset, linking_entry.addend, linking_entry.destination, functionName, rplInfo);
curPluginInformation.addRelocationData(reloc); curPluginInformation->addRelocationData(reloc);
} }
/* load function symbol data */ /* load function symbol data */
for (uint32_t j = 0; j < plugin_data->info.number_function_symbol_data; j++) { for (uint32_t j = 0; j < plugin_data->info.number_function_symbol_data; j++) {
auto symbol_data = &plugin_data->info.function_symbol_data[j]; auto symbol_data = &plugin_data->info.function_symbol_data[j];
std::string symbol_name = symbol_data->name; std::string symbol_name = symbol_data->name;
FunctionSymbolData funSymbolData(symbol_name, (void *) symbol_data->address, symbol_data->size); auto funSymbolData = std::make_shared<FunctionSymbolData>(symbol_name, (void *) symbol_data->address, symbol_data->size);
curPluginInformation.addFunctionSymbolData(funSymbolData); curPluginInformation->addFunctionSymbolData(funSymbolData);
} }
PluginContainer container; auto container = std::make_shared<PluginContainer>();
container.setMetaInformation(metaInformation); container->setMetaInformation(metaInformation);
container.setPluginData(pluginData); container->setPluginData(pluginData);
container.setPluginInformation(curPluginInformation); container->setPluginInformation(curPluginInformation);
result.push_back(container); result.push_back(container);
} }
return result; return result;

View File

@ -5,7 +5,7 @@
class PluginContainerPersistence { class PluginContainerPersistence {
public: public:
static bool savePlugin(plugin_information_t *pluginInformation, PluginContainer &plugin, MEMHeapHandle heapHandle); static bool savePlugin(plugin_information_t *pluginInformation, const std::shared_ptr<PluginContainer> &plugin, MEMHeapHandle heapHandle);
static std::vector<PluginContainer> loadPlugins(plugin_information_t *pluginInformation); static std::vector<std::shared_ptr<PluginContainer>> loadPlugins(plugin_information_t *pluginInformation);
}; };

View File

@ -23,8 +23,8 @@
#include "../utils/StringTools.h" #include "../utils/StringTools.h"
std::vector<PluginData> PluginDataFactory::loadDir(const std::string &path, MEMHeapHandle heapHandle) { std::vector<std::shared_ptr<PluginData>> PluginDataFactory::loadDir(const std::string &path, MEMHeapHandle heapHandle) {
std::vector<PluginData> result; std::vector<std::shared_ptr<PluginData>> result;
struct dirent *dp; struct dirent *dp;
DIR *dfd = nullptr; DIR *dfd = nullptr;
@ -64,7 +64,7 @@ std::vector<PluginData> PluginDataFactory::loadDir(const std::string &path, MEMH
return result; return result;
} }
std::optional<PluginData> PluginDataFactory::load(const std::string &filename, MEMHeapHandle heapHandle) { std::optional<std::shared_ptr<PluginData>> PluginDataFactory::load(const std::string &filename, MEMHeapHandle heapHandle) {
// Not going to explicitly check these. // Not going to explicitly check these.
// The use of gcount() below will compensate for a failure here. // The use of gcount() below will compensate for a failure here.
std::ifstream is(filename, std::ios::binary); std::ifstream is(filename, std::ios::binary);
@ -93,11 +93,10 @@ std::optional<PluginData> PluginDataFactory::load(const std::string &filename, M
return load(result, heapHandle); return load(result, heapHandle);
} }
std::optional<PluginData> PluginDataFactory::load(std::vector<uint8_t> &buffer, MEMHeapHandle heapHandle) { std::optional<std::shared_ptr<PluginData>> PluginDataFactory::load(std::vector<uint8_t> &buffer, MEMHeapHandle heapHandle) {
if (buffer.empty()) { if (buffer.empty()) {
return std::nullopt; return std::nullopt;
} }
PluginData pluginData(buffer, heapHandle, eMemoryTypes::eMemTypeMEM2); return std::shared_ptr<PluginData>(new PluginData(buffer, heapHandle, eMemoryTypes::eMemTypeMEM2));
return pluginData;
} }

View File

@ -25,9 +25,9 @@
class PluginDataFactory { class PluginDataFactory {
public: public:
static std::vector<PluginData> loadDir(const std::string &path, MEMHeapHandle heapHandle); static std::vector<std::shared_ptr<PluginData>> loadDir(const std::string &path, MEMHeapHandle heapHandle);
static std::optional<PluginData> load(const std::string &path, MEMHeapHandle heapHandle); static std::optional<std::shared_ptr<PluginData>> load(const std::string &path, MEMHeapHandle heapHandle);
static std::optional<PluginData> load(std::vector<uint8_t> &buffer, MEMHeapHandle heapHandle); static std::optional<std::shared_ptr<PluginData>> load(std::vector<uint8_t> &buffer, MEMHeapHandle heapHandle);
}; };

View File

@ -1,24 +1,35 @@
#include <memory>
#include "../common/plugin_defines.h" #include "../common/plugin_defines.h"
#include "PluginDataPersistence.h" #include "PluginDataPersistence.h"
#include "PluginData.h"
bool PluginDataPersistence::save(plugin_data_t *pluginDataStruct, PluginData &plugin) { bool PluginDataPersistence::save(plugin_data_t *pluginDataStruct, const std::shared_ptr<PluginData> &plugin) {
if (pluginDataStruct == nullptr) { if (pluginDataStruct == nullptr) {
return false; return false;
} }
pluginDataStruct->buffer = (char *) plugin.buffer; pluginDataStruct->buffer = (char *) plugin->buffer;
pluginDataStruct->bufferLength = plugin.length; pluginDataStruct->bufferLength = plugin->length;
pluginDataStruct->memoryType = plugin.memoryType; pluginDataStruct->memoryType = plugin->memoryType;
pluginDataStruct->heapHandle = (int) plugin.heapHandle; pluginDataStruct->heapHandle = (int) plugin->heapHandle;
return true; return true;
} }
PluginData PluginDataPersistence::load(plugin_data_t *pluginDataStruct) { bool PluginDataPersistence::save(plugin_data_t *pluginDataStruct, PluginData* plugin) {
PluginData pluginData; if (pluginDataStruct == nullptr) {
return false;
}
pluginDataStruct->buffer = (char *) plugin->buffer;
pluginDataStruct->bufferLength = plugin->length;
pluginDataStruct->memoryType = plugin->memoryType;
pluginDataStruct->heapHandle = (int) plugin->heapHandle;
return true;
}
pluginData.buffer = pluginDataStruct->buffer; std::shared_ptr<PluginData> PluginDataPersistence::load(plugin_data_t *pluginDataStruct) {
pluginData.length = pluginDataStruct->bufferLength; auto pluginData = std::make_shared<PluginData>();
pluginData.memoryType = (eMemoryTypes) pluginDataStruct->memoryType;
pluginData.heapHandle = (MEMHeapHandle) pluginDataStruct->heapHandle; pluginData->buffer = pluginDataStruct->buffer;
pluginData->length = pluginDataStruct->bufferLength;
pluginData->memoryType = (eMemoryTypes) pluginDataStruct->memoryType;
pluginData->heapHandle = (MEMHeapHandle) pluginDataStruct->heapHandle;
return pluginData; return pluginData;
} }

View File

@ -5,7 +5,8 @@
class PluginDataPersistence { class PluginDataPersistence {
public: public:
static bool save(plugin_data_t *pluginDataStruct, PluginData &plugin); static bool save(plugin_data_t *pluginDataStruct, const std::shared_ptr<PluginData> &plugin);
static bool save(plugin_data_t *pluginDataStruct, PluginData* plugin);
static PluginData load(plugin_data_t *pluginDataStruct); static std::shared_ptr<PluginData> load(plugin_data_t *pluginDataStruct);
}; };

View File

@ -22,6 +22,7 @@
#include <optional> #include <optional>
#include <string> #include <string>
#include <vector> #include <vector>
#include <memory>
#include "PluginMetaInformation.h" #include "PluginMetaInformation.h"
#include "RelocationData.h" #include "RelocationData.h"
#include "HookData.h" #include "HookData.h"
@ -29,6 +30,14 @@
#include "SectionInfo.h" #include "SectionInfo.h"
#include "FunctionSymbolData.h" #include "FunctionSymbolData.h"
struct FunctionSymbolDataComparator {
bool operator()(const std::shared_ptr<FunctionSymbolData>& lhs,
const std::shared_ptr<FunctionSymbolData>& rhs) const
{
return (uint32_t) lhs->getAddress() < (uint32_t) rhs->getAddress();
}
};
class PluginInformation { class PluginInformation {
public: public:
PluginInformation(const PluginInformation &other); PluginInformation(const PluginInformation &other);
@ -37,47 +46,48 @@ public:
virtual ~PluginInformation() = default; virtual ~PluginInformation() = default;
void addHookData(const HookData &hook_data) { void addHookData(const std::shared_ptr<HookData> &hook_data) {
hook_data_list.push_back(hook_data); hook_data_list.push_back(hook_data);
} }
[[nodiscard]] const std::vector<HookData> &getHookDataList() const { [[nodiscard]] const std::vector<std::shared_ptr<HookData>> &getHookDataList() const {
return hook_data_list; return hook_data_list;
} }
void addFunctionData(const FunctionData &function_data) { void addFunctionData(const std::shared_ptr<FunctionData> &function_data) {
function_data_list.push_back(function_data); function_data_list.push_back(function_data);
} }
[[nodiscard]] const std::vector<FunctionData> &getFunctionDataList() const { [[nodiscard]] const std::vector<std::shared_ptr<FunctionData>> &getFunctionDataList() const {
return function_data_list; return function_data_list;
} }
void addRelocationData(const RelocationData &relocation_data) { void addRelocationData(const std::shared_ptr<RelocationData> &relocation_data) {
relocation_data_list.push_back(relocation_data); relocation_data_list.push_back(relocation_data);
} }
[[nodiscard]] const std::vector<RelocationData> &getRelocationDataList() const { [[nodiscard]] const std::vector<std::shared_ptr<RelocationData>> &getRelocationDataList() const {
return relocation_data_list; return relocation_data_list;
} }
void addFunctionSymbolData(const FunctionSymbolData &symbol_data) {
void addFunctionSymbolData(const std::shared_ptr<FunctionSymbolData> &symbol_data) {
symbol_data_list.insert(symbol_data); symbol_data_list.insert(symbol_data);
} }
[[nodiscard]] const std::set<FunctionSymbolData> &getFunctionSymbolDataList() const { [[nodiscard]] const std::set<std::shared_ptr<FunctionSymbolData>, FunctionSymbolDataComparator> &getFunctionSymbolDataList() const {
return symbol_data_list; return symbol_data_list;
} }
void addSectionInfo(const SectionInfo &sectionInfo) { void addSectionInfo(const std::shared_ptr<SectionInfo> &sectionInfo) {
section_info_list[sectionInfo.getName()] = sectionInfo; section_info_list[sectionInfo->getName()] = sectionInfo;
} }
[[nodiscard]] const std::map<std::string, SectionInfo> &getSectionInfoList() const { [[nodiscard]] const std::map<std::string, std::shared_ptr<SectionInfo>> &getSectionInfoList() const {
return section_info_list; return section_info_list;
} }
[[nodiscard]] std::optional<SectionInfo> getSectionInfo(const std::string &sectionName) const { [[nodiscard]] std::optional<std::shared_ptr<SectionInfo>> getSectionInfo(const std::string &sectionName) const {
if (getSectionInfoList().count(sectionName) > 0) { if (getSectionInfoList().count(sectionName) > 0) {
return section_info_list.at(sectionName); return section_info_list.at(sectionName);
} }
@ -93,11 +103,11 @@ public:
} }
private: private:
std::vector<HookData> hook_data_list; std::vector<std::shared_ptr<HookData>> hook_data_list;
std::vector<FunctionData> function_data_list; std::vector<std::shared_ptr<FunctionData>> function_data_list;
std::vector<RelocationData> relocation_data_list; std::vector<std::shared_ptr<RelocationData>> relocation_data_list;
std::set<FunctionSymbolData> symbol_data_list; std::set<std::shared_ptr<FunctionSymbolData>, FunctionSymbolDataComparator> symbol_data_list;
std::map<std::string, SectionInfo> section_info_list; std::map<std::string, std::shared_ptr<SectionInfo>> section_info_list;
uint8_t trampolinId = 0; uint8_t trampolinId = 0;

View File

@ -15,6 +15,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
****************************************************************************/ ****************************************************************************/
#include <memory>
#include <string> #include <string>
#include <vector> #include <vector>
#include <map> #include <map>
@ -28,19 +29,20 @@
using namespace ELFIO; using namespace ELFIO;
std::optional<PluginInformation> std::optional<std::shared_ptr<PluginInformation>>
PluginInformationFactory::load(const PluginData &pluginData, MEMHeapHandle heapHandle, relocation_trampolin_entry_t *trampolin_data, uint32_t trampolin_data_length, uint8_t trampolinId) { PluginInformationFactory::load(const std::shared_ptr<PluginData> &pluginData, MEMHeapHandle heapHandle, relocation_trampolin_entry_t *trampolin_data, uint32_t trampolin_data_length,
if (pluginData.buffer == nullptr) { uint8_t trampolinId) {
if (pluginData->buffer == nullptr) {
DEBUG_FUNCTION_LINE("Buffer was nullptr"); DEBUG_FUNCTION_LINE("Buffer was nullptr");
return std::nullopt; return std::nullopt;
} }
elfio reader; elfio reader;
if (!reader.load((char *) pluginData.buffer, pluginData.length)) { if (!reader.load((char *) pluginData->buffer, pluginData->length)) {
DEBUG_FUNCTION_LINE("Can't process PluginData in elfio"); DEBUG_FUNCTION_LINE("Can't process PluginData in elfio");
return std::nullopt; return std::nullopt;
} }
PluginInformation pluginInfo; auto pluginInfo = std::make_shared<PluginInformation>();
uint32_t sec_num = reader.sections.size(); uint32_t sec_num = reader.sections.size();
auto **destinations = (uint8_t **) malloc(sizeof(uint8_t *) * sec_num); auto **destinations = (uint8_t **) malloc(sizeof(uint8_t *) * sec_num);
@ -128,7 +130,7 @@ PluginInformationFactory::load(const PluginData &pluginData, MEMHeapHandle heapH
} }
std::string sectionName(psec->get_name()); std::string sectionName(psec->get_name());
pluginInfo.addSectionInfo(SectionInfo(sectionName, destination, sectionSize)); pluginInfo->addSectionInfo(std::make_shared<SectionInfo>(sectionName, destination, sectionSize));
DEBUG_FUNCTION_LINE_VERBOSE("Saved %s section info. Location: %08X size: %08X", psec->get_name().c_str(), destination, sectionSize); DEBUG_FUNCTION_LINE_VERBOSE("Saved %s section info. Location: %08X size: %08X", psec->get_name().c_str(), destination, sectionSize);
totalSize += sectionSize; totalSize += sectionSize;
@ -152,10 +154,10 @@ PluginInformationFactory::load(const PluginData &pluginData, MEMHeapHandle heapH
} }
} }
} }
std::vector<RelocationData> relocationData = getImportRelocationData(reader, destinations); auto relocationData = getImportRelocationData(reader, destinations);
for (auto const &reloc: relocationData) { for (auto const &reloc: relocationData) {
pluginInfo.addRelocationData(reloc); pluginInfo->addRelocationData(reloc);
} }
DCFlushRange((void *) text_data, text_size); DCFlushRange((void *) text_data, text_size);
@ -165,37 +167,38 @@ PluginInformationFactory::load(const PluginData &pluginData, MEMHeapHandle heapH
free(destinations); free(destinations);
pluginInfo.setTrampolinId(trampolinId); pluginInfo->setTrampolinId(trampolinId);
std::optional<SectionInfo> secInfo = pluginInfo.getSectionInfo(".wups.hooks"); auto secInfo = pluginInfo->getSectionInfo(".wups.hooks");
if (secInfo && secInfo->getSize() > 0) { if (secInfo && secInfo.value()->getSize() > 0) {
size_t entries_count = secInfo->getSize() / sizeof(wups_loader_hook_t); size_t entries_count = secInfo.value()->getSize() / sizeof(wups_loader_hook_t);
auto *entries = (wups_loader_hook_t *) secInfo->getAddress(); auto *entries = (wups_loader_hook_t *) secInfo.value()->getAddress();
if (entries != nullptr) { if (entries != nullptr) {
for (size_t j = 0; j < entries_count; j++) { for (size_t j = 0; j < entries_count; j++) {
wups_loader_hook_t *hook = &entries[j]; wups_loader_hook_t *hook = &entries[j];
DEBUG_FUNCTION_LINE_VERBOSE("Saving hook of plugin Type: %08X, target: %08X"/*,pluginData.getPluginInformation()->getName().c_str()*/, hook->type, (void *) hook->target); DEBUG_FUNCTION_LINE_VERBOSE("Saving hook of plugin Type: %08X, target: %08X"/*,pluginData->getPluginInformation()->getName().c_str()*/, hook->type, (void *) hook->target);
HookData hook_data((void *) hook->target, hook->type); auto hook_data = std::make_shared<HookData>((void *) hook->target, hook->type);
pluginInfo.addHookData(hook_data); pluginInfo->addHookData(hook_data);
} }
} }
} }
secInfo = pluginInfo.getSectionInfo(".wups.load"); secInfo = pluginInfo->getSectionInfo(".wups.load");
if (secInfo && secInfo->getSize() > 0) { if (secInfo && secInfo.value()->getSize() > 0) {
size_t entries_count = secInfo->getSize() / sizeof(wups_loader_entry_t); size_t entries_count = secInfo.value()->getSize() / sizeof(wups_loader_entry_t);
auto *entries = (wups_loader_entry_t *) secInfo->getAddress(); auto *entries = (wups_loader_entry_t *) secInfo.value()->getAddress();
if (entries != nullptr) { if (entries != nullptr) {
for (size_t j = 0; j < entries_count; j++) { for (size_t j = 0; j < entries_count; j++) {
wups_loader_entry_t *cur_function = &entries[j]; wups_loader_entry_t *cur_function = &entries[j];
DEBUG_FUNCTION_LINE_VERBOSE("Saving function \"%s\" of plugin . PA:%08X VA:%08X Library: %08X, target: %08X, call_addr: %08X", DEBUG_FUNCTION_LINE_VERBOSE("Saving function \"%s\" of plugin . PA:%08X VA:%08X Library: %08X, target: %08X, call_addr: %08X",
cur_function->_function.name/*,pluginData.getPluginInformation()->getName().c_str()*/, cur_function->_function.name/*,pluginData->getPluginInformation()->getName().c_str()*/,
cur_function->_function.physical_address, cur_function->_function.virtual_address, cur_function->_function.library, cur_function->_function.target, cur_function->_function.physical_address, cur_function->_function.virtual_address, cur_function->_function.library, cur_function->_function.target,
(void *) cur_function->_function.call_addr); (void *) cur_function->_function.call_addr);
FunctionData function_data((void *) cur_function->_function.physical_address, (void *) cur_function->_function.virtual_address, cur_function->_function.name, auto function_data = std::make_shared<FunctionData>((void *) cur_function->_function.physical_address, (void *) cur_function->_function.virtual_address, cur_function->_function.name,
(function_replacement_library_type_t) cur_function->_function.library, (function_replacement_library_type_t) cur_function->_function.library,
(void *) cur_function->_function.target, (void *) cur_function->_function.call_addr, (FunctionPatcherTargetProcess) cur_function->_function.targetProcess); (void *) cur_function->_function.target, (void *) cur_function->_function.call_addr,
pluginInfo.addFunctionData(function_data); (FunctionPatcherTargetProcess) cur_function->_function.targetProcess);
pluginInfo->addFunctionData(function_data);
} }
} }
} }
@ -221,14 +224,13 @@ PluginInformationFactory::load(const PluginData &pluginData, MEMHeapHandle heapH
if (type == STT_FUNC) { // We only care about functions. if (type == STT_FUNC) { // We only care about functions.
auto sectionVal = reader.sections[section]; auto sectionVal = reader.sections[section];
auto offsetVal = value - sectionVal->get_address(); auto offsetVal = value - sectionVal->get_address();
auto sectionOpt = pluginInfo.getSectionInfo(sectionVal->get_name()); auto sectionOpt = pluginInfo->getSectionInfo(sectionVal->get_name());
if (!sectionOpt.has_value()) { if (!sectionOpt.has_value()) {
continue; continue;
} }
auto finalAddress = offsetVal + sectionOpt->getAddress(); auto finalAddress = offsetVal + sectionOpt.value()->getAddress();
pluginInfo->addFunctionSymbolData(std::make_shared<FunctionSymbolData>(name, (void *) finalAddress, (uint32_t) size));
pluginInfo.addFunctionSymbolData(FunctionSymbolData(name, (void *) finalAddress, (uint32_t) size));
} }
} }
} }
@ -238,14 +240,14 @@ PluginInformationFactory::load(const PluginData &pluginData, MEMHeapHandle heapH
} }
// Save the addresses for the allocated memory. This way we can free it again :) // Save the addresses for the allocated memory. This way we can free it again :)
pluginInfo.allocatedDataMemoryAddress = data_data; pluginInfo->allocatedDataMemoryAddress = data_data;
pluginInfo.allocatedTextMemoryAddress = text_data; pluginInfo->allocatedTextMemoryAddress = text_data;
return pluginInfo; return pluginInfo;
} }
std::vector<RelocationData> PluginInformationFactory::getImportRelocationData(const elfio &reader, uint8_t **destinations) { std::vector<std::shared_ptr<RelocationData>> PluginInformationFactory::getImportRelocationData(const elfio &reader, uint8_t **destinations) {
std::vector<RelocationData> result; std::vector<std::shared_ptr<RelocationData>> result;
std::map<uint32_t, std::string> infoMap; std::map<uint32_t, std::string> infoMap;
@ -302,11 +304,10 @@ std::vector<RelocationData> PluginInformationFactory::getImportRelocationData(co
continue; continue;
} }
ImportRPLInformation rplInfo(rplName, isData); auto rplInfo = std::make_shared<ImportRPLInformation>(rplName, isData);
uint32_t section_index = psec->get_info(); uint32_t section_index = psec->get_info();
result.push_back(std::make_shared<RelocationData>(type, offset - 0x02000000, addend, (void *) (destinations[section_index]), sym_name, rplInfo));
result.emplace_back(type, offset - 0x02000000, addend, (void *) (destinations[section_index]), sym_name, rplInfo);
} }
} }
} }

View File

@ -29,12 +29,12 @@
class PluginInformationFactory { class PluginInformationFactory {
public: public:
static std::optional<PluginInformation> static std::optional<std::shared_ptr<PluginInformation>>
load(const PluginData &pluginData, MEMHeapHandle heaphandle, relocation_trampolin_entry_t *trampolin_data, uint32_t trampolin_data_length, uint8_t trampolinId); load(const std::shared_ptr<PluginData> &pluginData, MEMHeapHandle heaphandle, relocation_trampolin_entry_t *trampolin_data, uint32_t trampolin_data_length, uint8_t trampolinId);
static bool static bool
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, 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,
uint8_t trampolinId); uint8_t trampolinId);
static std::vector<RelocationData> getImportRelocationData(const elfio &reader, uint8_t **destinations); static std::vector<std::shared_ptr<RelocationData>> getImportRelocationData(const elfio &reader, uint8_t **destinations);
}; };

View File

@ -16,31 +16,28 @@
****************************************************************************/ ****************************************************************************/
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h> #include <dirent.h>
#include <whb/file.h> #include <whb/file.h>
#include <memory>
#include "../utils/StringTools.h" #include "../utils/StringTools.h"
#include "PluginMetaInformationFactory.h" #include "PluginMetaInformationFactory.h"
#include "PluginMetaInformation.h"
#include "../elfio/elfio.hpp"
#include "../utils/logger.h"
using namespace ELFIO; using namespace ELFIO;
std::optional<PluginMetaInformation> PluginMetaInformationFactory::loadPlugin(const PluginData &pluginData) { std::optional<std::shared_ptr<PluginMetaInformation>> PluginMetaInformationFactory::loadPlugin(const std::shared_ptr<PluginData> &pluginData) {
if (pluginData.buffer == nullptr) { if (pluginData->buffer == nullptr) {
DEBUG_FUNCTION_LINE("Buffer was nullptr"); DEBUG_FUNCTION_LINE("Buffer was nullptr");
return std::nullopt; return std::nullopt;
} }
elfio reader; elfio reader;
if (!reader.load((char *) pluginData.buffer, pluginData.length)) { if (!reader.load((char *) pluginData->buffer, pluginData->length)) {
DEBUG_FUNCTION_LINE("Can't process PluginData in elfio"); DEBUG_FUNCTION_LINE("Can't process PluginData in elfio");
return std::nullopt; return std::nullopt;
} }
return loadPlugin(reader); return loadPlugin(reader);
} }
std::optional<PluginMetaInformation> PluginMetaInformationFactory::loadPlugin(std::string &filePath) { std::optional<std::shared_ptr<PluginMetaInformation>> PluginMetaInformationFactory::loadPlugin(std::string &filePath) {
elfio reader; elfio reader;
if (!reader.load(filePath)) { if (!reader.load(filePath)) {
DEBUG_FUNCTION_LINE("Can't find or process ELF file"); DEBUG_FUNCTION_LINE("Can't find or process ELF file");
@ -49,7 +46,7 @@ std::optional<PluginMetaInformation> PluginMetaInformationFactory::loadPlugin(st
return loadPlugin(reader); return loadPlugin(reader);
} }
std::optional<PluginMetaInformation> PluginMetaInformationFactory::loadPlugin(char *buffer, size_t size) { std::optional<std::shared_ptr<PluginMetaInformation>> PluginMetaInformationFactory::loadPlugin(char *buffer, size_t size) {
elfio reader; elfio reader;
if (!reader.load(buffer, size)) { if (!reader.load(buffer, size)) {
DEBUG_FUNCTION_LINE("Can't find or process ELF file"); DEBUG_FUNCTION_LINE("Can't find or process ELF file");
@ -59,10 +56,10 @@ std::optional<PluginMetaInformation> PluginMetaInformationFactory::loadPlugin(ch
return loadPlugin(reader); return loadPlugin(reader);
} }
std::optional<PluginMetaInformation> PluginMetaInformationFactory::loadPlugin(const elfio &reader) { std::optional<std::shared_ptr<PluginMetaInformation>> PluginMetaInformationFactory::loadPlugin(const elfio &reader) {
size_t pluginSize = 0; size_t pluginSize = 0;
PluginMetaInformation pluginInfo; auto pluginInfo = std::shared_ptr<PluginMetaInformation>(new PluginMetaInformation);
uint32_t sec_num = reader.sections.size(); uint32_t sec_num = reader.sections.size();
@ -99,19 +96,19 @@ std::optional<PluginMetaInformation> PluginMetaInformationFactory::loadPlugin(co
std::string value(curEntry + firstFound + 1); std::string value(curEntry + firstFound + 1);
if (key == "name") { if (key == "name") {
pluginInfo.setName(value); pluginInfo->setName(value);
} else if (key == "author") { } else if (key == "author") {
pluginInfo.setAuthor(value); pluginInfo->setAuthor(value);
} else if (key == "version") { } else if (key == "version") {
pluginInfo.setVersion(value); pluginInfo->setVersion(value);
} else if (key == "license") { } else if (key == "license") {
pluginInfo.setLicense(value); pluginInfo->setLicense(value);
} else if (key == "buildtimestamp") { } else if (key == "buildtimestamp") {
pluginInfo.setBuildTimestamp(value); pluginInfo->setBuildTimestamp(value);
} else if (key == "description") { } else if (key == "description") {
pluginInfo.setDescription(value); pluginInfo->setDescription(value);
} else if (key == "storage_id") { } else if (key == "storage_id") {
pluginInfo.setStorageId(value); pluginInfo->setStorageId(value);
} else if (key == "wups") { } else if (key == "wups") {
if (value != "0.6.1") { if (value != "0.6.1") {
DEBUG_FUNCTION_LINE("Warning: Ignoring plugin - Unsupported WUPS version: %s.", value.c_str()); DEBUG_FUNCTION_LINE("Warning: Ignoring plugin - Unsupported WUPS version: %s.", value.c_str());
@ -124,7 +121,7 @@ std::optional<PluginMetaInformation> PluginMetaInformationFactory::loadPlugin(co
} }
} }
pluginInfo.setSize(pluginSize); pluginInfo->setSize(pluginSize);
return pluginInfo; return pluginInfo;
} }

View File

@ -19,17 +19,18 @@
#include <optional> #include <optional>
#include <string> #include <string>
#include <memory>
#include <vector> #include <vector>
#include "PluginMetaInformation.h" #include "PluginMetaInformation.h"
#include "PluginData.h" #include "PluginData.h"
class PluginMetaInformationFactory { class PluginMetaInformationFactory {
public: public:
static std::optional<PluginMetaInformation> loadPlugin(const PluginData &pluginData); static std::optional<std::shared_ptr<PluginMetaInformation>> loadPlugin(const std::shared_ptr<PluginData> &pluginData);
static std::optional<PluginMetaInformation> loadPlugin(std::string &filePath); static std::optional<std::shared_ptr<PluginMetaInformation>> loadPlugin(std::string &filePath);
static std::optional<PluginMetaInformation> loadPlugin(char *buffer, size_t size); static std::optional<std::shared_ptr<PluginMetaInformation>> loadPlugin(char *buffer, size_t size);
static std::optional<PluginMetaInformation> loadPlugin(const elfio &reader); static std::optional<std::shared_ptr<PluginMetaInformation>> loadPlugin(const elfio &reader);
}; };

View File

@ -18,18 +18,19 @@
#pragma once #pragma once
#include <string> #include <string>
#include <utility>
#include "ImportRPLInformation.h" #include "ImportRPLInformation.h"
class RelocationData { class RelocationData {
public: public:
RelocationData(const char type, size_t offset, int32_t addend, void *destination, std::string &name, const ImportRPLInformation &rplInfo) : RelocationData(const char type, size_t offset, int32_t addend, void *destination, std::string &name, std::shared_ptr<ImportRPLInformation> rplInfo) :
type(type), type(type),
offset(offset), offset(offset),
addend(addend), addend(addend),
destination(destination), destination(destination),
name(name), name(name),
rplInfo(rplInfo) { rplInfo(std::move(rplInfo)) {
} }
RelocationData(const RelocationData &o2) = default; RelocationData(const RelocationData &o2) = default;
@ -56,7 +57,7 @@ public:
return name; return name;
} }
[[nodiscard]] const ImportRPLInformation &getImportRPLInformation() const { [[nodiscard]] const std::shared_ptr<ImportRPLInformation> &getImportRPLInformation() const {
return rplInfo; return rplInfo;
} }
@ -66,5 +67,5 @@ private:
int32_t addend; int32_t addend;
void *destination; void *destination;
std::string name; std::string name;
ImportRPLInformation rplInfo; std::shared_ptr<ImportRPLInformation> rplInfo;
}; };

View File

@ -9,7 +9,7 @@
#include "exports.h" #include "exports.h"
#include <wums.h> #include <wums.h>
void fillPluginInformation(plugin_information *out, PluginMetaInformation *metaInformation) { void fillPluginInformation(plugin_information *out, const std::shared_ptr<PluginMetaInformation>& metaInformation) {
out->plugin_information_version = PLUGIN_INFORMATION_VERSION; out->plugin_information_version = PLUGIN_INFORMATION_VERSION;
strncpy(out->author, metaInformation->getAuthor().c_str(), sizeof(out->author) - 1); strncpy(out->author, metaInformation->getAuthor().c_str(), sizeof(out->author) - 1);
strncpy(out->buildTimestamp, metaInformation->getBuildTimestamp().c_str(), sizeof(out->buildTimestamp) - 1); strncpy(out->buildTimestamp, metaInformation->getBuildTimestamp().c_str(), sizeof(out->buildTimestamp) - 1);
@ -27,7 +27,7 @@ extern "C" PluginBackendApiErrorType WUPSLoadAndLinkByDataHandle(const plugin_da
for (uint32_t i = 0; i < plugin_data_handle_list_size; i++) { for (uint32_t i = 0; i < plugin_data_handle_list_size; i++) {
plugin_data_handle handle = plugin_data_handle_list[i]; plugin_data_handle handle = plugin_data_handle_list[i];
auto *pluginData = (PluginData *) handle; auto *pluginData = (PluginData *) handle;
PluginDataPersistence::save(&gLinkOnReload.plugin_data[gLinkOnReload.number_used_plugins], *pluginData); PluginDataPersistence::save(&gLinkOnReload.plugin_data[gLinkOnReload.number_used_plugins], pluginData);
gLinkOnReload.number_used_plugins++; gLinkOnReload.number_used_plugins++;
} }
@ -65,7 +65,7 @@ extern "C" PluginBackendApiErrorType WUPSDeletePluginData(const plugin_data_hand
} }
extern "C" PluginBackendApiErrorType WUPSLoadPluginAsData(GetPluginInformationInputType inputType, const char *path, char *buffer, size_t size, plugin_data_handle *out) { extern "C" PluginBackendApiErrorType WUPSLoadPluginAsData(GetPluginInformationInputType inputType, const char *path, char *buffer, size_t size, plugin_data_handle *out) {
std::optional<PluginData> pluginData; std::optional<std::shared_ptr<PluginData>> pluginData;
if (inputType == PLUGIN_INFORMATION_INPUT_TYPE_PATH && path != nullptr) { if (inputType == PLUGIN_INFORMATION_INPUT_TYPE_PATH && path != nullptr) {
pluginData = PluginDataFactory::load(path, gPluginDataHeap); pluginData = PluginDataFactory::load(path, gPluginDataHeap);
} else if (inputType == PLUGIN_INFORMATION_INPUT_TYPE_BUFFER && buffer != nullptr && size > 0) { } else if (inputType == PLUGIN_INFORMATION_INPUT_TYPE_BUFFER && buffer != nullptr && size > 0) {
@ -85,7 +85,7 @@ extern "C" PluginBackendApiErrorType WUPSLoadPluginAsData(GetPluginInformationIn
DEBUG_FUNCTION_LINE("PLUGIN_BACKEND_API_ERROR_INVALID_ARG"); DEBUG_FUNCTION_LINE("PLUGIN_BACKEND_API_ERROR_INVALID_ARG");
return PLUGIN_BACKEND_API_ERROR_INVALID_ARG; return PLUGIN_BACKEND_API_ERROR_INVALID_ARG;
} else { } else {
auto *pluginDataHandle = new PluginData(pluginData.value()); auto *pluginDataHandle = new PluginData(*pluginData.value());
*out = (uint32_t) pluginDataHandle; *out = (uint32_t) pluginDataHandle;
} }
@ -101,7 +101,7 @@ extern "C" PluginBackendApiErrorType WUPSLoadPluginAsDataByBuffer(plugin_data_ha
} }
extern "C" PluginBackendApiErrorType WUPSGetPluginMetaInformation(GetPluginInformationInputType inputType, const char *path, char *buffer, size_t size, plugin_information *output) { extern "C" PluginBackendApiErrorType WUPSGetPluginMetaInformation(GetPluginInformationInputType inputType, const char *path, char *buffer, size_t size, plugin_information *output) {
std::optional<PluginMetaInformation> pluginInfo; std::optional<std::shared_ptr<PluginMetaInformation>> pluginInfo;
if (inputType == PLUGIN_INFORMATION_INPUT_TYPE_PATH && path != nullptr) { if (inputType == PLUGIN_INFORMATION_INPUT_TYPE_PATH && path != nullptr) {
std::string pathStr(path); std::string pathStr(path);
pluginInfo = PluginMetaInformationFactory::loadPlugin(pathStr); pluginInfo = PluginMetaInformationFactory::loadPlugin(pathStr);
@ -121,7 +121,7 @@ extern "C" PluginBackendApiErrorType WUPSGetPluginMetaInformation(GetPluginInfor
DEBUG_FUNCTION_LINE("PLUGIN_BACKEND_API_ERROR_INVALID_ARG"); DEBUG_FUNCTION_LINE("PLUGIN_BACKEND_API_ERROR_INVALID_ARG");
return PLUGIN_BACKEND_API_ERROR_INVALID_ARG; return PLUGIN_BACKEND_API_ERROR_INVALID_ARG;
} else { } else {
fillPluginInformation(output, &pluginInfo.value()); fillPluginInformation(output, pluginInfo.value());
} }
return PLUGIN_BACKEND_API_ERROR_NONE; return PLUGIN_BACKEND_API_ERROR_NONE;
} }
@ -140,7 +140,7 @@ extern "C" PluginBackendApiErrorType WUPSGetPluginDataForContainerHandles(const
for (uint32_t i = 0; i < buffer_size; i++) { for (uint32_t i = 0; i < buffer_size; i++) {
auto handle = plugin_container_handle_list[i]; auto handle = plugin_container_handle_list[i];
auto *container = (PluginContainer *) handle; auto *container = (PluginContainer *) handle;
auto *pluginData = new PluginData(container->getPluginData()); auto *pluginData = new PluginData(*container->getPluginData());
plugin_data_list[i] = (uint32_t) pluginData; plugin_data_list[i] = (uint32_t) pluginData;
} }
} else { } else {
@ -158,14 +158,14 @@ extern "C" PluginBackendApiErrorType WUPSGetMetaInformation(const plugin_contain
auto *container = (PluginContainer *) handle; auto *container = (PluginContainer *) handle;
plugin_information_list[i].plugin_information_version = PLUGIN_INFORMATION_VERSION; plugin_information_list[i].plugin_information_version = PLUGIN_INFORMATION_VERSION;
strncpy(plugin_information_list[i].storageId, container->metaInformation.getStorageId().c_str(), sizeof(plugin_information_list[i].storageId) - 1); strncpy(plugin_information_list[i].storageId, container->metaInformation->getStorageId().c_str(), sizeof(plugin_information_list[i].storageId) - 1);
strncpy(plugin_information_list[i].author, container->metaInformation.getAuthor().c_str(), sizeof(plugin_information_list[i].author) - 1); strncpy(plugin_information_list[i].author, container->metaInformation->getAuthor().c_str(), sizeof(plugin_information_list[i].author) - 1);
strncpy(plugin_information_list[i].buildTimestamp, container->metaInformation.getBuildTimestamp().c_str(), sizeof(plugin_information_list[i].buildTimestamp) - 1); strncpy(plugin_information_list[i].buildTimestamp, container->metaInformation->getBuildTimestamp().c_str(), sizeof(plugin_information_list[i].buildTimestamp) - 1);
strncpy(plugin_information_list[i].description, container->metaInformation.getDescription().c_str(), sizeof(plugin_information_list[i].description) - 1); strncpy(plugin_information_list[i].description, container->metaInformation->getDescription().c_str(), sizeof(plugin_information_list[i].description) - 1);
strncpy(plugin_information_list[i].name, container->metaInformation.getName().c_str(), sizeof(plugin_information_list[i].name) - 1); strncpy(plugin_information_list[i].name, container->metaInformation->getName().c_str(), sizeof(plugin_information_list[i].name) - 1);
strncpy(plugin_information_list[i].license, container->metaInformation.getLicense().c_str(), sizeof(plugin_information_list[i].license) - 1); strncpy(plugin_information_list[i].license, container->metaInformation->getLicense().c_str(), sizeof(plugin_information_list[i].license) - 1);
strncpy(plugin_information_list[i].version, container->metaInformation.getVersion().c_str(), sizeof(plugin_information_list[i].version) - 1); strncpy(plugin_information_list[i].version, container->metaInformation->getVersion().c_str(), sizeof(plugin_information_list[i].version) - 1);
plugin_information_list[i].size = container->metaInformation.getSize(); plugin_information_list[i].size = container->metaInformation->getSize();
} }
} else { } else {
DEBUG_FUNCTION_LINE("PLUGIN_BACKEND_API_ERROR_INVALID_ARG"); DEBUG_FUNCTION_LINE("PLUGIN_BACKEND_API_ERROR_INVALID_ARG");
@ -184,7 +184,7 @@ extern "C" PluginBackendApiErrorType WUPSGetLoadedPlugins(plugin_container_handl
uint32_t counter = 0; uint32_t counter = 0;
for (auto &plugin: plugins) { for (auto &plugin: plugins) {
if (counter < buffer_size) { if (counter < buffer_size) {
auto *container = new PluginContainer(plugin); auto *container = new PluginContainer(*plugin);
io_handles[counter] = (uint32_t) container; io_handles[counter] = (uint32_t) container;
counter++; counter++;
} else { } else {