1
0
mirror of synced 2025-01-31 03:53:44 +01:00

feat: Make yara match list sortable

This commit is contained in:
WerWolv 2023-03-16 13:35:09 +01:00
parent 4271b2e9fd
commit 5a2b2e0813
3 changed files with 50 additions and 19 deletions

View File

@ -110,6 +110,7 @@ namespace hex::plugin::builtin {
std::vector<std::pair<std::fs::path, std::fs::path>> rules;
std::vector<YaraMatch> matches;
std::vector<YaraMatch*> sortedMatches;
} yara;
};

View File

@ -20,9 +20,12 @@
#include <wolv/io/file.hpp>
#include <wolv/io/fs.hpp>
#include <wolv/utils/guards.hpp>
#include <wolv/literals.hpp>
namespace hex::plugin::builtin {
using namespace wolv::literals;
ViewYara::ViewYara() : View("hex.builtin.view.yara.name") {
yr_initialize();
@ -105,6 +108,7 @@ namespace hex::plugin::builtin {
auto &extraData = ProviderExtraData::getCurrent().yara;
auto &rules = extraData.rules;
auto &matches = extraData.matches;
auto &sortedMatches = extraData.sortedMatches;
if (ImGui::BeginListBox("##rules", ImVec2(-FLT_MIN, ImGui::GetTextLineHeightWithSpacing() * 5))) {
for (u32 i = 0; i < rules.size(); i++) {
@ -161,20 +165,46 @@ namespace hex::plugin::builtin {
if (ImGui::BeginTable("matches", 4, ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable | ImGuiTableFlags_Sortable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_RowBg | ImGuiTableFlags_ScrollY, matchesTableSize)) {
ImGui::TableSetupScrollFreeze(0, 1);
ImGui::TableSetupColumn("hex.builtin.view.yara.matches.identifier"_lang);
ImGui::TableSetupColumn("hex.builtin.view.yara.matches.variable"_lang);
ImGui::TableSetupColumn("hex.builtin.common.address"_lang);
ImGui::TableSetupColumn("hex.builtin.common.size"_lang);
ImGui::TableSetupColumn("hex.builtin.view.yara.matches.identifier"_lang, ImGuiTableColumnFlags_PreferSortAscending, 0, ImGui::GetID("identifier"));
ImGui::TableSetupColumn("hex.builtin.view.yara.matches.variable"_lang, ImGuiTableColumnFlags_PreferSortAscending, 0, ImGui::GetID("variable"));
ImGui::TableSetupColumn("hex.builtin.common.address"_lang, ImGuiTableColumnFlags_PreferSortAscending, 0, ImGui::GetID("address"));
ImGui::TableSetupColumn("hex.builtin.common.size"_lang, ImGuiTableColumnFlags_PreferSortAscending, 0, ImGui::GetID("size"));
ImGui::TableHeadersRow();
auto sortSpecs = ImGui::TableGetSortSpecs();
if (!matches.empty() && (sortSpecs->SpecsDirty || sortedMatches.empty())) {
sortedMatches.clear();
std::transform(matches.begin(), matches.end(), std::back_inserter(sortedMatches), [](auto &match) {
return &match;
});
std::sort(sortedMatches.begin(), sortedMatches.end(), [&sortSpecs](ProviderExtraData::Data::Yara::YaraMatch *left, ProviderExtraData::Data::Yara::YaraMatch *right) -> bool {
if (sortSpecs->Specs->ColumnUserID == ImGui::GetID("identifier"))
return left->identifier < right->identifier;
else if (sortSpecs->Specs->ColumnUserID == ImGui::GetID("variable"))
return left->variable < right->variable;
else if (sortSpecs->Specs->ColumnUserID == ImGui::GetID("address"))
return left->address < right->address;
else if (sortSpecs->Specs->ColumnUserID == ImGui::GetID("size"))
return left->size < right->size;
else
return false;
});
if (sortSpecs->Specs->SortDirection == ImGuiSortDirection_Descending)
std::reverse(sortedMatches.begin(), sortedMatches.end());
sortSpecs->SpecsDirty = false;
}
if (!this->m_matcherTask.isRunning()) {
ImGuiListClipper clipper;
clipper.Begin(matches.size());
clipper.Begin(sortedMatches.size());
while (clipper.Step()) {
for (int i = clipper.DisplayStart; i < clipper.DisplayEnd; i++) {
auto &[identifier, variableName, address, size, wholeDataMatch, highlightId, tooltipId] = matches[i];
auto &[identifier, variableName, address, size, wholeDataMatch, highlightId, tooltipId] = *sortedMatches[i];
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::PushID(i);
@ -357,7 +387,7 @@ namespace hex::plugin::builtin {
iterator->last_error = ERROR_SUCCESS;
context.currBlock.base = address;
context.currBlock.size = ImHexApi::Provider::get()->getActualSize() - address;
context.currBlock.size = std::min<size_t>(ImHexApi::Provider::get()->getActualSize() - address, 10_MiB);
context.currBlock.context = &context;
context.task->update(address);

View File

@ -765,34 +765,34 @@ namespace hex::plugin::builtin::ui {
static bool sortPatterns(const ImGuiTableSortSpecs* sortSpecs, const pl::ptrn::Pattern * left, const pl::ptrn::Pattern * right) {
if (sortSpecs->Specs->ColumnUserID == ImGui::GetID("name")) {
if (sortSpecs->Specs->SortDirection == ImGuiSortDirection_Ascending)
return left->getDisplayName() > right->getDisplayName();
else
return left->getDisplayName() < right->getDisplayName();
else
return left->getDisplayName() > right->getDisplayName();
} else if (sortSpecs->Specs->ColumnUserID == ImGui::GetID("offset")) {
if (sortSpecs->Specs->SortDirection == ImGuiSortDirection_Ascending)
return left->getOffset() > right->getOffset();
else
return left->getOffset() < right->getOffset();
else
return left->getOffset() > right->getOffset();
} else if (sortSpecs->Specs->ColumnUserID == ImGui::GetID("size")) {
if (sortSpecs->Specs->SortDirection == ImGuiSortDirection_Ascending)
return left->getSize() > right->getSize();
else
return left->getSize() < right->getSize();
else
return left->getSize() > right->getSize();
} else if (sortSpecs->Specs->ColumnUserID == ImGui::GetID("value")) {
if (sortSpecs->Specs->SortDirection == ImGuiSortDirection_Ascending)
return left->getValue() > right->getValue();
else
return left->getValue() < right->getValue();
else
return left->getValue() > right->getValue();
} else if (sortSpecs->Specs->ColumnUserID == ImGui::GetID("type")) {
if (sortSpecs->Specs->SortDirection == ImGuiSortDirection_Ascending)
return left->getTypeName() > right->getTypeName();
else
return left->getTypeName() < right->getTypeName();
else
return left->getTypeName() > right->getTypeName();
} else if (sortSpecs->Specs->ColumnUserID == ImGui::GetID("color")) {
if (sortSpecs->Specs->SortDirection == ImGuiSortDirection_Ascending)
return left->getColor() > right->getColor();
else
return left->getColor() < right->getColor();
else
return left->getColor() > right->getColor();
}
return false;