Skip to content

Commit 8b6346a

Browse files
committed
feat: Allow jumping to Yara rule matches
Fixes #2439
1 parent c161982 commit 8b6346a

File tree

1 file changed

+25
-5
lines changed

1 file changed

+25
-5
lines changed

plugins/yara_rules/source/content/views/view_yara.cpp

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -203,33 +203,53 @@ namespace hex::plugin::yara {
203203
matchesTableSize.y -= ImGui::GetTextLineHeightWithSpacing();
204204
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, { 0, 0 });
205205
if (ImGuiExt::BeginSubWindow("hex.yara_rules.view.yara.header.matches"_lang, nullptr, matchesTableSize)) {
206-
if (ImGui::BeginTable("matches", 3, ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable | ImGuiTableFlags_Sortable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_RowBg | ImGuiTableFlags_ScrollY)) {
206+
if (ImGui::BeginTable("matches", 3, ImGuiTableFlags_SizingStretchProp | ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_RowBg | ImGuiTableFlags_ScrollY)) {
207207
ImGui::TableSetupScrollFreeze(0, 1);
208-
ImGui::TableSetupColumn("hex.yara_rules.view.yara.matches.variable"_lang, ImGuiTableColumnFlags_PreferSortAscending, 0, ImGui::GetID("variable"));
209-
ImGui::TableSetupColumn("hex.ui.common.address"_lang, ImGuiTableColumnFlags_PreferSortAscending, 0, ImGui::GetID("address"));
210-
ImGui::TableSetupColumn("hex.ui.common.size"_lang, ImGuiTableColumnFlags_PreferSortAscending, 0, ImGui::GetID("size"));
208+
ImGui::TableSetupColumn("hex.yara_rules.view.yara.matches.variable"_lang, ImGuiTableColumnFlags_None, 0.5);
209+
ImGui::TableSetupColumn("hex.ui.common.address"_lang, ImGuiTableColumnFlags_None, 0.25);
210+
ImGui::TableSetupColumn("hex.ui.common.size"_lang, ImGuiTableColumnFlags_None, 0.25);
211211

212212
ImGui::TableHeadersRow();
213213

214214
if (!m_matcherTask.isRunning()) {
215+
u32 ruleId = 1;
215216
for (const auto &rule : *m_matchedRules) {
216217
if (rule.matches.empty()) continue;
217218

218219
ImGui::TableNextRow();
219220
ImGui::TableNextColumn();
220221

221-
if (ImGui::TreeNode(rule.identifier.c_str())) {
222+
ImGui::PushID(ruleId);
223+
ImGui::PushStyleVarX(ImGuiStyleVar_FramePadding, 0.0F);
224+
const bool open = ImGui::TreeNodeEx("##TreeNode", ImGuiTreeNodeFlags_DrawLinesToNodes | ImGuiTreeNodeFlags_SpanLabelWidth | ImGuiTreeNodeFlags_OpenOnArrow);
225+
ImGui::PopStyleVar();
226+
ImGui::SameLine();
227+
ImGui::TextUnformatted(rule.identifier.c_str());
228+
if (open) {
229+
u32 matchId = 1;
222230
for (const auto &match : rule.matches) {
223231
ImGui::TableNextRow();
224232
ImGui::TableNextColumn();
233+
ImGui::PushID(matchId);
234+
235+
if (ImGui::Selectable("##match_selectable", false, ImGuiSelectableFlags_SpanAllColumns)) {
236+
ImHexApi::HexEditor::setSelection(match.region);
237+
}
238+
239+
ImGui::SameLine();
225240
ImGui::TextUnformatted(match.variable.c_str());
226241
ImGui::TableNextColumn();
227242
ImGui::TextUnformatted(fmt::format("0x{0:08X}", match.region.getStartAddress()).c_str());
228243
ImGui::TableNextColumn();
229244
ImGui::TextUnformatted(fmt::format("0x{0:08X}", match.region.getSize()).c_str());
245+
246+
ImGui::PopID();
247+
matchId += 1;
230248
}
231249
ImGui::TreePop();
232250
}
251+
ImGui::PopID();
252+
ruleId += 1;
233253
}
234254
}
235255

0 commit comments

Comments
 (0)