mirror of
https://github.com/WerWolv/ImHex.git
synced 2026-01-25 22:19:38 -06:00
feat: Added simple yara data analyzer
This commit is contained in:
@@ -188,7 +188,7 @@ namespace hex::plugin::builtin {
|
||||
|
||||
// Draw the section content
|
||||
ImGui::BeginDisabled(!enabled);
|
||||
{
|
||||
if (section->isEnabled()) {
|
||||
if (section->isValid())
|
||||
section->drawContent();
|
||||
else if (section->isAnalyzing())
|
||||
|
||||
@@ -16,6 +16,7 @@ add_imhex_plugin(
|
||||
source/plugin_yara.cpp
|
||||
|
||||
source/content/yara_rule.cpp
|
||||
source/content/data_information_sections.cpp
|
||||
source/content/views/view_yara.cpp
|
||||
INCLUDES
|
||||
include
|
||||
|
||||
@@ -38,7 +38,7 @@ namespace hex::plugin::yara {
|
||||
std::string message;
|
||||
};
|
||||
|
||||
wolv::util::Expected<Result, Error> match(prv::Provider *provider, u64 address, size_t size);
|
||||
wolv::util::Expected<Result, Error> match(prv::Provider *provider, Region region);
|
||||
void interrupt();
|
||||
[[nodiscard]] bool isInterrupted() const;
|
||||
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
#include <hex/api/content_registry.hpp>
|
||||
#include <hex/helpers/magic.hpp>
|
||||
#include <hex/providers/provider.hpp>
|
||||
|
||||
#include <imgui.h>
|
||||
#include <hex/api/task_manager.hpp>
|
||||
#include <hex/ui/imgui_imhex_extensions.h>
|
||||
|
||||
#include <content/yara_rule.hpp>
|
||||
#include <romfs/romfs.hpp>
|
||||
|
||||
namespace hex::plugin::yara {
|
||||
|
||||
class InformationYaraRules : public ContentRegistry::DataInformation::InformationSection {
|
||||
public:
|
||||
InformationYaraRules() : InformationSection("hex.yara.information_section.yara_rules") { }
|
||||
~InformationYaraRules() override = default;
|
||||
|
||||
void process(Task &task, prv::Provider *provider, Region region) override {
|
||||
const auto &ruleFilePaths = romfs::list("rules");
|
||||
task.setMaxValue(ruleFilePaths.size());
|
||||
|
||||
u32 progress = 0;
|
||||
for (const auto &ruleFilePath : ruleFilePaths) {
|
||||
const std::string fileContent = romfs::get(ruleFilePath).data<const char>();
|
||||
|
||||
YaraRule rule(fileContent);
|
||||
auto result = rule.match(provider, region);
|
||||
if (result.has_value()) {
|
||||
m_matches[ruleFilePath.filename().string()] = result.value().matches;
|
||||
}
|
||||
|
||||
task.update(progress);
|
||||
progress += 1;
|
||||
}
|
||||
}
|
||||
|
||||
void reset() override {
|
||||
m_matches.clear();
|
||||
}
|
||||
|
||||
void drawContent() override {
|
||||
if (ImGui::BeginTable("information", 2, ImGuiTableFlags_SizingStretchProp | ImGuiTableFlags_NoKeepColumnsVisible)) {
|
||||
ImGui::TableSetupColumn("Left", ImGuiTableColumnFlags_WidthStretch, 0.5F);
|
||||
ImGui::TableSetupColumn("Right", ImGuiTableColumnFlags_WidthStretch, 0.5F);
|
||||
|
||||
ImGui::TableNextRow();
|
||||
|
||||
for (auto &[name, matches] : m_matches) {
|
||||
if (matches.empty())
|
||||
continue;
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
ImGuiExt::BeginSubWindow(name.c_str());
|
||||
{
|
||||
for (const auto &match : matches) {
|
||||
ImGui::TextUnformatted(match.identifier.c_str());
|
||||
}
|
||||
}
|
||||
ImGuiExt::EndSubWindow();
|
||||
}
|
||||
|
||||
ImGui::EndTable();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
std::map<std::string, std::vector<YaraRule::Match>> m_matches;
|
||||
};
|
||||
|
||||
void registerDataInformationSections() {
|
||||
ContentRegistry::DataInformation::addInformationSection<InformationYaraRules>();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -264,7 +264,7 @@ namespace hex::plugin::yara {
|
||||
rule.interrupt();
|
||||
});
|
||||
|
||||
auto result = rule.match(provider, provider->getBaseAddress(), provider->getSize());
|
||||
auto result = rule.match(provider, { provider->getBaseAddress(), provider->getSize() });
|
||||
if (!result.has_value()) {
|
||||
TaskManager::doLater([this, error = result.error()] {
|
||||
m_consoleMessages->emplace_back(error.message);
|
||||
|
||||
@@ -73,7 +73,7 @@ namespace hex::plugin::yara {
|
||||
return results.rule->isInterrupted() ? CALLBACK_ABORT : CALLBACK_CONTINUE;
|
||||
}
|
||||
|
||||
wolv::util::Expected<YaraRule::Result, YaraRule::Error> YaraRule::match(prv::Provider *provider, u64 address, size_t size) {
|
||||
wolv::util::Expected<YaraRule::Result, YaraRule::Error> YaraRule::match(prv::Provider *provider, Region region) {
|
||||
YR_COMPILER *compiler = nullptr;
|
||||
yr_compiler_create(&compiler);
|
||||
ON_SCOPE_EXIT {
|
||||
@@ -126,7 +126,7 @@ namespace hex::plugin::yara {
|
||||
ScanContext context;
|
||||
|
||||
context.provider = provider;
|
||||
context.region = { address, size };
|
||||
context.region = region;
|
||||
context.currBlock.base = 0;
|
||||
context.currBlock.fetch_data = [](YR_MEMORY_BLOCK *block) -> const u8 * {
|
||||
auto &context = *static_cast<ScanContext *>(block->context);
|
||||
|
||||
@@ -10,8 +10,9 @@
|
||||
using namespace hex;
|
||||
using namespace hex::plugin::yara;
|
||||
|
||||
namespace {
|
||||
namespace hex::plugin::yara {
|
||||
|
||||
void registerDataInformationSections();
|
||||
void registerViews() {
|
||||
ContentRegistry::Views::add<ViewYara>();
|
||||
}
|
||||
@@ -24,4 +25,5 @@ IMHEX_PLUGIN_SETUP("Yara Rules", "WerWolv", "Support for matching Yara rules") {
|
||||
hex::ContentRegistry::Language::addLocalization(nlohmann::json::parse(romfs::get(path).string()));
|
||||
|
||||
registerViews();
|
||||
registerDataInformationSections();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user