feat: Added simple yara data analyzer

This commit is contained in:
WerWolv
2024-02-21 23:17:12 +01:00
parent 4bd24a4ffe
commit 5ccb7a7b9a
7 changed files with 84 additions and 6 deletions

View File

@@ -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())

View File

@@ -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

View File

@@ -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;

View File

@@ -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>();
}
}

View File

@@ -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);

View File

@@ -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);

View File

@@ -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();
}