1
0
mirror of synced 2025-01-31 12:03:46 +01:00

ui: Added console to yara view, add support for yara's new console module

This commit is contained in:
WerWolv 2022-03-15 23:48:49 +01:00
parent 29ded2483c
commit f6a498854c
3 changed files with 116 additions and 65 deletions

View File

@ -28,10 +28,12 @@ namespace hex::plugin::builtin {
std::vector<YaraMatch> m_matches; std::vector<YaraMatch> m_matches;
u32 m_selectedRule = 0; u32 m_selectedRule = 0;
bool m_matching = false; bool m_matching = false;
std::vector<char> m_errorMessage;
std::vector<std::string> m_consoleMessages;
void reloadRules(); void reloadRules();
void applyRules(); void applyRules();
void clearResult();
}; };
} }

View File

@ -263,20 +263,20 @@ namespace hex::plugin::builtin {
textEditorSize.y -= ImGui::GetTextLineHeightWithSpacing(); textEditorSize.y -= ImGui::GetTextLineHeightWithSpacing();
this->m_textEditor.Render("hex.builtin.view.pattern_editor.name"_lang, textEditorSize, true); this->m_textEditor.Render("hex.builtin.view.pattern_editor.name"_lang, textEditorSize, true);
auto size = ImGui::GetContentRegionAvail(); auto settingsSize = ImGui::GetContentRegionAvail();
size.y -= ImGui::GetTextLineHeightWithSpacing() * 2.5; settingsSize.y -= ImGui::GetTextLineHeightWithSpacing() * 2.5;
if (ImGui::BeginTabBar("##settings")) { if (ImGui::BeginTabBar("##settings")) {
if (ImGui::BeginTabItem("hex.builtin.view.pattern_editor.console"_lang)) { if (ImGui::BeginTabItem("hex.builtin.view.pattern_editor.console"_lang)) {
this->drawConsole(size); this->drawConsole(settingsSize);
ImGui::EndTabItem(); ImGui::EndTabItem();
} }
if (ImGui::BeginTabItem("hex.builtin.view.pattern_editor.env_vars"_lang)) { if (ImGui::BeginTabItem("hex.builtin.view.pattern_editor.env_vars"_lang)) {
this->drawEnvVars(size); this->drawEnvVars(settingsSize);
ImGui::EndTabItem(); ImGui::EndTabItem();
} }
if (ImGui::BeginTabItem("hex.builtin.view.pattern_editor.settings"_lang)) { if (ImGui::BeginTabItem("hex.builtin.view.pattern_editor.settings"_lang)) {
this->drawVariableSettings(size); this->drawVariableSettings(settingsSize);
ImGui::EndTabItem(); ImGui::EndTabItem();
} }

View File

@ -40,11 +40,6 @@ namespace hex::plugin::builtin {
void ViewYara::drawContent() { void ViewYara::drawContent() {
if (ImGui::Begin(View::toWindowName("hex.builtin.view.yara.name").c_str(), &this->getWindowOpenState(), ImGuiWindowFlags_NoCollapse)) { if (ImGui::Begin(View::toWindowName("hex.builtin.view.yara.name").c_str(), &this->getWindowOpenState(), ImGuiWindowFlags_NoCollapse)) {
if (!this->m_matching && !this->m_errorMessage.empty()) {
View::showErrorPopup("hex.builtin.view.yara.error"_lang + this->m_errorMessage.data());
this->m_errorMessage.clear();
}
ImGui::TextUnformatted("hex.builtin.view.yara.header.rules"_lang); ImGui::TextUnformatted("hex.builtin.view.yara.header.rules"_lang);
ImGui::Separator(); ImGui::Separator();
@ -81,7 +76,11 @@ namespace hex::plugin::builtin {
ImGui::TextUnformatted("hex.builtin.view.yara.header.matches"_lang); ImGui::TextUnformatted("hex.builtin.view.yara.header.matches"_lang);
ImGui::Separator(); ImGui::Separator();
if (ImGui::BeginTable("matches", 4, ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable | ImGuiTableFlags_Sortable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_RowBg | ImGuiTableFlags_ScrollY)) { auto matchesTableSize = ImGui::GetContentRegionAvail();
matchesTableSize.y *= 3.75 / 5.0;
matchesTableSize.y -= ImGui::GetTextLineHeightWithSpacing();
if (ImGui::BeginTable("matches", 4, ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable | ImGuiTableFlags_Sortable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_RowBg | ImGuiTableFlags_ScrollY, matchesTableSize)) {
ImGui::TableSetupScrollFreeze(0, 1); ImGui::TableSetupScrollFreeze(0, 1);
ImGui::TableSetupColumn("hex.builtin.view.yara.matches.identifier"_lang); ImGui::TableSetupColumn("hex.builtin.view.yara.matches.identifier"_lang);
ImGui::TableSetupColumn("hex.builtin.view.yara.matches.variable"_lang); ImGui::TableSetupColumn("hex.builtin.view.yara.matches.variable"_lang);
@ -90,6 +89,7 @@ namespace hex::plugin::builtin {
ImGui::TableHeadersRow(); ImGui::TableHeadersRow();
if (!this->m_matching) {
ImGuiListClipper clipper; ImGuiListClipper clipper;
clipper.Begin(this->m_matches.size()); clipper.Begin(this->m_matches.size());
@ -123,13 +123,36 @@ namespace hex::plugin::builtin {
} }
clipper.End(); clipper.End();
}
ImGui::EndTable(); ImGui::EndTable();
} }
auto consoleSize = ImGui::GetContentRegionAvail();
if (ImGui::BeginChild("##console", consoleSize, true, ImGuiWindowFlags_AlwaysVerticalScrollbar | ImGuiWindowFlags_HorizontalScrollbar)) {
ImGuiListClipper clipper(this->m_consoleMessages.size());
while (clipper.Step())
for (u64 i = clipper.DisplayStart; i < clipper.DisplayEnd; i++) {
const auto &message = this->m_consoleMessages[i];
if (ImGui::Selectable(message.c_str()))
ImGui::SetClipboardText(message.c_str());
}
}
ImGui::EndChild();
} }
ImGui::End(); ImGui::End();
} }
void ViewYara::clearResult() {
for (const auto &match : this->m_matches)
ImHexApi::HexEditor::removeHighlight(match.highlightId);
this->m_matches.clear();
this->m_consoleMessages.clear();
}
void ViewYara::reloadRules() { void ViewYara::reloadRules() {
this->m_rules.clear(); this->m_rules.clear();
@ -147,11 +170,8 @@ namespace hex::plugin::builtin {
} }
void ViewYara::applyRules() { void ViewYara::applyRules() {
for (const auto &match : this->m_matches) this->clearResult();
ImHexApi::HexEditor::removeHighlight(match.highlightId);
this->m_matches.clear();
this->m_errorMessage.clear();
this->m_matching = true; this->m_matching = true;
std::thread([this] { std::thread([this] {
@ -193,8 +213,16 @@ namespace hex::plugin::builtin {
if (!file.isValid()) return; if (!file.isValid()) return;
if (yr_compiler_add_file(compiler, file.getHandle(), nullptr, nullptr) != 0) { if (yr_compiler_add_file(compiler, file.getHandle(), nullptr, nullptr) != 0) {
this->m_errorMessage.resize(0xFFFF); std::string errorMessage(0xFFFF, '\x00');
yr_compiler_get_error_message(compiler, this->m_errorMessage.data(), this->m_errorMessage.size()); yr_compiler_get_error_message(compiler, errorMessage.data(), errorMessage.size());
hex::trim(errorMessage);
ImHexApi::Tasks::doLater([this, errorMessage] {
this->clearResult();
this->m_consoleMessages.push_back("Error: " + errorMessage);
});
return; return;
} }
@ -202,8 +230,6 @@ namespace hex::plugin::builtin {
yr_compiler_get_rules(compiler, &rules); yr_compiler_get_rules(compiler, &rules);
ON_SCOPE_EXIT { yr_rules_destroy(rules); }; ON_SCOPE_EXIT { yr_rules_destroy(rules); };
std::vector<YaraMatch> newMatches;
YR_MEMORY_BLOCK_ITERATOR iterator; YR_MEMORY_BLOCK_ITERATOR iterator;
struct ScanContext { struct ScanContext {
@ -262,10 +288,20 @@ namespace hex::plugin::builtin {
}; };
struct ResultContext {
std::vector<YaraMatch> newMatches;
std::vector<std::string> consoleMessages;
};
ResultContext resultContext;
yr_rules_scan_mem_blocks( yr_rules_scan_mem_blocks(
rules, &iterator, 0, [](YR_SCAN_CONTEXT *context, int message, void *data, void *userData) -> int { rules, &iterator, 0, [](YR_SCAN_CONTEXT *context, int message, void *data, void *userData) -> int {
if (message == CALLBACK_MSG_RULE_MATCHING) { auto &results = *static_cast<ResultContext *>(userData);
auto &newMatches = *static_cast<std::vector<YaraMatch> *>(userData);
switch (message) {
case CALLBACK_MSG_RULE_MATCHING:
{
auto rule = static_cast<YR_RULE *>(data); auto rule = static_cast<YR_RULE *>(data);
YR_STRING *string; YR_STRING *string;
@ -274,24 +310,37 @@ namespace hex::plugin::builtin {
if (rule->strings != nullptr) { if (rule->strings != nullptr) {
yr_rule_strings_foreach(rule, string) { yr_rule_strings_foreach(rule, string) {
yr_string_matches_foreach(context, string, match) { yr_string_matches_foreach(context, string, match) {
newMatches.push_back({ rule->identifier, string->identifier, u64(match->offset), size_t(match->match_length), false }); results.newMatches.push_back({ rule->identifier, string->identifier, u64(match->offset), size_t(match->match_length), false });
} }
} }
} else { } else {
newMatches.push_back({ rule->identifier, "", 0, 0, true }); results.newMatches.push_back({ rule->identifier, "", 0, 0, true });
} }
} }
break;
case CALLBACK_MSG_CONSOLE_LOG:
{
results.consoleMessages.emplace_back(static_cast<const char *>(data));
}
break;
default:
break;
}
return CALLBACK_CONTINUE; return CALLBACK_CONTINUE;
}, },
&newMatches, &resultContext,
0); 0);
for (auto &match : newMatches) {
ImHexApi::Tasks::doLater([this, resultContext] {
this->m_matches = resultContext.newMatches;
this->m_consoleMessages = resultContext.consoleMessages;
for (auto &match : this->m_matches) {
match.highlightId = ImHexApi::HexEditor::addHighlight({ match.address, match.size }, 0x70B4771F, hex::format("{0} [{1}]", match.identifier, match.variable)); match.highlightId = ImHexApi::HexEditor::addHighlight({ match.address, match.size }, 0x70B4771F, hex::format("{0} [{1}]", match.identifier, match.variable));
} }
});
std::copy(newMatches.begin(), newMatches.end(), std::back_inserter(this->m_matches));
}).detach(); }).detach();
} }