From f74eff8934fe35eb5c355872ecbe0de8bcb6feb8 Mon Sep 17 00:00:00 2001 From: WerWolv Date: Sun, 27 Dec 2020 15:39:06 +0100 Subject: [PATCH] Add support for custom providers via plugins --- .idea/.name | 1 + include/helpers/plugin_handler.hpp | 9 +- include/views/view_bookmarks.hpp | 4 +- include/views/view_data_inspector.hpp | 3 +- include/views/view_disassembler.hpp | 3 +- include/views/view_hashes.hpp | 4 +- include/views/view_hexeditor.hpp | 3 +- include/views/view_information.hpp | 4 +- include/views/view_patches.hpp | 5 +- include/views/view_pattern.hpp | 3 +- include/views/view_pattern_data.hpp | 3 +- include/views/view_strings.hpp | 3 +- include/views/view_tools.hpp | 4 +- plugins/example/CMakeLists.txt | 9 +- plugins/example/source/plugin_example.cpp | 3 +- plugins/libimhex/CMakeLists.txt | 2 +- plugins/libimhex/include/hex.hpp | 57 ++++++- plugins/libimhex/include/plugin.hpp | 18 +++ .../libimhex/include/providers/provider.hpp | 10 ++ source/helpers/plugin_handler.cpp | 12 +- source/main.cpp | 23 +-- source/views/view_bookmarks.cpp | 4 +- source/views/view_data_inspector.cpp | 14 +- source/views/view_disassembler.cpp | 8 +- source/views/view_hashes.cpp | 25 +-- source/views/view_hexeditor.cpp | 142 ++++++++++-------- source/views/view_information.cpp | 23 +-- source/views/view_patches.cpp | 19 ++- source/views/view_pattern.cpp | 19 ++- source/views/view_pattern_data.cpp | 11 +- source/views/view_strings.cpp | 15 +- source/views/view_tools.cpp | 12 +- source/window.cpp | 4 +- 33 files changed, 286 insertions(+), 193 deletions(-) create mode 100644 .idea/.name create mode 100644 plugins/libimhex/include/plugin.hpp diff --git a/.idea/.name b/.idea/.name new file mode 100644 index 000000000..9f335cad9 --- /dev/null +++ b/.idea/.name @@ -0,0 +1 @@ +imhex \ No newline at end of file diff --git a/include/helpers/plugin_handler.hpp b/include/helpers/plugin_handler.hpp index 6a547457d..730e14bef 100644 --- a/include/helpers/plugin_handler.hpp +++ b/include/helpers/plugin_handler.hpp @@ -1,6 +1,9 @@ #pragma once +#include + #include "views/view.hpp" +#include "providers/provider.hpp" #include @@ -11,18 +14,18 @@ namespace hex { Plugin(std::string_view path); ~Plugin(); - void setImGuiContext(ImGuiContext *ctx) const; + void initializePlugin(ImGuiContext *ctx, prv::Provider **provider) const; View* createView() const; void drawToolsEntry() const; private: - using SetImGuiContextFunc = void(*)(ImGuiContext*); + using InitializePluginFunc = void(*)(ImGuiContext*, hex::prv::Provider**); using CreateViewFunc = View*(*)(); using DrawToolsEntryFunc = void(*)(); void *m_handle = nullptr; - SetImGuiContextFunc m_setImGuiContextFunction = nullptr; + InitializePluginFunc m_initializePluginFunction = nullptr; CreateViewFunc m_createViewFunction = nullptr; DrawToolsEntryFunc m_drawToolsEntryFunction = nullptr; diff --git a/include/views/view_bookmarks.hpp b/include/views/view_bookmarks.hpp index 0eed7e7aa..6bebb186c 100644 --- a/include/views/view_bookmarks.hpp +++ b/include/views/view_bookmarks.hpp @@ -13,15 +13,13 @@ namespace hex { class ViewBookmarks : public View { public: - explicit ViewBookmarks(prv::Provider* &dataProvider); + explicit ViewBookmarks(); ~ViewBookmarks() override; void drawContent() override; void drawMenu() override; private: - prv::Provider* &m_dataProvider; - std::list m_bookmarks; }; diff --git a/include/views/view_data_inspector.hpp b/include/views/view_data_inspector.hpp index e68ec5cf3..38b4573b1 100644 --- a/include/views/view_data_inspector.hpp +++ b/include/views/view_data_inspector.hpp @@ -51,14 +51,13 @@ namespace hex { class ViewDataInspector : public View { public: - explicit ViewDataInspector(prv::Provider* &dataProvider); + explicit ViewDataInspector(); ~ViewDataInspector() override; void drawContent() override; void drawMenu() override; private: - prv::Provider* &m_dataProvider; bool m_shouldInvalidate = true; std::endian m_endianess = std::endian::native; diff --git a/include/views/view_disassembler.hpp b/include/views/view_disassembler.hpp index 97cdf8027..16be20672 100644 --- a/include/views/view_disassembler.hpp +++ b/include/views/view_disassembler.hpp @@ -24,14 +24,13 @@ namespace hex { class ViewDisassembler : public View { public: - explicit ViewDisassembler(prv::Provider* &dataProvider); + explicit ViewDisassembler(); ~ViewDisassembler() override; void drawContent() override; void drawMenu() override; private: - prv::Provider* &m_dataProvider; bool m_shouldInvalidate = false; u64 m_baseAddress = 0; diff --git a/include/views/view_hashes.hpp b/include/views/view_hashes.hpp index eebc9ab98..b0bfb6d61 100644 --- a/include/views/view_hashes.hpp +++ b/include/views/view_hashes.hpp @@ -10,15 +10,13 @@ namespace hex { class ViewHashes : public View { public: - explicit ViewHashes(prv::Provider* &dataProvider); + explicit ViewHashes(); ~ViewHashes() override; void drawContent() override; void drawMenu() override; private: - prv::Provider* &m_dataProvider; - bool m_shouldInvalidate = true; int m_currHashFunction = 0; u64 m_hashRegion[2] = { 0 }; diff --git a/include/views/view_hexeditor.hpp b/include/views/view_hexeditor.hpp index 80ef550d2..dbd5f5a14 100644 --- a/include/views/view_hexeditor.hpp +++ b/include/views/view_hexeditor.hpp @@ -20,7 +20,7 @@ namespace hex { class ViewHexEditor : public View { public: - ViewHexEditor(prv::Provider* &dataProvider, std::vector &patternData); + ViewHexEditor(std::vector &patternData); ~ViewHexEditor() override; void drawContent() override; @@ -31,7 +31,6 @@ namespace hex { MemoryEditor m_memoryEditor; imgui_addons::ImGuiFileBrowser m_fileBrowser; - prv::Provider* &m_dataProvider; std::vector &m_patternData; char m_searchStringBuffer[0xFFFF] = { 0 }; diff --git a/include/views/view_information.hpp b/include/views/view_information.hpp index 82c13629a..a463fc2b5 100644 --- a/include/views/view_information.hpp +++ b/include/views/view_information.hpp @@ -13,15 +13,13 @@ namespace hex { class ViewInformation : public View { public: - explicit ViewInformation(prv::Provider* &dataProvider); + explicit ViewInformation(); ~ViewInformation() override; void drawContent() override; void drawMenu() override; private: - prv::Provider* &m_dataProvider; - bool m_dataValid = false; u32 m_blockSize = 0; float m_averageEntropy = 0; diff --git a/include/views/view_patches.hpp b/include/views/view_patches.hpp index 9804276e1..2e4f364ce 100644 --- a/include/views/view_patches.hpp +++ b/include/views/view_patches.hpp @@ -13,16 +13,13 @@ namespace hex { class ViewPatches : public View { public: - explicit ViewPatches(prv::Provider* &dataProvider); + explicit ViewPatches(); ~ViewPatches() override; void drawContent() override; void drawMenu() override; private: - prv::Provider* &m_dataProvider; - - u64 m_selectedPatch; }; diff --git a/include/views/view_pattern.hpp b/include/views/view_pattern.hpp index 3886f1cc6..24964de05 100644 --- a/include/views/view_pattern.hpp +++ b/include/views/view_pattern.hpp @@ -17,7 +17,7 @@ namespace hex { class ViewPattern : public View { public: - explicit ViewPattern(prv::Provider* &dataProvider, std::vector &patternData); + explicit ViewPattern(std::vector &patternData); ~ViewPattern() override; void drawMenu() override; @@ -25,7 +25,6 @@ namespace hex { private: std::vector &m_patternData; - prv::Provider* &m_dataProvider; std::filesystem::path m_possiblePatternFile; TextEditor m_textEditor; diff --git a/include/views/view_pattern_data.hpp b/include/views/view_pattern_data.hpp index ff62e26f1..8535b0010 100644 --- a/include/views/view_pattern_data.hpp +++ b/include/views/view_pattern_data.hpp @@ -16,7 +16,7 @@ namespace hex { class ViewPatternData : public View { public: - ViewPatternData(prv::Provider* &dataProvider, std::vector &patternData); + ViewPatternData(std::vector &patternData); ~ViewPatternData() override; void drawContent() override; @@ -24,7 +24,6 @@ namespace hex { private: - prv::Provider* &m_dataProvider; std::vector &m_patternData; std::vector m_sortedPatternData; }; diff --git a/include/views/view_strings.hpp b/include/views/view_strings.hpp index 267ac0964..d41f42597 100644 --- a/include/views/view_strings.hpp +++ b/include/views/view_strings.hpp @@ -17,14 +17,13 @@ namespace hex { class ViewStrings : public View { public: - explicit ViewStrings(prv::Provider* &dataProvider); + explicit ViewStrings(); ~ViewStrings() override; void drawContent() override; void drawMenu() override; private: - prv::Provider* &m_dataProvider; bool m_shouldInvalidate = false; std::vector m_foundStrings; diff --git a/include/views/view_tools.hpp b/include/views/view_tools.hpp index 9a2a24561..6162894c1 100644 --- a/include/views/view_tools.hpp +++ b/include/views/view_tools.hpp @@ -15,15 +15,13 @@ namespace hex { class ViewTools : public View { public: - ViewTools(hex::prv::Provider* &provider); + ViewTools(); ~ViewTools() override; void drawContent() override; void drawMenu() override; private: - hex::prv::Provider* &m_dataProvider; - char *m_mangledBuffer = nullptr; std::string m_demangledName; diff --git a/plugins/example/CMakeLists.txt b/plugins/example/CMakeLists.txt index 0c62846b7..0fba5ab12 100644 --- a/plugins/example/CMakeLists.txt +++ b/plugins/example/CMakeLists.txt @@ -3,10 +3,7 @@ project(example) set(CMAKE_CXX_STANDARD 20) -if (TARGET ${CMAKE_PROJECT_NAME}) - add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../../external/ImGui ${CMAKE_CURRENT_BINARY_DIR}/external/ImGui) - add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../libimhex ${CMAKE_CURRENT_BINARY_DIR}/plugins/libimhex) -endif() +add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../libimhex ${CMAKE_CURRENT_BINARY_DIR}/plugins/libimhex) set(CMAKE_SHARED_LIBRARY_PREFIX "plugin") @@ -14,5 +11,5 @@ add_library(example SHARED source/plugin_example.cpp ) -target_include_directories(example PUBLIC include) -target_link_libraries(example PRIVATE imgui libimhex) +target_include_directories(example PRIVATE include) +target_link_libraries(example PRIVATE libimhex) diff --git a/plugins/example/source/plugin_example.cpp b/plugins/example/source/plugin_example.cpp index c2d142855..3715d2e87 100644 --- a/plugins/example/source/plugin_example.cpp +++ b/plugins/example/source/plugin_example.cpp @@ -1,7 +1,6 @@ -#include +#include #include -#include class ViewExample : public hex::View { public: diff --git a/plugins/libimhex/CMakeLists.txt b/plugins/libimhex/CMakeLists.txt index 6d112e0bc..11cfab1d6 100644 --- a/plugins/libimhex/CMakeLists.txt +++ b/plugins/libimhex/CMakeLists.txt @@ -17,4 +17,4 @@ add_library(libimhex STATIC ) target_include_directories(libimhex PUBLIC include) -target_link_libraries(libimhex PRIVATE imgui) +target_link_libraries(libimhex PUBLIC imgui) diff --git a/plugins/libimhex/include/hex.hpp b/plugins/libimhex/include/hex.hpp index c10d09250..c527edbde 100644 --- a/plugins/libimhex/include/hex.hpp +++ b/plugins/libimhex/include/hex.hpp @@ -2,6 +2,7 @@ #include #include +#include using u8 = std::uint8_t; using u16 = std::uint16_t; @@ -18,16 +19,56 @@ using s128 = __int128_t; extern int mainArgc; extern char **mainArgv; -#define IMHEX_PLUGIN namespace hex::plugin::internal { \ - void setImGuiContext(ImGuiContext *ctx) { \ - gladLoadGL(); \ - ImGui::SetCurrentContext(ctx); \ - } \ - } \ - namespace hex::plugin - #ifdef OS_WINDOWS #define MAGIC_PATH_SEPARATOR ";" #else #define MAGIC_PATH_SEPARATOR ":" +#endif + +template<> +struct std::is_integral : public std::true_type { }; +template<> +struct std::is_integral : public std::true_type { }; +template<> +struct std::is_signed : public std::true_type { }; + +#if defined(_LIBCPP_VERSION) && _LIBCPP_VERSION <= 12000 +#if __has_include() +// Make sure we break when derived_from is implemented in libc++. Then we can fix a compatibility version above +#include +#endif +// libcxx 12 still doesn't have many default concepts implemented, as a result we need to define it ourself using clang built-ins. +// [concept.derived] (patch from https://reviews.llvm.org/D74292) +namespace hex { +template +concept derived_from = + __is_base_of(_Bp, _Dp) && __is_convertible_to(const volatile _Dp*, const volatile _Bp*); +} + +// [concepts.arithmetic] (patch from https://reviews.llvm.org/D88131) +namespace hex { +template +concept integral = __is_integral(_Tp); + +template +concept signed_integral = integral<_Tp> && __is_signed(_Tp); + +template +concept unsigned_integral = integral<_Tp> && !signed_integral<_Tp>; + +template +concept floating_point = __is_floating_point(_Tp); +} +#else +// Assume supported +#include + +namespace hex { + using std::derived_from; + + using std::integral; + using std::signed_integral; + using std::unsigned_integral; + using std::floating_point; +} #endif \ No newline at end of file diff --git a/plugins/libimhex/include/plugin.hpp b/plugins/libimhex/include/plugin.hpp new file mode 100644 index 000000000..8d7429409 --- /dev/null +++ b/plugins/libimhex/include/plugin.hpp @@ -0,0 +1,18 @@ +#pragma once + +#include +#include + +#include +#include +#include + +#define IMHEX_PLUGIN namespace hex::plugin::internal { \ + void initializePlugin(ImGuiContext *ctx, hex::prv::Provider **provider) { \ + if (glGetString == NULL) \ + gladLoadGL(); \ + ImGui::SetCurrentContext(ctx); \ + hex::prv::Provider::setProviderStorage(*provider); \ + } \ + } \ + namespace hex::plugin diff --git a/plugins/libimhex/include/providers/provider.hpp b/plugins/libimhex/include/providers/provider.hpp index 1fd548ab2..721b793cb 100644 --- a/plugins/libimhex/include/providers/provider.hpp +++ b/plugins/libimhex/include/providers/provider.hpp @@ -40,10 +40,20 @@ namespace hex::prv { virtual std::vector> getDataInformation() = 0; + static void setProviderStorage(Provider* &provider) { + Provider::s_currProvider = &provider; + } + + static Provider*& getCurrentProvider() { + return *Provider::s_currProvider; + } + protected: u32 m_currPage = 0; std::vector> m_patches; + + static inline Provider **s_currProvider = nullptr; }; } \ No newline at end of file diff --git a/source/helpers/plugin_handler.cpp b/source/helpers/plugin_handler.cpp index 4b64aab37..ff9c8700f 100644 --- a/source/helpers/plugin_handler.cpp +++ b/source/helpers/plugin_handler.cpp @@ -9,8 +9,8 @@ namespace hex { constexpr auto CreateViewSymbol = "_ZN3hex6plugin10createViewEv"; // hex::plugin::drawToolsEntry(void) constexpr auto DrawToolsEntrySymbol = "_ZN3hex6plugin14drawToolsEntryEv"; - // hex::plugin::internal::setImGuiContext(ImGuiContext*) - constexpr auto SetImGuiContextSymbol = "_ZN3hex6plugin8internal15setImGuiContextEP12ImGuiContext"; + // hex::plugin::internal::initializePlugin(ImGuiContext*, hex::prv::Provider**) + constexpr auto InitializePluginSymbol = "_ZN3hex6plugin8internal16initializePluginEP12ImGuiContextPPNS_3prv8ProviderE"; Plugin::Plugin(std::string_view path) { this->m_handle = dlopen(path.data(), RTLD_LAZY); @@ -20,7 +20,7 @@ namespace hex { this->m_createViewFunction = reinterpret_cast(dlsym(this->m_handle, CreateViewSymbol)); this->m_drawToolsEntryFunction = reinterpret_cast(dlsym(this->m_handle, DrawToolsEntrySymbol)); - this->m_setImGuiContextFunction = reinterpret_cast(dlsym(this->m_handle, SetImGuiContextSymbol)); + this->m_initializePluginFunction = reinterpret_cast(dlsym(this->m_handle, InitializePluginSymbol)); } Plugin::~Plugin() { @@ -28,9 +28,9 @@ namespace hex { dlclose(this->m_handle); } - void Plugin::setImGuiContext(ImGuiContext *ctx) const { - if (this->m_setImGuiContextFunction != nullptr) - this->m_setImGuiContextFunction(ctx); + void Plugin::initializePlugin(ImGuiContext *ctx, prv::Provider **provider) const { + if (this->m_initializePluginFunction != nullptr) + this->m_initializePluginFunction(ctx, provider); } View* Plugin::createView() const { diff --git a/source/main.cpp b/source/main.cpp index cc67e0b39..bd1371cda 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -31,19 +31,20 @@ int main(int argc, char **argv) { // Shared Data std::vector patternData; hex::prv::Provider *dataProvider = nullptr; + hex::prv::Provider::setProviderStorage(dataProvider); // Create views - window.addView(dataProvider, patternData); - window.addView(dataProvider, patternData); - window.addView(dataProvider, patternData); - window.addView(dataProvider); - window.addView(dataProvider); - window.addView(dataProvider); - window.addView(dataProvider); - window.addView(dataProvider); - window.addView(dataProvider); - window.addView(dataProvider); - window.addView(dataProvider); + window.addView(patternData); + window.addView(patternData); + window.addView(patternData); + window.addView(); + window.addView(); + window.addView(); + window.addView(); + window.addView(); + window.addView(); + window.addView(); + window.addView(); window.addView(); window.addView(); diff --git a/source/views/view_bookmarks.cpp b/source/views/view_bookmarks.cpp index e7c66bea5..3e55bdda0 100644 --- a/source/views/view_bookmarks.cpp +++ b/source/views/view_bookmarks.cpp @@ -7,7 +7,7 @@ namespace hex { - ViewBookmarks::ViewBookmarks(prv::Provider* &dataProvider) : View("Bookmarks"), m_dataProvider(dataProvider) { + ViewBookmarks::ViewBookmarks() : View("Bookmarks") { View::subscribeEvent(Events::AddBookmark, [this](const void *userData) { Bookmark bookmark = *reinterpret_cast(userData); bookmark.name.resize(64); @@ -55,7 +55,7 @@ namespace hex { { u8 bytes[10] = { 0 }; - this->m_dataProvider->read(region.address, bytes, std::min(region.size, size_t(10))); + prv::Provider::getCurrentProvider()->read(region.address, bytes, std::min(region.size, size_t(10))); std::string bytesString; for (u8 i = 0; i < std::min(region.size, size_t(10)); i++) { diff --git a/source/views/view_data_inspector.cpp b/source/views/view_data_inspector.cpp index ee719f638..9cb3e20b7 100644 --- a/source/views/view_data_inspector.cpp +++ b/source/views/view_data_inspector.cpp @@ -9,11 +9,13 @@ extern int ImTextCharFromUtf8(unsigned int* out_char, const char* in_text, const namespace hex { - ViewDataInspector::ViewDataInspector(prv::Provider* &dataProvider) : View("Data Inspector"), m_dataProvider(dataProvider) { + ViewDataInspector::ViewDataInspector() : View("Data Inspector") { View::subscribeEvent(Events::RegionSelected, [this](const void* userData){ Region region = *static_cast(userData); - if (this->m_dataProvider == nullptr) { + auto provider = prv::Provider::getCurrentProvider(); + + if (provider == nullptr) { this->m_validBytes = 0; return; } @@ -23,9 +25,9 @@ namespace hex { return; } - this->m_validBytes = std::min(u64(this->m_dataProvider->getSize() - region.address), u64(sizeof(PreviewData))); + this->m_validBytes = std::min(u64(provider->getSize() - region.address), u64(sizeof(PreviewData))); std::memset(&this->m_previewData, 0x00, sizeof(PreviewData)); - this->m_dataProvider->read(region.address, &this->m_previewData, this->m_validBytes); + provider->read(region.address, &this->m_previewData, this->m_validBytes); this->m_shouldInvalidate = true; }); @@ -118,7 +120,9 @@ namespace hex { if (ImGui::Begin("Data Inspector", &this->getWindowOpenState(), ImGuiWindowFlags_NoCollapse)) { - if (this->m_dataProvider != nullptr && this->m_dataProvider->isReadable()) { + auto provider = prv::Provider::getCurrentProvider(); + + if (provider != nullptr && provider->isReadable()) { if (ImGui::BeginChild("##scrolling", ImVec2(0, ImGui::GetWindowHeight() - 60))) { if (ImGui::BeginTable("##datainspector", 2, ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable | ImGuiTableFlags_RowBg | ImGuiTableFlags_NoBordersInBody)) { ImGui::TableSetupColumn("Name"); diff --git a/source/views/view_disassembler.cpp b/source/views/view_disassembler.cpp index dddb5eb4b..508a4af31 100644 --- a/source/views/view_disassembler.cpp +++ b/source/views/view_disassembler.cpp @@ -9,7 +9,7 @@ using namespace std::literals::string_literals; namespace hex { - ViewDisassembler::ViewDisassembler(prv::Provider* &dataProvider) : View("Disassembler"), m_dataProvider(dataProvider) { + ViewDisassembler::ViewDisassembler() : View("Disassembler") { View::subscribeEvent(Events::DataChanged, [this](const void*){ this->m_shouldInvalidate = true; }); @@ -51,10 +51,11 @@ namespace hex { if (cs_open(Disassembler::toCapstoneArchictecture(this->m_architecture), mode, &capstoneHandle) == CS_ERR_OK) { + auto provider = prv::Provider::getCurrentProvider(); std::vector buffer(2048, 0x00); for (u64 address = 0; address < (this->m_codeRegion[1] - this->m_codeRegion[0] + 1); address += 2048) { size_t bufferSize = std::min(u64(2048), (this->m_codeRegion[1] - this->m_codeRegion[0] + 1) - address); - this->m_dataProvider->read(this->m_codeRegion[0] + address, buffer.data(), bufferSize); + provider->read(this->m_codeRegion[0] + address, buffer.data(), bufferSize); size_t instructionCount = cs_disasm(capstoneHandle, buffer.data(), bufferSize, this->m_baseAddress + address, 0, &instructions); @@ -94,7 +95,8 @@ namespace hex { if (ImGui::Begin("Disassembler", &this->getWindowOpenState(), ImGuiWindowFlags_NoCollapse)) { - if (this->m_dataProvider != nullptr && this->m_dataProvider->isReadable()) { + auto provider = prv::Provider::getCurrentProvider(); + if (provider != nullptr && provider->isReadable()) { ImGui::TextUnformatted("Position"); ImGui::Separator(); diff --git a/source/views/view_hashes.cpp b/source/views/view_hashes.cpp index 1753ff91d..1f67de79e 100644 --- a/source/views/view_hashes.cpp +++ b/source/views/view_hashes.cpp @@ -10,7 +10,7 @@ namespace hex { - ViewHashes::ViewHashes(prv::Provider* &dataProvider) : View("Hashes"), m_dataProvider(dataProvider) { + ViewHashes::ViewHashes() : View("Hashes") { View::subscribeEvent(Events::DataChanged, [this](const void*){ this->m_shouldInvalidate = true; }); @@ -41,7 +41,8 @@ namespace hex { if (ImGui::Begin("Hashing", &this->getWindowOpenState(), ImGuiWindowFlags_NoCollapse)) { ImGui::BeginChild("##scrolling", ImVec2(0, 0), false, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoNav); - if (this->m_dataProvider != nullptr && this->m_dataProvider->isAvailable()) { + auto provider = prv::Provider::getCurrentProvider(); + if (provider != nullptr && provider->isAvailable()) { ImGui::TextUnformatted("Region"); ImGui::Separator(); @@ -59,7 +60,7 @@ namespace hex { if (ImGui::Combo("Hash Function", &this->m_currHashFunction, HashFunctionNames,sizeof(HashFunctionNames) / sizeof(const char *))) this->m_shouldInvalidate = true; - size_t dataSize = this->m_dataProvider->getSize(); + size_t dataSize = provider->getSize(); if (this->m_hashRegion[1] >= dataSize) this->m_hashRegion[1] = dataSize - 1; @@ -82,7 +83,7 @@ namespace hex { static u16 result = 0; if (this->m_shouldInvalidate) - result = crc16(this->m_dataProvider, this->m_hashRegion[0], this->m_hashRegion[1] - this->m_hashRegion[0] + 1, polynomial, init); + result = crc16(provider, this->m_hashRegion[0], this->m_hashRegion[1] - this->m_hashRegion[0] + 1, polynomial, init); char buffer[sizeof(result) * 2 + 1]; snprintf(buffer, sizeof(buffer), "%04X", result); @@ -107,7 +108,7 @@ namespace hex { static u32 result = 0; if (this->m_shouldInvalidate) - result = crc32(this->m_dataProvider, this->m_hashRegion[0], this->m_hashRegion[1] - this->m_hashRegion[0] + 1, polynomial, init); + result = crc32(provider, this->m_hashRegion[0], this->m_hashRegion[1] - this->m_hashRegion[0] + 1, polynomial, init); char buffer[sizeof(result) * 2 + 1]; snprintf(buffer, sizeof(buffer), "%08X", result); @@ -122,7 +123,7 @@ namespace hex { static std::array result; if (this->m_shouldInvalidate) - result = md4(this->m_dataProvider, this->m_hashRegion[0], this->m_hashRegion[1] - this->m_hashRegion[0] + 1); + result = md4(provider, this->m_hashRegion[0], this->m_hashRegion[1] - this->m_hashRegion[0] + 1); char buffer[sizeof(result) * 2 + 1]; formatBigHexInt(result, buffer, sizeof(buffer)); @@ -138,7 +139,7 @@ namespace hex { static std::array result = { 0 }; if (this->m_shouldInvalidate) - result = md5(this->m_dataProvider, this->m_hashRegion[0], this->m_hashRegion[1] - this->m_hashRegion[0] + 1); + result = md5(provider, this->m_hashRegion[0], this->m_hashRegion[1] - this->m_hashRegion[0] + 1); char buffer[sizeof(result) * 2 + 1]; formatBigHexInt(result, buffer, sizeof(buffer)); @@ -154,7 +155,7 @@ namespace hex { static std::array result = { 0 }; if (this->m_shouldInvalidate) - result = sha1(this->m_dataProvider, this->m_hashRegion[0], this->m_hashRegion[1] - this->m_hashRegion[0] + 1); + result = sha1(provider, this->m_hashRegion[0], this->m_hashRegion[1] - this->m_hashRegion[0] + 1); char buffer[sizeof(result) * 2 + 1]; formatBigHexInt(result, buffer, sizeof(buffer)); @@ -170,7 +171,7 @@ namespace hex { static std::array result = { 0 }; if (this->m_shouldInvalidate) - result = sha224(this->m_dataProvider, this->m_hashRegion[0], this->m_hashRegion[1] - this->m_hashRegion[0] + 1); + result = sha224(provider, this->m_hashRegion[0], this->m_hashRegion[1] - this->m_hashRegion[0] + 1); char buffer[sizeof(result) * 2 + 1]; formatBigHexInt(result, buffer, sizeof(buffer)); @@ -186,7 +187,7 @@ namespace hex { static std::array result; if (this->m_shouldInvalidate) - result = sha256(this->m_dataProvider, this->m_hashRegion[0], this->m_hashRegion[1] - this->m_hashRegion[0] + 1); + result = sha256(provider, this->m_hashRegion[0], this->m_hashRegion[1] - this->m_hashRegion[0] + 1); char buffer[sizeof(result) * 2 + 1]; formatBigHexInt(result, buffer, sizeof(buffer)); @@ -202,7 +203,7 @@ namespace hex { static std::array result; if (this->m_shouldInvalidate) - result = sha384(this->m_dataProvider, this->m_hashRegion[0], this->m_hashRegion[1] - this->m_hashRegion[0] + 1); + result = sha384(provider, this->m_hashRegion[0], this->m_hashRegion[1] - this->m_hashRegion[0] + 1); char buffer[sizeof(result) * 2 + 1]; formatBigHexInt(result, buffer, sizeof(buffer)); @@ -218,7 +219,7 @@ namespace hex { static std::array result; if (this->m_shouldInvalidate) - result = sha512(this->m_dataProvider, this->m_hashRegion[0], this->m_hashRegion[1] - this->m_hashRegion[0] + 1); + result = sha512(provider, this->m_hashRegion[0], this->m_hashRegion[1] - this->m_hashRegion[0] + 1); char buffer[sizeof(result) * 2 + 1]; formatBigHexInt(result, buffer, sizeof(buffer)); diff --git a/source/views/view_hexeditor.cpp b/source/views/view_hexeditor.cpp index 2c5dfa04d..878c7dbf0 100644 --- a/source/views/view_hexeditor.cpp +++ b/source/views/view_hexeditor.cpp @@ -15,29 +15,27 @@ namespace hex { - ViewHexEditor::ViewHexEditor(prv::Provider* &dataProvider, std::vector &patternData) - : View("Hex Editor"), m_dataProvider(dataProvider), m_patternData(patternData) { + ViewHexEditor::ViewHexEditor(std::vector &patternData) + : View("Hex Editor"), m_patternData(patternData) { this->m_memoryEditor.ReadFn = [](const ImU8 *data, size_t off) -> ImU8 { - ViewHexEditor *_this = (ViewHexEditor *) data; - - if (!_this->m_dataProvider->isAvailable() || !_this->m_dataProvider->isReadable()) + auto provider = prv::Provider::getCurrentProvider(); + if (!provider->isAvailable() || !provider->isReadable()) return 0x00; ImU8 byte; - _this->m_dataProvider->read(off, &byte, sizeof(ImU8)); + provider->read(off, &byte, sizeof(ImU8)); return byte; }; this->m_memoryEditor.WriteFn = [](ImU8 *data, size_t off, ImU8 d) -> void { - ViewHexEditor *_this = (ViewHexEditor *) data; - - if (!_this->m_dataProvider->isAvailable() || !_this->m_dataProvider->isWritable()) + auto provider = prv::Provider::getCurrentProvider(); + if (!provider->isAvailable() || !provider->isWritable()) return; - _this->m_dataProvider->write(off, &d, sizeof(ImU8)); - _this->postEvent(Events::DataChanged); + provider->write(off, &d, sizeof(ImU8)); + View::postEvent(Events::DataChanged); ProjectFile::markDirty(); }; @@ -69,11 +67,12 @@ namespace hex { View::subscribeEvent(Events::SelectionChangeRequest, [this](const void *userData) { const Region ®ion = *reinterpret_cast(userData); - auto page = this->m_dataProvider->getPageOfAddress(region.address); + auto provider = prv::Provider::getCurrentProvider(); + auto page = provider->getPageOfAddress(region.address); if (!page.has_value()) return; - this->m_dataProvider->setCurrentPage(page.value()); + provider->setCurrentPage(page.value()); this->m_memoryEditor.GotoAddr = region.address; this->m_memoryEditor.DataPreviewAddr = region.address; this->m_memoryEditor.DataPreviewAddrEnd = region.address + region.size - 1; @@ -96,26 +95,26 @@ namespace hex { } ViewHexEditor::~ViewHexEditor() { - if (this->m_dataProvider != nullptr) - delete this->m_dataProvider; - this->m_dataProvider = nullptr; + } void ViewHexEditor::drawContent() { - size_t dataSize = (this->m_dataProvider == nullptr || !this->m_dataProvider->isReadable()) ? 0x00 : this->m_dataProvider->getSize(); + auto provider = prv::Provider::getCurrentProvider(); - this->m_memoryEditor.DrawWindow("Hex Editor", &this->getWindowOpenState(), this, dataSize, dataSize == 0 ? 0x00 : this->m_dataProvider->getBaseAddress()); + size_t dataSize = (provider == nullptr || !provider->isReadable()) ? 0x00 : provider->getSize(); + + this->m_memoryEditor.DrawWindow("Hex Editor", &this->getWindowOpenState(), this, dataSize, dataSize == 0 ? 0x00 : provider->getBaseAddress()); if (dataSize != 0x00) { ImGui::Begin("Hex Editor"); ImGui::SameLine(); ImGui::Spacing(); ImGui::SameLine(); - ImGui::Text("Page %d / %d", this->m_dataProvider->getCurrentPage() + 1, this->m_dataProvider->getPageCount()); + ImGui::Text("Page %d / %d", provider->getCurrentPage() + 1, provider->getPageCount()); ImGui::SameLine(); if (ImGui::ArrowButton("prevPage", ImGuiDir_Left)) { - this->m_dataProvider->setCurrentPage(this->m_dataProvider->getCurrentPage() - 1); + provider->setCurrentPage(provider->getCurrentPage() - 1); Region dataPreview = { std::min(this->m_memoryEditor.DataPreviewAddr, this->m_memoryEditor.DataPreviewAddrEnd), 1 }; View::postEvent(Events::RegionSelected, &dataPreview); @@ -124,7 +123,7 @@ namespace hex { ImGui::SameLine(); if (ImGui::ArrowButton("nextPage", ImGuiDir_Right)) { - this->m_dataProvider->setCurrentPage(this->m_dataProvider->getCurrentPage() + 1); + provider->setCurrentPage(provider->getCurrentPage() + 1); Region dataPreview = { std::min(this->m_memoryEditor.DataPreviewAddr, this->m_memoryEditor.DataPreviewAddrEnd), 1 }; View::postEvent(Events::RegionSelected, &dataPreview); @@ -173,11 +172,11 @@ namespace hex { ImGui::NewLine(); confirmButtons("Load", "Cancel", - [this] { + [this, &provider] { if (!this->m_loaderScriptScriptPath.empty() && !this->m_loaderScriptFilePath.empty()) { this->openFile(this->m_loaderScriptFilePath); LoaderScript::setFilePath(this->m_loaderScriptFilePath); - LoaderScript::setDataProvider(this->m_dataProvider); + LoaderScript::setDataProvider(provider); LoaderScript::processFile(this->m_loaderScriptScriptPath); ImGui::CloseCurrentPopup(); } @@ -231,7 +230,7 @@ namespace hex { auto patch = hex::loadIPSPatch(patchData); for (auto &[address, value] : patch) { - this->m_dataProvider->write(address, &value, 1); + provider->write(address, &value, 1); } } @@ -240,7 +239,7 @@ namespace hex { auto patch = hex::loadIPS32Patch(patchData); for (auto &[address, value] : patch) { - this->m_dataProvider->write(address, &value, 1); + provider->write(address, &value, 1); } } @@ -253,11 +252,11 @@ namespace hex { fseek(file, 0, SEEK_SET); - for (u64 offset = 0; offset < this->m_dataProvider->getActualSize(); offset += bufferSize) { - if (bufferSize > this->m_dataProvider->getActualSize() - offset) - bufferSize = this->m_dataProvider->getActualSize() - offset; + for (u64 offset = 0; offset < provider->getActualSize(); offset += bufferSize) { + if (bufferSize > provider->getActualSize() - offset) + bufferSize = provider->getActualSize() - offset; - this->m_dataProvider->read(offset, buffer.data(), bufferSize); + provider->read(offset, buffer.data(), bufferSize); fwrite(buffer.data(), 1, bufferSize, file); } @@ -267,6 +266,7 @@ namespace hex { } void ViewHexEditor::drawMenu() { + auto provider = prv::Provider::getCurrentProvider(); if (ImGui::BeginMenu("File")) { if (ImGui::MenuItem("Open File...", "CTRL + O")) { @@ -274,12 +274,12 @@ namespace hex { View::doLater([]{ ImGui::OpenPopup("Open File"); }); } - if (ImGui::MenuItem("Save", "CTRL + S", false, this->m_dataProvider != nullptr && this->m_dataProvider->isWritable())) { - for (const auto &[address, value] : this->m_dataProvider->getPatches()) - this->m_dataProvider->writeRaw(address, &value, sizeof(u8)); + if (ImGui::MenuItem("Save", "CTRL + S", false, provider != nullptr && provider->isWritable())) { + for (const auto &[address, value] : provider->getPatches()) + provider->writeRaw(address, &value, sizeof(u8)); } - if (ImGui::MenuItem("Save As...", "CTRL + SHIFT + S", false, this->m_dataProvider != nullptr && this->m_dataProvider->isWritable())) { + if (ImGui::MenuItem("Save As...", "CTRL + SHIFT + S", false, provider != nullptr && provider->isWritable())) { View::doLater([]{ ImGui::OpenPopup("Save As"); }); } @@ -290,7 +290,7 @@ namespace hex { View::doLater([]{ ImGui::OpenPopup("Open Project"); }); } - if (ImGui::MenuItem("Save Project", "", false, this->m_dataProvider != nullptr && this->m_dataProvider->isWritable())) { + if (ImGui::MenuItem("Save Project", "", false, provider != nullptr && provider->isWritable())) { View::postEvent(Events::ProjectFileStore); if (ProjectFile::getProjectFilePath() == "") @@ -329,12 +329,12 @@ namespace hex { ImGui::EndMenu(); } - if (ImGui::BeginMenu("Export...", this->m_dataProvider != nullptr && this->m_dataProvider->isWritable())) { + if (ImGui::BeginMenu("Export...", provider != nullptr && provider->isWritable())) { if (ImGui::MenuItem("IPS Patch")) { - Patches patches = this->m_dataProvider->getPatches(); + Patches patches = provider->getPatches(); if (!patches.contains(0x00454F45) && patches.contains(0x00454F46)) { u8 value = 0; - this->m_dataProvider->read(0x00454F45, &value, sizeof(u8)); + provider->read(0x00454F45, &value, sizeof(u8)); patches[0x00454F45] = value; } @@ -342,10 +342,10 @@ namespace hex { View::doLater([]{ ImGui::OpenPopup("Export File"); }); } if (ImGui::MenuItem("IPS32 Patch")) { - Patches patches = this->m_dataProvider->getPatches(); + Patches patches = provider->getPatches(); if (!patches.contains(0x00454F45) && patches.contains(0x45454F46)) { u8 value = 0; - this->m_dataProvider->read(0x45454F45, &value, sizeof(u8)); + provider->read(0x45454F45, &value, sizeof(u8)); patches[0x45454F45] = value; } @@ -421,8 +421,9 @@ namespace hex { bool ViewHexEditor::handleShortcut(int key, int mods) { if (mods == GLFW_MOD_CONTROL && key == GLFW_KEY_S) { - for (const auto &[address, value] : this->m_dataProvider->getPatches()) - this->m_dataProvider->writeRaw(address, &value, sizeof(u8)); + auto provider = prv::Provider::getCurrentProvider(); + for (const auto &[address, value] : provider->getPatches()) + provider->writeRaw(address, &value, sizeof(u8)); return true; } else if (mods == (GLFW_MOD_CONTROL | GLFW_MOD_SHIFT) && key == GLFW_KEY_S) { ImGui::OpenPopup("Save As"); @@ -449,13 +450,15 @@ namespace hex { void ViewHexEditor::openFile(std::string path) { - if (this->m_dataProvider != nullptr) - delete this->m_dataProvider; + auto& provider = prv::Provider::getCurrentProvider(); - this->m_dataProvider = new prv::FileProvider(path); - this->m_memoryEditor.ReadOnly = !this->m_dataProvider->isWritable(); + if (provider != nullptr) + delete provider; - if (this->m_dataProvider->isAvailable()) + provider = new prv::FileProvider(path); + this->m_memoryEditor.ReadOnly = !provider->isWritable(); + + if (provider->isAvailable()) ProjectFile::setFilePath(path); this->getWindowOpenState() = true; @@ -495,13 +498,15 @@ namespace hex { } void ViewHexEditor::copyBytes() { + auto provider = prv::Provider::getCurrentProvider(); + size_t start = std::min(this->m_memoryEditor.DataPreviewAddr, this->m_memoryEditor.DataPreviewAddrEnd); size_t end = std::max(this->m_memoryEditor.DataPreviewAddr, this->m_memoryEditor.DataPreviewAddrEnd); size_t copySize = (end - start) + 1; std::vector buffer(copySize, 0x00); - this->m_dataProvider->read(start, buffer.data(), buffer.size()); + provider->read(start, buffer.data(), buffer.size()); std::string str; for (const auto &byte : buffer) @@ -512,6 +517,8 @@ namespace hex { } void ViewHexEditor::copyString() { + auto provider = prv::Provider::getCurrentProvider(); + size_t start = std::min(this->m_memoryEditor.DataPreviewAddr, this->m_memoryEditor.DataPreviewAddrEnd); size_t end = std::max(this->m_memoryEditor.DataPreviewAddr, this->m_memoryEditor.DataPreviewAddrEnd); @@ -519,19 +526,21 @@ namespace hex { std::string buffer(copySize, 0x00); buffer.reserve(copySize + 1); - this->m_dataProvider->read(start, buffer.data(), copySize); + provider->read(start, buffer.data(), copySize); ImGui::SetClipboardText(buffer.c_str()); } void ViewHexEditor::copyLanguageArray(Language language) { + auto provider = prv::Provider::getCurrentProvider(); + size_t start = std::min(this->m_memoryEditor.DataPreviewAddr, this->m_memoryEditor.DataPreviewAddrEnd); size_t end = std::max(this->m_memoryEditor.DataPreviewAddr, this->m_memoryEditor.DataPreviewAddrEnd); size_t copySize = (end - start) + 1; std::vector buffer(copySize, 0x00); - this->m_dataProvider->read(start, buffer.data(), buffer.size()); + provider->read(start, buffer.data(), buffer.size()); std::string str; switch (language) { @@ -625,13 +634,15 @@ namespace hex { } void ViewHexEditor::copyHexView() { + auto provider = prv::Provider::getCurrentProvider(); + size_t start = std::min(this->m_memoryEditor.DataPreviewAddr, this->m_memoryEditor.DataPreviewAddrEnd); size_t end = std::max(this->m_memoryEditor.DataPreviewAddr, this->m_memoryEditor.DataPreviewAddrEnd); size_t copySize = (end - start) + 1; std::vector buffer(copySize, 0x00); - this->m_dataProvider->read(start, buffer.data(), buffer.size()); + provider->read(start, buffer.data(), buffer.size()); std::string str = "Hex View 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F\n\n"; @@ -670,13 +681,15 @@ namespace hex { } void ViewHexEditor::copyHexViewHTML() { + auto provider = prv::Provider::getCurrentProvider(); + size_t start = std::min(this->m_memoryEditor.DataPreviewAddr, this->m_memoryEditor.DataPreviewAddrEnd); size_t end = std::max(this->m_memoryEditor.DataPreviewAddr, this->m_memoryEditor.DataPreviewAddrEnd); size_t copySize = (end - start) + 1; std::vector buffer(copySize, 0x00); - this->m_dataProvider->read(start, buffer.data(), buffer.size()); + provider->read(start, buffer.data(), buffer.size()); std::string str = R"( @@ -801,8 +814,9 @@ R"( void ViewHexEditor::drawSearchPopup() { static auto InputCallback = [](ImGuiInputTextCallbackData* data) -> int { auto _this = static_cast(data->UserData); + auto provider = prv::Provider::getCurrentProvider(); - *_this->m_lastSearchBuffer = _this->m_searchFunction(_this->m_dataProvider, data->Buf); + *_this->m_lastSearchBuffer = _this->m_searchFunction(provider, data->Buf); _this->m_lastSearchIndex = 0; if (_this->m_lastSearchBuffer->size() > 0) @@ -812,7 +826,9 @@ R"( }; static auto Find = [this](char *buffer) { - *this->m_lastSearchBuffer = this->m_searchFunction(this->m_dataProvider, buffer); + auto provider = prv::Provider::getCurrentProvider(); + + *this->m_lastSearchBuffer = this->m_searchFunction(provider, buffer); this->m_lastSearchIndex = 0; if (this->m_lastSearchBuffer->size() > 0) @@ -888,6 +904,8 @@ R"( } void ViewHexEditor::drawGotoPopup() { + auto provider = prv::Provider::getCurrentProvider(); + if (ImGui::BeginPopup("Goto")) { ImGui::TextUnformatted("Goto"); if (ImGui::BeginTabBar("gotoTabs")) { @@ -895,8 +913,8 @@ R"( if (ImGui::BeginTabItem("Begin")) { ImGui::InputScalar("##nolabel", ImGuiDataType_U64, &this->m_gotoAddress, nullptr, nullptr, "%llx", ImGuiInputTextFlags_CharsHexadecimal); - if (this->m_gotoAddress >= this->m_dataProvider->getActualSize()) - this->m_gotoAddress = this->m_dataProvider->getActualSize() - 1; + if (this->m_gotoAddress >= provider->getActualSize()) + this->m_gotoAddress = provider->getActualSize() - 1; newOffset = this->m_gotoAddress; @@ -913,9 +931,9 @@ R"( s64 currHighlightStart = std::min(this->m_memoryEditor.DataPreviewAddr, this->m_memoryEditor.DataPreviewAddrEnd); newOffset = this->m_gotoAddress + currHighlightStart; - if (newOffset >= this->m_dataProvider->getActualSize()) { - newOffset = this->m_dataProvider->getActualSize() - 1; - this->m_gotoAddress = (this->m_dataProvider->getActualSize() - 1) - currHighlightStart; + if (newOffset >= provider->getActualSize()) { + newOffset = provider->getActualSize() - 1; + this->m_gotoAddress = (provider->getActualSize() - 1) - currHighlightStart; } else if (newOffset < 0) { newOffset = 0; this->m_gotoAddress = -currHighlightStart; @@ -926,16 +944,16 @@ R"( if (ImGui::BeginTabItem("End")) { ImGui::InputScalar("##nolabel", ImGuiDataType_U64, &this->m_gotoAddress, nullptr, nullptr, "%llx", ImGuiInputTextFlags_CharsHexadecimal); - if (this->m_gotoAddress >= this->m_dataProvider->getActualSize()) - this->m_gotoAddress = this->m_dataProvider->getActualSize() - 1; + if (this->m_gotoAddress >= provider->getActualSize()) + this->m_gotoAddress = provider->getActualSize() - 1; - newOffset = (this->m_dataProvider->getActualSize() - 1) - this->m_gotoAddress; + newOffset = (provider->getActualSize() - 1) - this->m_gotoAddress; ImGui::EndTabItem(); } if (ImGui::Button("Goto")) { - this->m_dataProvider->setCurrentPage(std::floor(newOffset / double(prv::Provider::PageSize))); + provider->setCurrentPage(std::floor(newOffset / double(prv::Provider::PageSize))); this->m_memoryEditor.GotoAddr = newOffset; this->m_memoryEditor.DataPreviewAddr = newOffset; this->m_memoryEditor.DataPreviewAddrEnd = newOffset; diff --git a/source/views/view_information.cpp b/source/views/view_information.cpp index 1d4ccea54..700088c36 100644 --- a/source/views/view_information.cpp +++ b/source/views/view_information.cpp @@ -14,8 +14,7 @@ namespace hex { - ViewInformation::ViewInformation(prv::Provider* &dataProvider) - : View("Information"), m_dataProvider(dataProvider) { + ViewInformation::ViewInformation() : View("Information") { View::subscribeEvent(Events::DataChanged, [this](const void*) { this->m_dataValid = false; this->m_highestBlockEntropy = 0; @@ -50,20 +49,22 @@ namespace hex { if (ImGui::Begin("Data Information", &this->getWindowOpenState(), ImGuiWindowFlags_NoCollapse)) { ImGui::BeginChild("##scrolling", ImVec2(0, 0), false, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoNav); - if (this->m_dataProvider != nullptr && this->m_dataProvider->isReadable()) { + auto provider = prv::Provider::getCurrentProvider(); + + if (provider != nullptr && provider->isReadable()) { if (this->m_shouldInvalidate) { - this->m_analyzedRegion = { this->m_dataProvider->getBaseAddress(), this->m_dataProvider->getBaseAddress() + this->m_dataProvider->getSize() }; + this->m_analyzedRegion = { provider->getBaseAddress(), provider->getBaseAddress() + provider->getSize() }; { - this->m_blockSize = std::ceil(this->m_dataProvider->getSize() / 2048.0F); + this->m_blockSize = std::ceil(provider->getSize() / 2048.0F); std::vector buffer(this->m_blockSize, 0x00); std::memset(this->m_valueCounts.data(), 0x00, this->m_valueCounts.size() * sizeof(u32)); this->m_blockEntropy.clear(); - for (u64 i = 0; i < this->m_dataProvider->getSize(); i += this->m_blockSize) { + for (u64 i = 0; i < provider->getSize(); i += this->m_blockSize) { std::array blockValueCounts = { 0 }; - this->m_dataProvider->read(i, buffer.data(), std::min(u64(this->m_blockSize), this->m_dataProvider->getSize() - i)); + provider->read(i, buffer.data(), std::min(u64(this->m_blockSize), provider->getSize() - i)); for (size_t j = 0; j < this->m_blockSize; j++) { blockValueCounts[buffer[j]]++; @@ -72,13 +73,13 @@ namespace hex { this->m_blockEntropy.push_back(calculateEntropy(blockValueCounts, this->m_blockSize)); } - this->m_averageEntropy = calculateEntropy(this->m_valueCounts, this->m_dataProvider->getSize()); + this->m_averageEntropy = calculateEntropy(this->m_valueCounts, provider->getSize()); this->m_highestBlockEntropy = *std::max_element(this->m_blockEntropy.begin(), this->m_blockEntropy.end()); } { - std::vector buffer(this->m_dataProvider->getSize(), 0x00); - this->m_dataProvider->read(0x00, buffer.data(), buffer.size()); + std::vector buffer(provider->getSize(), 0x00); + provider->read(0x00, buffer.data(), buffer.size()); this->m_fileDescription.clear(); this->m_mimeType.clear(); @@ -134,7 +135,7 @@ namespace hex { if (this->m_dataValid) { - for (auto &[name, value] : this->m_dataProvider->getDataInformation()) { + for (auto &[name, value] : prv::Provider::getCurrentProvider()->getDataInformation()) { ImGui::LabelText(name.c_str(), "%s", value.c_str()); } diff --git a/source/views/view_patches.cpp b/source/views/view_patches.cpp index 67517ff80..4137a0592 100644 --- a/source/views/view_patches.cpp +++ b/source/views/view_patches.cpp @@ -11,15 +11,17 @@ using namespace std::literals::string_literals; namespace hex { - ViewPatches::ViewPatches(prv::Provider* &dataProvider) : View("Patches"), m_dataProvider(dataProvider) { + ViewPatches::ViewPatches() : View("Patches") { View::subscribeEvent(Events::ProjectFileStore, [this](const void*) { - if (this->m_dataProvider != nullptr) - ProjectFile::setPatches(this->m_dataProvider->getPatches()); + auto provider = prv::Provider::getCurrentProvider(); + if (provider != nullptr) + ProjectFile::setPatches(provider->getPatches()); }); View::subscribeEvent(Events::ProjectFileLoad, [this](const void*) { - if (this->m_dataProvider != nullptr) - this->m_dataProvider->getPatches() = ProjectFile::getPatches(); + auto provider = prv::Provider::getCurrentProvider(); + if (provider != nullptr) + provider->getPatches() = ProjectFile::getPatches(); }); } @@ -30,8 +32,9 @@ namespace hex { void ViewPatches::drawContent() { if (ImGui::Begin("Patches", &this->getWindowOpenState(), ImGuiWindowFlags_NoCollapse)) { + auto provider = prv::Provider::getCurrentProvider(); - if (this->m_dataProvider != nullptr && this->m_dataProvider->isReadable()) { + if (provider != nullptr && provider->isReadable()) { if (ImGui::BeginTable("##patchesTable", 3, ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable | ImGuiTableFlags_Sortable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_RowBg | ImGuiTableFlags_ScrollY)) { @@ -42,7 +45,7 @@ namespace hex { ImGui::TableHeadersRow(); - auto& patches = this->m_dataProvider->getPatches(); + auto& patches = provider->getPatches(); u32 index = 0; for (const auto &[address, patch] : patches) { @@ -61,7 +64,7 @@ namespace hex { ImGui::TableNextColumn(); u8 previousValue = 0x00; - this->m_dataProvider->readRaw(address, &previousValue, sizeof(u8)); + provider->readRaw(address, &previousValue, sizeof(u8)); ImGui::Text("0x%02X", previousValue); ImGui::TableNextColumn(); diff --git a/source/views/view_pattern.cpp b/source/views/view_pattern.cpp index bc97f483b..ed05601be 100644 --- a/source/views/view_pattern.cpp +++ b/source/views/view_pattern.cpp @@ -72,8 +72,7 @@ namespace hex { } - ViewPattern::ViewPattern(prv::Provider* &dataProvider, std::vector &patternData) - : View("Pattern"), m_dataProvider(dataProvider), m_patternData(patternData) { + ViewPattern::ViewPattern(std::vector &patternData) : View("Pattern"), m_patternData(patternData) { this->m_textEditor.SetLanguageDefinition(PatternLanguage()); this->m_textEditor.SetShowWhitespaces(false); @@ -110,8 +109,13 @@ namespace hex { if (error) return; - std::vector buffer(std::min(this->m_dataProvider->getSize(), size_t(0xFFFF)), 0x00); - this->m_dataProvider->read(0, buffer.data(), buffer.size()); + auto provider = prv::Provider::getCurrentProvider(); + + if (provider == nullptr) + return; + + std::vector buffer(std::min(provider->getSize(), size_t(0xFFFF)), 0x00); + provider->read(0, buffer.data(), buffer.size()); std::string mimeType; @@ -178,7 +182,9 @@ namespace hex { void ViewPattern::drawContent() { if (ImGui::Begin("Pattern", &this->getWindowOpenState(), ImGuiWindowFlags_None | ImGuiWindowFlags_NoCollapse)) { - if (this->m_dataProvider != nullptr && this->m_dataProvider->isAvailable()) { + auto provider = prv::Provider::getCurrentProvider(); + + if (provider != nullptr && provider->isAvailable()) { this->m_textEditor.Render("Pattern"); if (this->m_textEditor.IsTextChanged()) { @@ -309,7 +315,8 @@ namespace hex { return; } - hex::lang::Evaluator evaluator(this->m_dataProvider, defaultDataEndianess); + auto provider = prv::Provider::getCurrentProvider(); + hex::lang::Evaluator evaluator(provider, defaultDataEndianess); auto patternData = evaluator.evaluate(ast.value()); if (!patternData.has_value()) { this->m_textEditor.SetErrorMarkers({ evaluator.getError() }); diff --git a/source/views/view_pattern_data.cpp b/source/views/view_pattern_data.cpp index 5e23fa924..0794036c4 100644 --- a/source/views/view_pattern_data.cpp +++ b/source/views/view_pattern_data.cpp @@ -5,8 +5,8 @@ namespace hex { - ViewPatternData::ViewPatternData(prv::Provider* &dataProvider, std::vector &patternData) - : View("Pattern Data"), m_dataProvider(dataProvider), m_patternData(patternData) { + ViewPatternData::ViewPatternData(std::vector &patternData) + : View("Pattern Data"), m_patternData(patternData) { this->subscribeEvent(Events::PatternChanged, [this](auto data) { this->m_sortedPatternData.clear(); @@ -50,14 +50,15 @@ namespace hex { void ViewPatternData::drawContent() { if (ImGui::Begin("Pattern Data", &this->getWindowOpenState(), ImGuiWindowFlags_NoCollapse)) { - if (this->m_dataProvider != nullptr && this->m_dataProvider->isReadable()) { + auto provider = prv::Provider::getCurrentProvider(); + if (provider != nullptr && provider->isReadable()) { - if (beginPatternDataTable(this->m_dataProvider, this->m_patternData, this->m_sortedPatternData)) { + if (beginPatternDataTable(provider, this->m_patternData, this->m_sortedPatternData)) { if (this->m_sortedPatternData.size() > 0) { ImGui::TableHeadersRow(); for (auto &patternData : this->m_sortedPatternData) - patternData->createEntry(this->m_dataProvider); + patternData->createEntry(provider); } diff --git a/source/views/view_strings.cpp b/source/views/view_strings.cpp index ff6965fd7..ea4e5e89f 100644 --- a/source/views/view_strings.cpp +++ b/source/views/view_strings.cpp @@ -11,7 +11,7 @@ using namespace std::literals::string_literals; namespace hex { - ViewStrings::ViewStrings(prv::Provider* &dataProvider) : View("Strings"), m_dataProvider(dataProvider) { + ViewStrings::ViewStrings() : View("Strings") { View::subscribeEvent(Events::DataChanged, [this](const void*){ this->m_foundStrings.clear(); }); @@ -47,6 +47,8 @@ namespace hex { void ViewStrings::drawContent() { + auto provider = prv::Provider::getCurrentProvider(); + if (this->m_shouldInvalidate) { this->m_shouldInvalidate = false; @@ -54,9 +56,10 @@ namespace hex { std::vector buffer(1024, 0x00); u32 foundCharacters = 0; - for (u64 offset = 0; offset < this->m_dataProvider->getSize(); offset += buffer.size()) { - size_t readSize = std::min(u64(buffer.size()), this->m_dataProvider->getSize() - offset); - this->m_dataProvider->read(offset, buffer.data(), readSize); + + for (u64 offset = 0; offset < provider->getSize(); offset += buffer.size()) { + size_t readSize = std::min(u64(buffer.size()), provider->getSize() - offset); + provider->read(offset, buffer.data(), readSize); for (u32 i = 0; i < readSize; i++) { if (buffer[i] >= 0x20 && buffer[i] <= 0x7E) @@ -69,7 +72,7 @@ namespace hex { foundString.size = foundCharacters; foundString.string.reserve(foundCharacters); foundString.string.resize(foundCharacters); - this->m_dataProvider->read(foundString.offset, foundString.string.data(), foundCharacters); + provider->read(foundString.offset, foundString.string.data(), foundCharacters); this->m_foundStrings.push_back(foundString); } @@ -82,7 +85,7 @@ namespace hex { if (ImGui::Begin("Strings", &this->getWindowOpenState(), ImGuiWindowFlags_NoCollapse)) { - if (this->m_dataProvider != nullptr && this->m_dataProvider->isReadable()) { + if (provider != nullptr && provider->isReadable()) { if (ImGui::InputInt("Minimum length", &this->m_minimumLength, 1, 0)) this->m_shouldInvalidate = true; diff --git a/source/views/view_tools.cpp b/source/views/view_tools.cpp index a8d757289..617296a25 100644 --- a/source/views/view_tools.cpp +++ b/source/views/view_tools.cpp @@ -12,7 +12,7 @@ namespace hex { - ViewTools::ViewTools(hex::prv::Provider* &provider) : View("Tools"), m_dataProvider(provider) { + ViewTools::ViewTools() : View("Tools") { this->m_mangledBuffer = new char[0xF'FFFF]; std::memset(this->m_mangledBuffer, 0x00, 0xF'FFFF); @@ -42,23 +42,25 @@ namespace hex { this->m_mathEvaluator.setFunction("read", [this](auto args) -> std::optional { u8 value = 0; - if (this->m_dataProvider == nullptr || !this->m_dataProvider->isReadable() || args[0] >= this->m_dataProvider->getActualSize()) + auto provider = prv::Provider::getCurrentProvider(); + if (provider == nullptr || !provider->isReadable() || args[0] >= provider->getActualSize()) return { }; - this->m_dataProvider->read(args[0], &value, sizeof(u8)); + provider->read(args[0], &value, sizeof(u8)); return value; }, 1, 1); this->m_mathEvaluator.setFunction("write", [this](auto args) -> std::optional { - if (this->m_dataProvider == nullptr || !this->m_dataProvider->isWritable() || args[0] >= this->m_dataProvider->getActualSize()) + auto provider = prv::Provider::getCurrentProvider(); + if (provider == nullptr || !provider->isWritable() || args[0] >= provider->getActualSize()) return { }; if (args[1] > 0xFF) return { }; u8 value = args[1]; - this->m_dataProvider->write(args[0], &value, sizeof(u8)); + provider->write(args[0], &value, sizeof(u8)); return { }; }, 2, 2); diff --git a/source/window.cpp b/source/window.cpp index 5ddee9bb4..5a64301e2 100644 --- a/source/window.cpp +++ b/source/window.cpp @@ -66,9 +66,6 @@ namespace hex { while (!glfwWindowShouldClose(this->m_window)) { this->frameBegin(); - for (const auto &plugin : PluginHandler::getPlugins()) - plugin.setImGuiContext(ImGui::GetCurrentContext()); - for (const auto &call : View::getDeferedCalls()) call(); View::getDeferedCalls().clear(); @@ -380,6 +377,7 @@ namespace hex { PluginHandler::load((std::filesystem::path(mainArgv[0]).parent_path() / "plugins").string()); for (const auto &plugin : PluginHandler::getPlugins()) { + plugin.initializePlugin(ImGui::GetCurrentContext(), &prv::Provider::getCurrentProvider()); if (auto view = plugin.createView(); view != nullptr) this->m_pluginViews.push_back(view); }