ImHex/plugins/yara_rules/source/content/data_information_sections.cpp

93 lines
3.3 KiB
C++
Raw Normal View History

2024-02-21 22:17:12 +00:00
#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 {
2024-02-22 20:31:26 +00:00
class InformationAdvancedFileInformation : public ContentRegistry::DataInformation::InformationSection {
2024-02-21 22:17:12 +00:00
public:
InformationAdvancedFileInformation() : InformationSection("hex.yara.information_section.advanced_data_info") { }
2024-02-22 20:31:26 +00:00
~InformationAdvancedFileInformation() override = default;
2024-02-21 22:17:12 +00:00
struct Category {
struct Comperator {
bool operator()(const YaraRule::Rule &a, const YaraRule::Rule &b) const {
return a.identifier < b.identifier;
}
};
std::set<YaraRule::Rule, Comperator> matchedRules;
};
2024-02-21 22:17:12 +00:00
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 yaraRule(fileContent);
const auto result = yaraRule.match(provider, region);
2024-02-21 22:17:12 +00:00
if (result.has_value()) {
const auto &rules = result.value().matchedRules;
for (const auto &rule : rules) {
if (!rule.metadata.contains("category")) continue;
const auto &categoryName = rule.metadata.at("category");
m_categories[categoryName].matchedRules.insert(rule);
}
2024-02-21 22:17:12 +00:00
}
task.update(progress);
progress += 1;
}
}
void reset() override {
m_categories.clear();
2024-02-21 22:17:12 +00:00
}
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 &[categoryName, category] : m_categories) {
if (category.matchedRules.empty())
2024-02-21 22:17:12 +00:00
continue;
ImGui::TableNextColumn();
ImGuiExt::BeginSubWindow(categoryName.c_str());
2024-02-21 22:17:12 +00:00
{
for (const auto &match : category.matchedRules) {
const auto &ruleName = match.metadata.contains("name") ? match.metadata.at("name") : match.identifier;
ImGui::TextUnformatted(ruleName.c_str());
2024-02-21 22:17:12 +00:00
}
}
ImGuiExt::EndSubWindow();
}
ImGui::EndTable();
}
}
private:
std::map<std::string, Category> m_categories;
2024-02-21 22:17:12 +00:00
};
void registerDataInformationSections() {
2024-02-22 20:31:26 +00:00
ContentRegistry::DataInformation::addInformationSection<InformationAdvancedFileInformation>();
2024-02-21 22:17:12 +00:00
}
}