From 6879cf765f0ccdc1811d2dcf67579b7ad292ae5d Mon Sep 17 00:00:00 2001 From: WerWolv Date: Mon, 6 Sep 2021 16:15:05 +0200 Subject: [PATCH] sys: Cleanup libmagic mess --- CMakeLists.txt | 4 +- plugins/libimhex/CMakeLists.txt | 5 +- plugins/libimhex/include/hex.hpp | 8 +- .../libimhex/include/hex/helpers/literals.hpp | 23 +++++ .../libimhex/include/hex/helpers/magic.hpp | 22 +++++ plugins/libimhex/source/helpers/magic.cpp | 94 +++++++++++++++++++ source/views/view_information.cpp | 49 ++-------- source/views/view_pattern_editor.cpp | 32 +------ 8 files changed, 157 insertions(+), 80 deletions(-) create mode 100644 plugins/libimhex/include/hex/helpers/literals.hpp create mode 100644 plugins/libimhex/include/hex/helpers/magic.hpp create mode 100644 plugins/libimhex/source/helpers/magic.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 33a343175..b4ef99c6c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -99,9 +99,9 @@ set_target_properties(imhex PROPERTIES CXX_VISIBILITY_PRESET hidden) target_link_directories(imhex PRIVATE ${CAPSTONE_LIBRARY_DIRS} ${MAGIC_LIBRARY_DIRS}) if (WIN32) - target_link_libraries(imhex magic ${CMAKE_DL_LIBS} capstone LLVMDemangle libimhex ${Python_LIBRARIES} wsock32 ws2_32 libyara Dwmapi.lib dl) + target_link_libraries(imhex ${CMAKE_DL_LIBS} capstone LLVMDemangle libimhex ${Python_LIBRARIES} wsock32 ws2_32 libyara Dwmapi.lib dl) else () - target_link_libraries(imhex magic ${CMAKE_DL_LIBS} capstone LLVMDemangle libimhex ${Python_LIBRARIES} dl pthread libyara) + target_link_libraries(imhex ${CMAKE_DL_LIBS} capstone LLVMDemangle libimhex ${Python_LIBRARIES} dl pthread libyara) endif () createPackage() diff --git a/plugins/libimhex/CMakeLists.txt b/plugins/libimhex/CMakeLists.txt index 6d9a3d772..33ce5ce0b 100644 --- a/plugins/libimhex/CMakeLists.txt +++ b/plugins/libimhex/CMakeLists.txt @@ -47,6 +47,7 @@ set(LIBIMHEX_SOURCES source/helpers/utils.cpp source/helpers/paths.cpp + source/helpers/magic.cpp source/helpers/shared_data.cpp source/helpers/crypto.cpp source/helpers/lang.cpp @@ -93,9 +94,9 @@ target_link_directories(libimhex PUBLIC ${MBEDTLS_LIBRARY_DIR}) if (APPLE) find_library(FOUNDATION NAMES Foundation) - target_link_libraries(libimhex PUBLIC imgui nlohmann_json mbedcrypto ${FOUNDATION} nfd fmt-header-only libcurl) + target_link_libraries(libimhex PUBLIC imgui nlohmann_json mbedcrypto ${FOUNDATION} nfd fmt-header-only libcurl magic) else () - target_link_libraries(libimhex PUBLIC imgui nlohmann_json mbedcrypto nfd) + target_link_libraries(libimhex PUBLIC imgui nlohmann_json mbedcrypto nfd magic) if (NOT USE_SYSTEM_FMT) target_link_libraries(libimhex PUBLIC fmt-header-only) diff --git a/plugins/libimhex/include/hex.hpp b/plugins/libimhex/include/hex.hpp index 461575023..def511081 100644 --- a/plugins/libimhex/include/hex.hpp +++ b/plugins/libimhex/include/hex.hpp @@ -23,10 +23,4 @@ using s128 = __int128_t; struct Region { u64 address; size_t size; -}; - -#ifdef OS_WINDOWS -#define MAGIC_PATH_SEPARATOR ";" -#else -#define MAGIC_PATH_SEPARATOR ":" -#endif \ No newline at end of file +}; \ No newline at end of file diff --git a/plugins/libimhex/include/hex/helpers/literals.hpp b/plugins/libimhex/include/hex/helpers/literals.hpp new file mode 100644 index 000000000..6bd3fc701 --- /dev/null +++ b/plugins/libimhex/include/hex/helpers/literals.hpp @@ -0,0 +1,23 @@ +#pragma once + +namespace hex::literals { + + /* Byte literals */ + + unsigned long long operator ""_Bytes(unsigned long long bytes) { + return bytes; + } + + unsigned long long operator ""_kiB(unsigned long long kiB) { + return operator ""_Bytes(kiB * 1024); + } + + unsigned long long operator ""_MiB(unsigned long long MiB) { + return operator ""_kiB(MiB * 1024); + } + + unsigned long long operator ""_GiB(unsigned long long GiB) { + return operator ""_MiB(GiB * 1024); + } + +} \ No newline at end of file diff --git a/plugins/libimhex/include/hex/helpers/magic.hpp b/plugins/libimhex/include/hex/helpers/magic.hpp new file mode 100644 index 000000000..6b5deeabc --- /dev/null +++ b/plugins/libimhex/include/hex/helpers/magic.hpp @@ -0,0 +1,22 @@ +#pragma once + +#include + +#include + +#include +#include + +namespace hex::prv { class Provider; } + +namespace hex::magic { + + using namespace hex::literals; + + bool compile(); + std::string getDescription(const std::vector &data); + std::string getDescription(prv::Provider *provider, size_t size = 5_MiB); + std::string getMIMEType(const std::vector &data); + std::string getMIMEType(prv::Provider *provider, size_t size = 5_MiB); + +} \ No newline at end of file diff --git a/plugins/libimhex/source/helpers/magic.cpp b/plugins/libimhex/source/helpers/magic.cpp new file mode 100644 index 000000000..98d216103 --- /dev/null +++ b/plugins/libimhex/source/helpers/magic.cpp @@ -0,0 +1,94 @@ +#include + +#include +#include + +#include + +#include +#include +#include + +#include + +#if defined(OS_WINDOWS) + #define MAGIC_PATH_SEPARATOR ";" +#else + #define MAGIC_PATH_SEPARATOR ":" +#endif + + +namespace hex::magic { + + static std::optional getMagicFiles(bool sourceFiles = false) { + std::string magicFiles; + + std::error_code error; + for (const auto &dir : hex::getPath(ImHexPath::Magic)) { + for (const auto &entry : std::filesystem::directory_iterator(dir, error)) { + if (entry.is_regular_file() && ((sourceFiles && entry.path().extension().empty()) || (!sourceFiles && entry.path().extension() == ".mgc"))) + magicFiles += entry.path().string() + MAGIC_PATH_SEPARATOR; + } + } + + if (error) + return { }; + else + return magicFiles; + } + + bool compile() { + magic_t ctx = magic_open(MAGIC_NONE); + ON_SCOPE_EXIT { magic_close(ctx); }; + + auto magicFiles = getMagicFiles(true); + + if (!magicFiles.has_value()) + return false; + + return magic_compile(ctx, magicFiles->c_str()) == 0; + } + + std::string getDescription(const std::vector &data) { + auto magicFiles = getMagicFiles(); + + if (magicFiles.has_value()) { + magic_t ctx = magic_open(MAGIC_NONE); + ON_SCOPE_EXIT { magic_close(ctx); }; + + if (magic_load(ctx, magicFiles->c_str())) + return magic_buffer(ctx, data.data(), data.size()) ?: ""; + } + + return ""; + } + + std::string getDescription(prv::Provider *provider, size_t size) { + std::vector buffer(std::min(provider->getSize(), size), 0x00); + provider->readRelative(0x00, buffer.data(), buffer.size()); + + return getDescription(buffer); + } + + std::string getMIMEType(const std::vector &data){ + auto magicFiles = getMagicFiles(); + + if (magicFiles.has_value()) { + magic_t ctx = magic_open(MAGIC_MIME); + ON_SCOPE_EXIT { magic_close(ctx); }; + + if (magic_load(ctx, magicFiles->c_str())) + return magic_buffer(ctx, data.data(), data.size()) ?: ""; + } + + return ""; + } + + std::string getMIMEType(prv::Provider *provider, size_t size) { + std::vector buffer(std::min(provider->getSize(), size), 0x00); + provider->readRelative(0x00, buffer.data(), buffer.size()); + + return getMIMEType(buffer); + } + +} \ No newline at end of file diff --git a/source/views/view_information.cpp b/source/views/view_information.cpp index d2f91d892..5cbd30253 100644 --- a/source/views/view_information.cpp +++ b/source/views/view_information.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include @@ -12,13 +13,15 @@ #include #include -#include +#include #include #include namespace hex { + using namespace hex::literals; + ViewInformation::ViewInformation() : View("hex.view.information.name") { EventManager::subscribe(this, [this]() { this->m_dataValid = false; @@ -93,47 +96,9 @@ namespace hex { } { - std::vector buffer(provider->getSize(), 0x00); - provider->readRelative(0x00, buffer.data(), buffer.size()); - - this->m_fileDescription.clear(); - this->m_mimeType.clear(); - - std::string magicFiles; - - std::error_code error; - for (const auto &dir : hex::getPath(ImHexPath::Magic)) { - for (const auto &entry : std::filesystem::directory_iterator(dir, error)) { - if (entry.is_regular_file() && entry.path().extension() == ".mgc") - magicFiles += entry.path().string() + MAGIC_PATH_SEPARATOR; - } - } - - if (!error) { - magicFiles.pop_back(); - - { - magic_t cookie = magic_open(MAGIC_NONE); - if (magic_load(cookie, magicFiles.c_str()) != -1) - this->m_fileDescription = magic_buffer(cookie, buffer.data(), buffer.size()); - else - this->m_fileDescription = ""; - - magic_close(cookie); - } - - { - magic_t cookie = magic_open(MAGIC_MIME); - if (magic_load(cookie, magicFiles.c_str()) != -1) - this->m_mimeType = magic_buffer(cookie, buffer.data(), buffer.size()); - else - this->m_mimeType = ""; - - magic_close(cookie); - } - - this->m_dataValid = true; - } + this->m_fileDescription = magic::getDescription(provider); + this->m_mimeType = magic::getMIMEType(provider); + this->m_dataValid = true; } this->m_analyzing = false; diff --git a/source/views/view_pattern_editor.cpp b/source/views/view_pattern_editor.cpp index f0ad27eb6..08533b968 100644 --- a/source/views/view_pattern_editor.cpp +++ b/source/views/view_pattern_editor.cpp @@ -5,7 +5,8 @@ #include #include -#include +#include +#include #include @@ -13,6 +14,8 @@ namespace hex { + using namespace hex::literals; + static const TextEditor::LanguageDefinition& PatternLanguage() { static bool initialized = false; static TextEditor::LanguageDefinition langDef; @@ -101,37 +104,12 @@ namespace hex { return; lang::Preprocessor preprocessor; - std::string magicFiles; - - std::error_code error; - for (const auto &dir : hex::getPath(ImHexPath::Magic)) { - if (!std::filesystem::is_directory(dir)) - continue; - - for (const auto &entry : std::filesystem::directory_iterator(dir, error)) { - if (entry.is_regular_file() && entry.path().extension() == ".mgc") - magicFiles += entry.path().string() + MAGIC_PATH_SEPARATOR; - } - } - - if (error) - return; - auto provider = SharedData::currentProvider; if (provider == nullptr) return; - std::vector buffer(std::min(provider->getSize(), size_t(0xFFFF)), 0x00); - provider->readRelative(0, buffer.data(), buffer.size()); - - std::string mimeType; - - magic_t cookie = magic_open(MAGIC_MIME_TYPE); - if (magic_load(cookie, magicFiles.c_str()) != -1) - mimeType = magic_buffer(cookie, buffer.data(), buffer.size()); - - magic_close(cookie); + std::string mimeType = magic::getMIMEType(provider); bool foundCorrectType = false; preprocessor.addPragmaHandler("MIME", [&mimeType, &foundCorrectType](std::string value) {