From 8b81f41e52b55835aaaa7e4962af23a00188cbdc Mon Sep 17 00:00:00 2001 From: Vaxry <43317083+vaxerski@users.noreply.github.com> Date: Mon, 27 Feb 2023 12:32:38 +0000 Subject: Plugin System (#1590) --------- Co-authored-by: Mihai Fufezan --- src/managers/HookSystemManager.cpp | 57 ++++++++++++++++++++++++++++++-------- 1 file changed, 46 insertions(+), 11 deletions(-) (limited to 'src/managers/HookSystemManager.cpp') diff --git a/src/managers/HookSystemManager.cpp b/src/managers/HookSystemManager.cpp index 02775a24..c5e4cdd8 100644 --- a/src/managers/HookSystemManager.cpp +++ b/src/managers/HookSystemManager.cpp @@ -1,44 +1,79 @@ #include "HookSystemManager.hpp" +#include "../plugins/PluginSystem.hpp" + CHookSystemManager::CHookSystemManager() { ; // } // returns the pointer to the function -HOOK_CALLBACK_FN* CHookSystemManager::hookDynamic(const std::string& event, HOOK_CALLBACK_FN fn) { +HOOK_CALLBACK_FN* CHookSystemManager::hookDynamic(const std::string& event, HOOK_CALLBACK_FN fn, HANDLE handle) { const auto PVEC = getVecForEvent(event); const auto PFN = &m_lCallbackFunctions.emplace_back(fn); - PVEC->emplace_back(PFN); + PVEC->emplace_back(SCallbackFNPtr{PFN, handle}); return PFN; } -void CHookSystemManager::hookStatic(const std::string& event, HOOK_CALLBACK_FN* fn) { +void CHookSystemManager::hookStatic(const std::string& event, HOOK_CALLBACK_FN* fn, HANDLE handle) { const auto PVEC = getVecForEvent(event); - PVEC->emplace_back(fn); + PVEC->emplace_back(SCallbackFNPtr{fn, handle}); } void CHookSystemManager::unhook(HOOK_CALLBACK_FN* fn) { std::erase_if(m_lCallbackFunctions, [&](const auto& other) { return &other == fn; }); for (auto& [k, v] : m_lpRegisteredHooks) { - std::erase_if(v, [&](const auto& other) { return other == fn; }); + std::erase_if(v, [&](const auto& other) { return other.fn == fn; }); } } -void CHookSystemManager::emit(const std::vector* callbacks, std::any data) { +void CHookSystemManager::emit(const std::vector* callbacks, std::any data) { if (callbacks->empty()) return; - for (auto& cb : *callbacks) - (*cb)(cb, data); + std::vector faultyHandles; + + for (auto& cb : *callbacks) { + + m_bCurrentEventPlugin = false; + + if (!cb.handle) { + // we don't guard hl hooks + (*cb.fn)(cb.fn, data); + continue; + } + + m_bCurrentEventPlugin = true; + + if (std::find(faultyHandles.begin(), faultyHandles.end(), cb.handle) != faultyHandles.end()) + continue; + + try { + if (!setjmp(m_jbHookFaultJumpBuf)) + (*cb.fn)(cb.fn, data); + else { + // this module crashed. + throw std::exception(); + } + } catch (std::exception& e) { + // TODO: this works only once...? + faultyHandles.push_back(cb.handle); + Debug::log(ERR, " [hookSystem] Hook from plugin %lx caused a SIGSEGV, queueing for unloading.", cb.handle); + } + } + + if (!faultyHandles.empty()) { + for (auto& h : faultyHandles) + g_pPluginSystem->unloadPlugin(g_pPluginSystem->getPluginByHandle(h), true); + } } -std::vector* CHookSystemManager::getVecForEvent(const std::string& event) { +std::vector* CHookSystemManager::getVecForEvent(const std::string& event) { auto IT = std::find_if(m_lpRegisteredHooks.begin(), m_lpRegisteredHooks.end(), [&](const auto& other) { return other.first == event; }); if (IT != m_lpRegisteredHooks.end()) return &IT->second; - Debug::log(LOG, "[hookSystem] New hook event registered: %s", event.c_str()); + Debug::log(LOG, " [hookSystem] New hook event registered: %s", event.c_str()); - return &m_lpRegisteredHooks.emplace_back(std::make_pair<>(event, std::vector{})).second; + return &m_lpRegisteredHooks.emplace_back(std::make_pair<>(event, std::vector{})).second; } \ No newline at end of file -- cgit v1.2.3