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/dynload.h>
#include <coreinit/memdefaultheap.h>
#include <memory>
#include "patcher/hooks_patcher_static.h"
#include "plugin/PluginContainer.h"
@ -12,11 +14,11 @@
#include "hooks.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;
for (auto const &cur: relocData) {
uint32_t functionAddress = 0;
const std::string &functionName = cur.getName();
const std::string &functionName = cur->getName();
if (functionName == "MEMAllocFromDefaultHeap") {
OSDynLoad_Module rplHandle;
@ -33,8 +35,8 @@ bool PluginManagement::doRelocation(const std::vector<RelocationData> &relocData
}
if (functionAddress == 0) {
std::string rplName = cur.getImportRPLInformation().getName();
int32_t isData = cur.getImportRPLInformation().isData();
std::string rplName = cur->getImportRPLInformation()->getName();
int32_t isData = cur->getImportRPLInformation()->isData();
OSDynLoad_Module rplHandle = nullptr;
if (moduleHandleCache.count(rplName) > 0) {
rplHandle = moduleHandleCache[rplName];
@ -51,7 +53,7 @@ bool PluginManagement::doRelocation(const std::vector<RelocationData> &relocData
} else {
//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");
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) {
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");
}
}
}
void PluginManagement::memsetBSS(const std::vector<PluginContainer> &plugins) {
void PluginManagement::memsetBSS(const std::vector<std::shared_ptr<PluginContainer>> &plugins) {
for (auto &pluginContainer: plugins) {
auto sbssSection = pluginContainer.getPluginInformation().getSectionInfo(".sbss");
auto sbssSection = pluginContainer->getPluginInformation()->getSectionInfo(".sbss");
if (sbssSection) {
DEBUG_FUNCTION_LINE_VERBOSE("memset .sbss %08X (%d)", sbssSection->getAddress(), sbssSection->getSize());
memset((void *) sbssSection->getAddress(), 0, sbssSection->getSize());
DEBUG_FUNCTION_LINE_VERBOSE("memset .sbss %08X (%d)", sbssSection.value()->getAddress(), sbssSection.value()->getSize());
memset((void *) sbssSection.value()->getAddress(), 0, sbssSection.value()->getSize());
}
auto bssSection = pluginContainer.getPluginInformation().getSectionInfo(".bss");
auto bssSection = pluginContainer->getPluginInformation()->getSectionInfo(".bss");
if (bssSection) {
DEBUG_FUNCTION_LINE_VERBOSE("memset .bss %08X (%d)", bssSection->getAddress(), bssSection->getSize());
memset((void *) bssSection->getAddress(), 0, bssSection->getSize());
DEBUG_FUNCTION_LINE_VERBOSE("memset .bss %08X (%d)", bssSection.value()->getAddress(), bssSection.value()->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);
}
std::vector<PluginContainer>
PluginManagement::loadPlugins(const std::vector<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>>
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<std::shared_ptr<PluginContainer>> plugins;
for (auto &pluginData: pluginList) {
DEBUG_FUNCTION_LINE_VERBOSE("Load meta information");
auto metaInfo = PluginMetaInformationFactory::loadPlugin(pluginData);
if (metaInfo) {
PluginContainer container;
container.setMetaInformation(metaInfo.value());
container.setPluginData(pluginData);
auto container = std::make_shared<PluginContainer>();
container->setMetaInformation(metaInfo.value());
container->setPluginData(pluginData);
plugins.push_back(container);
} else {
DEBUG_FUNCTION_LINE("Failed to get meta information");
@ -204,12 +206,12 @@ PluginManagement::loadPlugins(const std::vector<PluginData> &pluginList, MEMHeap
}
uint32_t trampolineID = 0;
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) {
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;
}
pluginContainer.setPluginInformation(info.value());
pluginContainer->setPluginInformation(info.value());
}
return plugins;
}

View File

@ -6,19 +6,19 @@
class PluginManagement {
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 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 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);
};

View File

@ -6,6 +6,7 @@
#include <coreinit/cache.h>
#include <coreinit/dynload.h>
#include <coreinit/memdefaultheap.h>
#include <memory>
#include "plugin/PluginContainer.h"
#include "globals.h"
#include "plugin/PluginDataFactory.h"
@ -120,14 +121,14 @@ WUMS_APPLICATION_STARTS() {
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);
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());
std::vector<PluginContainer> plugins = PluginManagement::loadPlugins(pluginList, gPluginDataHeap, gTrampolineData, gTrampolineDataSize);
auto plugins = PluginManagement::loadPlugins(pluginList, gPluginDataHeap, gTrampolineData, gTrampolineDataSize);
for (auto &pluginContainer: plugins) {
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());
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());
}
if (!PluginContainerPersistence::savePlugin(gPluginInformation, pluginContainer, gPluginDataHeap)) {
DEBUG_FUNCTION_LINE("Failed to save plugin");
@ -138,7 +139,7 @@ WUMS_APPLICATION_STARTS() {
}
if (gLinkOnReload.loadOnReload) {
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++) {
auto pluginData = PluginDataPersistence::load(&gLinkOnReload.plugin_data[i]);
pluginDataList.push_back(pluginData);
@ -148,7 +149,7 @@ WUMS_APPLICATION_STARTS() {
plugin_information_single_t *plugin = &(gPluginInformation->plugin_data[plugin_index]);
BOOL doDelete = true;
for (auto &pluginData: pluginDataList) {
if (pluginData.buffer == plugin->data.buffer) {
if (pluginData->buffer == plugin->data.buffer) {
doDelete = false;
break;
}
@ -177,10 +178,10 @@ WUMS_APPLICATION_STARTS() {
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) {
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)) {
DEBUG_FUNCTION_LINE("Failed to save plugin");
}
@ -190,7 +191,7 @@ WUMS_APPLICATION_STARTS() {
}
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::memsetBSS(plugins);

View File

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

View File

@ -3,6 +3,7 @@
#include <wums/defines/dynamic_linking_defines.h>
#include <string>
#include <vector>
#include <memory>
#include "RelocationData.h"
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 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
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 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,
dyn_linking_function_t *functionName,

View File

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

View File

@ -1,5 +1,7 @@
#include <coreinit/cache.h>
#include <memory>
#include "PluginContainer.h"
#include "PluginInformationFactory.h"
#include "PluginMetaInformationFactory.h"
@ -7,10 +9,10 @@
#include "PluginDataPersistence.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;
auto pluginName = plugin.getMetaInformation().getName();
auto pluginName = plugin->getMetaInformation()->getName();
if (plugin_count >= MAXIMUM_PLUGINS - 1) {
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.
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;
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.");
}
strncpy(plugin_meta_data->name, pluginMetaInfo.getName().c_str(), MAXIMUM_PLUGIN_META_FIELD_LENGTH - 1);
if (pluginMetaInfo.getAuthor().size() >= MAXIMUM_PLUGIN_META_FIELD_LENGTH) {
strncpy(plugin_meta_data->name, pluginMetaInfo->getName().c_str(), MAXIMUM_PLUGIN_META_FIELD_LENGTH - 1);
if (pluginMetaInfo->getAuthor().size() >= MAXIMUM_PLUGIN_META_FIELD_LENGTH) {
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.");
}
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.");
}
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.");
}
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("%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.");
}
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
std::vector<RelocationData> relocationData = pluginInfo.getRelocationDataList();
auto relocationData = pluginInfo->getRelocationDataList();
for (auto &reloc: relocationData) {
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");
@ -73,8 +75,8 @@ bool PluginContainerPersistence::savePlugin(plugin_information_t *pluginInformat
}
}
std::vector<FunctionData> function_data_list = pluginInfo.getFunctionDataList();
std::vector<HookData> hook_data_list = pluginInfo.getHookDataList();
auto function_data_list = pluginInfo->getFunctionDataList();
auto hook_data_list = pluginInfo->getHookDataList();
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);
@ -92,48 +94,48 @@ bool PluginContainerPersistence::savePlugin(plugin_information_t *pluginInformat
/* Store function replacement information */
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];
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());
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());
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->library = (function_replacement_library_type_t) curFunction.getLibrary();
function_data->replaceAddr = (uint32_t) curFunction.getReplaceAddress();
function_data->replaceCall = (uint32_t) curFunction.getReplaceCall();
function_data->physicalAddr = (uint32_t) curFunction.getPhysicalAddress();
function_data->virtualAddr = (uint32_t) curFunction.getVirtualAddress();
function_data->targetProcess = curFunction.getTargetProcess();
function_data->library = (function_replacement_library_type_t) curFunction->getLibrary();
function_data->replaceAddr = (uint32_t) curFunction->getReplaceAddress();
function_data->replaceCall = (uint32_t) curFunction->getReplaceCall();
function_data->physicalAddr = (uint32_t) curFunction->getPhysicalAddress();
function_data->virtualAddr = (uint32_t) curFunction->getVirtualAddress();
function_data->targetProcess = curFunction->getTargetProcess();
plugin_data->info.number_used_functions++;
i++;
}
i = 0;
for (auto &curHook: pluginInfo.getHookDataList()) {
for (auto &curHook: pluginInfo->getHookDataList()) {
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->type = curHook.getType();
hook_data->func_pointer = (void *) curHook->getFunctionPointer();
hook_data->type = curHook->getType();
plugin_data->info.number_used_hooks++;
i++;
}
/* Saving SectionInfos */
for (auto &curSection: pluginInfo.getSectionInfoList()) {
for (auto &curSection: pluginInfo->getSectionInfoList()) {
bool foundFreeSlot = false;
uint32_t slot = 0;
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) {
foundFreeSlot = true;
slot = j;
@ -141,31 +143,30 @@ bool PluginContainerPersistence::savePlugin(plugin_information_t *pluginInformat
}
}
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) {
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;
}
strncpy(sectionInfo->name, curSection.first.c_str(), MAXIMUM_PLUGIN_SECTION_NAME_LENGTH - 1);
sectionInfo->addr = curSection.second.getAddress();
sectionInfo->size = curSection.second.getSize();
sectionInfo->addr = curSection.second->getAddress();
sectionInfo->size = curSection.second->getSize();
} else {
DEBUG_FUNCTION_LINE("Failed to store SectionInfos");
return false;
}
}
plugin_data->info.trampolinId = pluginInfo.getTrampolinId();
plugin_data->info.allocatedTextMemoryAddress = pluginInfo.allocatedTextMemoryAddress;
plugin_data->info.allocatedDataMemoryAddress = pluginInfo.allocatedDataMemoryAddress;
plugin_data->info.trampolinId = pluginInfo->getTrampolinId();
plugin_data->info.allocatedTextMemoryAddress = pluginInfo->allocatedTextMemoryAddress;
plugin_data->info.allocatedDataMemoryAddress = pluginInfo->allocatedDataMemoryAddress;
uint32_t entryCount = pluginInfo.getFunctionSymbolDataList().size();
uint32_t entryCount = pluginInfo->getFunctionSymbolDataList().size();
if (entryCount > 0) {
/* Saving SectionInfos */
// Saving SectionInfos
uint32_t funcSymStringLen = 1;
for (auto &curFuncSym: pluginInfo.getFunctionSymbolDataList()) {
funcSymStringLen += curFuncSym.getName().length() + 1;
for (auto &curFuncSym: pluginInfo->getFunctionSymbolDataList()) {
funcSymStringLen += curFuncSym->getName().length() + 1;
}
char *stringTable = (char *) MEMAllocFromExpHeapEx(heapHandle, funcSymStringLen, 0x4);
@ -186,12 +187,12 @@ bool PluginContainerPersistence::savePlugin(plugin_information_t *pluginInformat
uint32_t curStringOffset = 0;
uint32_t curEntryIndex = 0;
for (auto &curFuncSym: pluginInfo.getFunctionSymbolDataList()) {
entryTable[curEntryIndex].address = curFuncSym.getAddress();
for (auto &curFuncSym: pluginInfo->getFunctionSymbolDataList()) {
entryTable[curEntryIndex].address = curFuncSym->getAddress();
entryTable[curEntryIndex].name = &stringTable[curStringOffset];
entryTable[curEntryIndex].size = curFuncSym.getSize();
auto len = curFuncSym.getName().length() + 1;
memcpy(stringTable + curStringOffset, curFuncSym.getName().c_str(), len);
entryTable[curEntryIndex].size = curFuncSym->getSize();
auto len = curFuncSym->getName().length() + 1;
memcpy(stringTable + curStringOffset, curFuncSym->getName().c_str(), len);
curStringOffset += len;
curEntryIndex++;
}
@ -203,7 +204,7 @@ bool PluginContainerPersistence::savePlugin(plugin_information_t *pluginInformat
plugin_data->info.number_function_symbol_data = entryCount;
/* Copy plugin data */
auto pluginData = plugin.getPluginData();
auto pluginData = plugin->getPluginData();
auto plugin_data_data = &plugin_data->data;
PluginDataPersistence::save(plugin_data_data, pluginData);
@ -216,8 +217,8 @@ bool PluginContainerPersistence::savePlugin(plugin_information_t *pluginInformat
return true;
}
std::vector<PluginContainer> PluginContainerPersistence::loadPlugins(plugin_information_t *pluginInformation) {
std::vector<PluginContainer> result;
std::vector<std::shared_ptr<PluginContainer>> PluginContainerPersistence::loadPlugins(plugin_information_t *pluginInformation) {
std::vector<std::shared_ptr<PluginContainer>> result;
if (pluginInformation == nullptr) {
DEBUG_FUNCTION_LINE("pluginInformation == nullptr");
return result;
@ -234,27 +235,27 @@ std::vector<PluginContainer> PluginContainerPersistence::loadPlugins(plugin_info
// Copy data from struct.
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);
metaInformation.setAuthor(meta->author);
metaInformation.setVersion(meta->version);
metaInformation.setBuildTimestamp(meta->buildTimestamp);
metaInformation.setLicense(meta->license);
metaInformation.setDescription(meta->descripion);
metaInformation.setSize(meta->size);
metaInformation.setName(meta->name);
metaInformation.setStorageId(meta->storageId);
metaInformation->setAuthor(meta->author);
metaInformation->setVersion(meta->version);
metaInformation->setBuildTimestamp(meta->buildTimestamp);
metaInformation->setLicense(meta->license);
metaInformation->setDescription(meta->descripion);
metaInformation->setSize(meta->size);
metaInformation->setName(meta->name);
metaInformation->setStorageId(meta->storageId);
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.allocatedTextMemoryAddress = plugin_data->info.allocatedTextMemoryAddress;
curPluginInformation.allocatedDataMemoryAddress = plugin_data->info.allocatedDataMemoryAddress;
curPluginInformation->setTrampolinId(plugin_data->info.trampolinId);
curPluginInformation->allocatedTextMemoryAddress = plugin_data->info.allocatedTextMemoryAddress;
curPluginInformation->allocatedDataMemoryAddress = plugin_data->info.allocatedDataMemoryAddress;
for (auto &curItem: plugin_data->info.sectionInfos) {
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);
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 */
@ -276,14 +277,13 @@ std::vector<PluginContainer> PluginContainerPersistence::loadPlugins(plugin_info
for (uint32_t j = 0; j < hookCount; j++) {
replacement_data_hook_t *hook_entry = &(plugin_data->info.hooks[j]);
HookData curHook(hook_entry->func_pointer, hook_entry->type);
curPluginInformation.addHookData(curHook);
curPluginInformation->addHookData(std::make_shared<HookData>(hook_entry->func_pointer, hook_entry->type));
}
bool storageHasId = true;
for (auto const &value: curPluginInformation.getHookDataList()) {
if (value.getType() == WUPS_LOADER_HOOK_INIT_STORAGE &&
metaInformation.getStorageId().empty()) {
for (auto const &value: curPluginInformation->getHookDataList()) {
if (value->getType() == WUPS_LOADER_HOOK_INIT_STORAGE &&
metaInformation->getStorageId().empty()) {
storageHasId = false;
}
}
@ -302,9 +302,10 @@ std::vector<PluginContainer> PluginContainerPersistence::loadPlugins(plugin_info
for (uint32_t j = 0; j < functionReplaceCount; 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,
(void *) entry->replaceCall, entry->targetProcess);
curPluginInformation.addFunctionData(func);
auto func = std::make_shared<FunctionData>((void *) entry->physicalAddr, (void *) entry->virtualAddr, entry->function_name, (function_replacement_library_type_t) entry->library,
(void *) entry->replaceAddr,
(void *) entry->replaceCall, entry->targetProcess);
curPluginInformation->addFunctionData(func);
}
/* load relocation data */
@ -323,24 +324,24 @@ std::vector<PluginContainer> PluginContainerPersistence::loadPlugins(plugin_info
DEBUG_FUNCTION_LINE("functionEntry was nullptr, skipping relocation entry");
continue;
}
ImportRPLInformation rplInfo(importEntry->importName, importEntry->isData);
auto rplInfo = std::make_shared<ImportRPLInformation>(importEntry->importName, importEntry->isData);
std::string functionName(functionEntry->functionName);
RelocationData reloc(linking_entry.type, linking_entry.offset, linking_entry.addend, linking_entry.destination, functionName, rplInfo);
curPluginInformation.addRelocationData(reloc);
auto reloc = std::make_shared<RelocationData>(linking_entry.type, linking_entry.offset, linking_entry.addend, linking_entry.destination, functionName, rplInfo);
curPluginInformation->addRelocationData(reloc);
}
/* load function symbol data */
for (uint32_t j = 0; j < plugin_data->info.number_function_symbol_data; j++) {
auto symbol_data = &plugin_data->info.function_symbol_data[j];
std::string symbol_name = symbol_data->name;
FunctionSymbolData funSymbolData(symbol_name, (void *) symbol_data->address, symbol_data->size);
curPluginInformation.addFunctionSymbolData(funSymbolData);
auto funSymbolData = std::make_shared<FunctionSymbolData>(symbol_name, (void *) symbol_data->address, symbol_data->size);
curPluginInformation->addFunctionSymbolData(funSymbolData);
}
PluginContainer container;
container.setMetaInformation(metaInformation);
container.setPluginData(pluginData);
container.setPluginInformation(curPluginInformation);
auto container = std::make_shared<PluginContainer>();
container->setMetaInformation(metaInformation);
container->setPluginData(pluginData);
container->setPluginInformation(curPluginInformation);
result.push_back(container);
}
return result;

View File

@ -5,7 +5,7 @@
class PluginContainerPersistence {
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"
std::vector<PluginData> PluginDataFactory::loadDir(const std::string &path, MEMHeapHandle heapHandle) {
std::vector<PluginData> result;
std::vector<std::shared_ptr<PluginData>> PluginDataFactory::loadDir(const std::string &path, MEMHeapHandle heapHandle) {
std::vector<std::shared_ptr<PluginData>> result;
struct dirent *dp;
DIR *dfd = nullptr;
@ -64,7 +64,7 @@ std::vector<PluginData> PluginDataFactory::loadDir(const std::string &path, MEMH
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.
// The use of gcount() below will compensate for a failure here.
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);
}
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()) {
return std::nullopt;
}
PluginData pluginData(buffer, heapHandle, eMemoryTypes::eMemTypeMEM2);
return pluginData;
return std::shared_ptr<PluginData>(new PluginData(buffer, heapHandle, eMemoryTypes::eMemTypeMEM2));
}

View File

@ -25,9 +25,9 @@
class PluginDataFactory {
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 "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) {
return false;
}
pluginDataStruct->buffer = (char *) plugin.buffer;
pluginDataStruct->bufferLength = plugin.length;
pluginDataStruct->memoryType = plugin.memoryType;
pluginDataStruct->heapHandle = (int) plugin.heapHandle;
pluginDataStruct->buffer = (char *) plugin->buffer;
pluginDataStruct->bufferLength = plugin->length;
pluginDataStruct->memoryType = plugin->memoryType;
pluginDataStruct->heapHandle = (int) plugin->heapHandle;
return true;
}
PluginData PluginDataPersistence::load(plugin_data_t *pluginDataStruct) {
PluginData pluginData;
bool PluginDataPersistence::save(plugin_data_t *pluginDataStruct, PluginData* plugin) {
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;
pluginData.length = pluginDataStruct->bufferLength;
pluginData.memoryType = (eMemoryTypes) pluginDataStruct->memoryType;
pluginData.heapHandle = (MEMHeapHandle) pluginDataStruct->heapHandle;
std::shared_ptr<PluginData> PluginDataPersistence::load(plugin_data_t *pluginDataStruct) {
auto pluginData = std::make_shared<PluginData>();
pluginData->buffer = pluginDataStruct->buffer;
pluginData->length = pluginDataStruct->bufferLength;
pluginData->memoryType = (eMemoryTypes) pluginDataStruct->memoryType;
pluginData->heapHandle = (MEMHeapHandle) pluginDataStruct->heapHandle;
return pluginData;
}

View File

@ -5,7 +5,8 @@
class PluginDataPersistence {
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 <string>
#include <vector>
#include <memory>
#include "PluginMetaInformation.h"
#include "RelocationData.h"
#include "HookData.h"
@ -29,6 +30,14 @@
#include "SectionInfo.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 {
public:
PluginInformation(const PluginInformation &other);
@ -37,47 +46,48 @@ public:
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);
}
[[nodiscard]] const std::vector<HookData> &getHookDataList() const {
[[nodiscard]] const std::vector<std::shared_ptr<HookData>> &getHookDataList() const {
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);
}
[[nodiscard]] const std::vector<FunctionData> &getFunctionDataList() const {
[[nodiscard]] const std::vector<std::shared_ptr<FunctionData>> &getFunctionDataList() const {
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);
}
[[nodiscard]] const std::vector<RelocationData> &getRelocationDataList() const {
[[nodiscard]] const std::vector<std::shared_ptr<RelocationData>> &getRelocationDataList() const {
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);
}
[[nodiscard]] const std::set<FunctionSymbolData> &getFunctionSymbolDataList() const {
[[nodiscard]] const std::set<std::shared_ptr<FunctionSymbolData>, FunctionSymbolDataComparator> &getFunctionSymbolDataList() const {
return symbol_data_list;
}
void addSectionInfo(const SectionInfo &sectionInfo) {
section_info_list[sectionInfo.getName()] = sectionInfo;
void addSectionInfo(const std::shared_ptr<SectionInfo> &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;
}
[[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) {
return section_info_list.at(sectionName);
}
@ -93,11 +103,11 @@ public:
}
private:
std::vector<HookData> hook_data_list;
std::vector<FunctionData> function_data_list;
std::vector<RelocationData> relocation_data_list;
std::set<FunctionSymbolData> symbol_data_list;
std::map<std::string, SectionInfo> section_info_list;
std::vector<std::shared_ptr<HookData>> hook_data_list;
std::vector<std::shared_ptr<FunctionData>> function_data_list;
std::vector<std::shared_ptr<RelocationData>> relocation_data_list;
std::set<std::shared_ptr<FunctionSymbolData>, FunctionSymbolDataComparator> symbol_data_list;
std::map<std::string, std::shared_ptr<SectionInfo>> section_info_list;
uint8_t trampolinId = 0;

View File

@ -15,6 +15,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
****************************************************************************/
#include <memory>
#include <string>
#include <vector>
#include <map>
@ -28,19 +29,20 @@
using namespace ELFIO;
std::optional<PluginInformation>
PluginInformationFactory::load(const PluginData &pluginData, MEMHeapHandle heapHandle, relocation_trampolin_entry_t *trampolin_data, uint32_t trampolin_data_length, uint8_t trampolinId) {
if (pluginData.buffer == nullptr) {
std::optional<std::shared_ptr<PluginInformation>>
PluginInformationFactory::load(const std::shared_ptr<PluginData> &pluginData, MEMHeapHandle heapHandle, relocation_trampolin_entry_t *trampolin_data, uint32_t trampolin_data_length,
uint8_t trampolinId) {
if (pluginData->buffer == nullptr) {
DEBUG_FUNCTION_LINE("Buffer was nullptr");
return std::nullopt;
}
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");
return std::nullopt;
}
PluginInformation pluginInfo;
auto pluginInfo = std::make_shared<PluginInformation>();
uint32_t sec_num = reader.sections.size();
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());
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);
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) {
pluginInfo.addRelocationData(reloc);
pluginInfo->addRelocationData(reloc);
}
DCFlushRange((void *) text_data, text_size);
@ -165,37 +167,38 @@ PluginInformationFactory::load(const PluginData &pluginData, MEMHeapHandle heapH
free(destinations);
pluginInfo.setTrampolinId(trampolinId);
pluginInfo->setTrampolinId(trampolinId);
std::optional<SectionInfo> secInfo = pluginInfo.getSectionInfo(".wups.hooks");
if (secInfo && secInfo->getSize() > 0) {
size_t entries_count = secInfo->getSize() / sizeof(wups_loader_hook_t);
auto *entries = (wups_loader_hook_t *) secInfo->getAddress();
auto secInfo = pluginInfo->getSectionInfo(".wups.hooks");
if (secInfo && secInfo.value()->getSize() > 0) {
size_t entries_count = secInfo.value()->getSize() / sizeof(wups_loader_hook_t);
auto *entries = (wups_loader_hook_t *) secInfo.value()->getAddress();
if (entries != nullptr) {
for (size_t j = 0; j < entries_count; 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);
HookData hook_data((void *) hook->target, hook->type);
pluginInfo.addHookData(hook_data);
DEBUG_FUNCTION_LINE_VERBOSE("Saving hook of plugin Type: %08X, target: %08X"/*,pluginData->getPluginInformation()->getName().c_str()*/, hook->type, (void *) hook->target);
auto hook_data = std::make_shared<HookData>((void *) hook->target, hook->type);
pluginInfo->addHookData(hook_data);
}
}
}
secInfo = pluginInfo.getSectionInfo(".wups.load");
if (secInfo && secInfo->getSize() > 0) {
size_t entries_count = secInfo->getSize() / sizeof(wups_loader_entry_t);
auto *entries = (wups_loader_entry_t *) secInfo->getAddress();
secInfo = pluginInfo->getSectionInfo(".wups.load");
if (secInfo && secInfo.value()->getSize() > 0) {
size_t entries_count = secInfo.value()->getSize() / sizeof(wups_loader_entry_t);
auto *entries = (wups_loader_entry_t *) secInfo.value()->getAddress();
if (entries != nullptr) {
for (size_t j = 0; j < entries_count; 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",
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,
(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,
(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);
pluginInfo.addFunctionData(function_data);
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,
(void *) cur_function->_function.target, (void *) cur_function->_function.call_addr,
(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.
auto sectionVal = reader.sections[section];
auto offsetVal = value - sectionVal->get_address();
auto sectionOpt = pluginInfo.getSectionInfo(sectionVal->get_name());
auto sectionOpt = pluginInfo->getSectionInfo(sectionVal->get_name());
if (!sectionOpt.has_value()) {
continue;
}
auto finalAddress = offsetVal + sectionOpt->getAddress();
pluginInfo.addFunctionSymbolData(FunctionSymbolData(name, (void *) finalAddress, (uint32_t) size));
auto finalAddress = offsetVal + sectionOpt.value()->getAddress();
pluginInfo->addFunctionSymbolData(std::make_shared<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 :)
pluginInfo.allocatedDataMemoryAddress = data_data;
pluginInfo.allocatedTextMemoryAddress = text_data;
pluginInfo->allocatedDataMemoryAddress = data_data;
pluginInfo->allocatedTextMemoryAddress = text_data;
return pluginInfo;
}
std::vector<RelocationData> PluginInformationFactory::getImportRelocationData(const elfio &reader, uint8_t **destinations) {
std::vector<RelocationData> result;
std::vector<std::shared_ptr<RelocationData>> PluginInformationFactory::getImportRelocationData(const elfio &reader, uint8_t **destinations) {
std::vector<std::shared_ptr<RelocationData>> result;
std::map<uint32_t, std::string> infoMap;
@ -302,11 +304,10 @@ std::vector<RelocationData> PluginInformationFactory::getImportRelocationData(co
continue;
}
ImportRPLInformation rplInfo(rplName, isData);
auto rplInfo = std::make_shared<ImportRPLInformation>(rplName, isData);
uint32_t section_index = psec->get_info();
result.emplace_back(type, offset - 0x02000000, addend, (void *) (destinations[section_index]), sym_name, rplInfo);
result.push_back(std::make_shared<RelocationData>(type, offset - 0x02000000, addend, (void *) (destinations[section_index]), sym_name, rplInfo));
}
}
}

View File

@ -29,12 +29,12 @@
class PluginInformationFactory {
public:
static std::optional<PluginInformation>
load(const PluginData &pluginData, MEMHeapHandle heaphandle, relocation_trampolin_entry_t *trampolin_data, uint32_t trampolin_data_length, uint8_t trampolinId);
static std::optional<std::shared_ptr<PluginInformation>>
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
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);
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/stat.h>
#include <dirent.h>
#include <whb/file.h>
#include <memory>
#include "../utils/StringTools.h"
#include "PluginMetaInformationFactory.h"
#include "PluginMetaInformation.h"
#include "../elfio/elfio.hpp"
#include "../utils/logger.h"
using namespace ELFIO;
std::optional<PluginMetaInformation> PluginMetaInformationFactory::loadPlugin(const PluginData &pluginData) {
if (pluginData.buffer == nullptr) {
std::optional<std::shared_ptr<PluginMetaInformation>> PluginMetaInformationFactory::loadPlugin(const std::shared_ptr<PluginData> &pluginData) {
if (pluginData->buffer == nullptr) {
DEBUG_FUNCTION_LINE("Buffer was nullptr");
return std::nullopt;
}
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");
return std::nullopt;
}
return loadPlugin(reader);
}
std::optional<PluginMetaInformation> PluginMetaInformationFactory::loadPlugin(std::string &filePath) {
std::optional<std::shared_ptr<PluginMetaInformation>> PluginMetaInformationFactory::loadPlugin(std::string &filePath) {
elfio reader;
if (!reader.load(filePath)) {
DEBUG_FUNCTION_LINE("Can't find or process ELF file");
@ -49,7 +46,7 @@ std::optional<PluginMetaInformation> PluginMetaInformationFactory::loadPlugin(st
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;
if (!reader.load(buffer, size)) {
DEBUG_FUNCTION_LINE("Can't find or process ELF file");
@ -59,10 +56,10 @@ std::optional<PluginMetaInformation> PluginMetaInformationFactory::loadPlugin(ch
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;
PluginMetaInformation pluginInfo;
auto pluginInfo = std::shared_ptr<PluginMetaInformation>(new PluginMetaInformation);
uint32_t sec_num = reader.sections.size();
@ -99,19 +96,19 @@ std::optional<PluginMetaInformation> PluginMetaInformationFactory::loadPlugin(co
std::string value(curEntry + firstFound + 1);
if (key == "name") {
pluginInfo.setName(value);
pluginInfo->setName(value);
} else if (key == "author") {
pluginInfo.setAuthor(value);
pluginInfo->setAuthor(value);
} else if (key == "version") {
pluginInfo.setVersion(value);
pluginInfo->setVersion(value);
} else if (key == "license") {
pluginInfo.setLicense(value);
pluginInfo->setLicense(value);
} else if (key == "buildtimestamp") {
pluginInfo.setBuildTimestamp(value);
pluginInfo->setBuildTimestamp(value);
} else if (key == "description") {
pluginInfo.setDescription(value);
pluginInfo->setDescription(value);
} else if (key == "storage_id") {
pluginInfo.setStorageId(value);
pluginInfo->setStorageId(value);
} else if (key == "wups") {
if (value != "0.6.1") {
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;
}

View File

@ -19,17 +19,18 @@
#include <optional>
#include <string>
#include <memory>
#include <vector>
#include "PluginMetaInformation.h"
#include "PluginData.h"
class PluginMetaInformationFactory {
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
#include <string>
#include <utility>
#include "ImportRPLInformation.h"
class RelocationData {
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),
offset(offset),
addend(addend),
destination(destination),
name(name),
rplInfo(rplInfo) {
rplInfo(std::move(rplInfo)) {
}
RelocationData(const RelocationData &o2) = default;
@ -56,7 +57,7 @@ public:
return name;
}
[[nodiscard]] const ImportRPLInformation &getImportRPLInformation() const {
[[nodiscard]] const std::shared_ptr<ImportRPLInformation> &getImportRPLInformation() const {
return rplInfo;
}
@ -66,5 +67,5 @@ private:
int32_t addend;
void *destination;
std::string name;
ImportRPLInformation rplInfo;
std::shared_ptr<ImportRPLInformation> rplInfo;
};

View File

@ -9,7 +9,7 @@
#include "exports.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;
strncpy(out->author, metaInformation->getAuthor().c_str(), sizeof(out->author) - 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++) {
plugin_data_handle handle = plugin_data_handle_list[i];
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++;
}
@ -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) {
std::optional<PluginData> pluginData;
std::optional<std::shared_ptr<PluginData>> pluginData;
if (inputType == PLUGIN_INFORMATION_INPUT_TYPE_PATH && path != nullptr) {
pluginData = PluginDataFactory::load(path, gPluginDataHeap);
} 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");
return PLUGIN_BACKEND_API_ERROR_INVALID_ARG;
} else {
auto *pluginDataHandle = new PluginData(pluginData.value());
auto *pluginDataHandle = new PluginData(*pluginData.value());
*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) {
std::optional<PluginMetaInformation> pluginInfo;
std::optional<std::shared_ptr<PluginMetaInformation>> pluginInfo;
if (inputType == PLUGIN_INFORMATION_INPUT_TYPE_PATH && path != nullptr) {
std::string pathStr(path);
pluginInfo = PluginMetaInformationFactory::loadPlugin(pathStr);
@ -121,7 +121,7 @@ extern "C" PluginBackendApiErrorType WUPSGetPluginMetaInformation(GetPluginInfor
DEBUG_FUNCTION_LINE("PLUGIN_BACKEND_API_ERROR_INVALID_ARG");
return PLUGIN_BACKEND_API_ERROR_INVALID_ARG;
} else {
fillPluginInformation(output, &pluginInfo.value());
fillPluginInformation(output, pluginInfo.value());
}
return PLUGIN_BACKEND_API_ERROR_NONE;
}
@ -140,7 +140,7 @@ extern "C" PluginBackendApiErrorType WUPSGetPluginDataForContainerHandles(const
for (uint32_t i = 0; i < buffer_size; i++) {
auto handle = plugin_container_handle_list[i];
auto *container = (PluginContainer *) handle;
auto *pluginData = new PluginData(container->getPluginData());
auto *pluginData = new PluginData(*container->getPluginData());
plugin_data_list[i] = (uint32_t) pluginData;
}
} else {
@ -158,14 +158,14 @@ extern "C" PluginBackendApiErrorType WUPSGetMetaInformation(const plugin_contain
auto *container = (PluginContainer *) handle;
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].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].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].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);
plugin_information_list[i].size = container->metaInformation.getSize();
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].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].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].version, container->metaInformation->getVersion().c_str(), sizeof(plugin_information_list[i].version) - 1);
plugin_information_list[i].size = container->metaInformation->getSize();
}
} else {
DEBUG_FUNCTION_LINE("PLUGIN_BACKEND_API_ERROR_INVALID_ARG");
@ -184,7 +184,7 @@ extern "C" PluginBackendApiErrorType WUPSGetLoadedPlugins(plugin_container_handl
uint32_t counter = 0;
for (auto &plugin: plugins) {
if (counter < buffer_size) {
auto *container = new PluginContainer(plugin);
auto *container = new PluginContainer(*plugin);
io_handles[counter] = (uint32_t) container;
counter++;
} else {