From 84f80b3e063a292d8871f2e361821909c1d5ace4 Mon Sep 17 00:00:00 2001 From: WerWolv Date: Mon, 23 Nov 2020 13:10:14 +0100 Subject: [PATCH] Select region when clicking on string, disassembly or pattern data item --- include/event.hpp | 4 +++- include/lang/pattern_data.hpp | 7 +++++++ include/providers/provider.hpp | 10 ++++++++++ include/utils.hpp | 5 +++++ include/views/view_disassembler.hpp | 1 + source/views/view_disassembler.cpp | 18 ++++++++++++++++++ source/views/view_hexeditor.cpp | 13 +++++++++++++ source/views/view_strings.cpp | 8 ++++++++ 8 files changed, 65 insertions(+), 1 deletion(-) diff --git a/include/event.hpp b/include/event.hpp index d8df5fc73..779b3314a 100644 --- a/include/event.hpp +++ b/include/event.hpp @@ -9,7 +9,9 @@ namespace hex { DataChanged, PatternChanged, FileDropped, - ByteSelected + ByteSelected, + + SelectionChangeRequest }; struct EventHandler { diff --git a/include/lang/pattern_data.hpp b/include/lang/pattern_data.hpp index 7de1d9db3..2dece4fa5 100644 --- a/include/lang/pattern_data.hpp +++ b/include/lang/pattern_data.hpp @@ -13,6 +13,8 @@ namespace hex::lang { + using namespace ::std::literals::string_literals; + namespace { std::string makeDisplayable(u8 *data, size_t size) { @@ -131,6 +133,11 @@ namespace hex::lang { ImGui::TableNextColumn(); ImGui::ColorButton("color", ImColor(this->getColor()), ImGuiColorEditFlags_NoTooltip); ImGui::TableNextColumn(); + if (ImGui::Selectable(("##PatternDataLine"s + std::to_string(this->getOffset())).c_str(), false, ImGuiSelectableFlags_SpanAllColumns)) { + Region selectRegion = { this->getOffset(), this->getSize() }; + View::postEvent(Events::SelectionChangeRequest, &selectRegion); + } + ImGui::SameLine(); ImGui::Text("%s", this->getName().c_str()); ImGui::TableNextColumn(); ImGui::Text("0x%08lx : 0x%08lx", this->getOffset(), this->getOffset() + this->getSize() - 1); diff --git a/include/providers/provider.hpp b/include/providers/provider.hpp index ac69dab70..7e8599756 100644 --- a/include/providers/provider.hpp +++ b/include/providers/provider.hpp @@ -3,6 +3,7 @@ #include #include +#include #include #include @@ -35,6 +36,15 @@ namespace hex::prv { return std::min(this->getActualSize() - PageSize * this->m_currPage, PageSize); } + virtual std::optional getPageOfAddress(u64 address) { + u32 page = std::floor(address / double(PageSize)); + + if (page >= this->getPageCount()) + return { }; + + return page; + } + virtual std::vector> getDataInformation() = 0; protected: diff --git a/include/utils.hpp b/include/utils.hpp index cc826dcd3..e24bb5e10 100644 --- a/include/utils.hpp +++ b/include/utils.hpp @@ -136,4 +136,9 @@ namespace hex { private: std::function m_func; }; + + struct Region { + u64 address; + size_t size; + }; } \ No newline at end of file diff --git a/include/views/view_disassembler.hpp b/include/views/view_disassembler.hpp index 410698d94..ee5eecfc6 100644 --- a/include/views/view_disassembler.hpp +++ b/include/views/view_disassembler.hpp @@ -15,6 +15,7 @@ namespace hex { struct Disassembly { u64 address; u64 offset; + size_t size; std::string bytes; std::string opcodeString; }; diff --git a/source/views/view_disassembler.cpp b/source/views/view_disassembler.cpp index c7a658149..f4e66c33b 100644 --- a/source/views/view_disassembler.cpp +++ b/source/views/view_disassembler.cpp @@ -59,6 +59,7 @@ namespace hex { Disassembly disassembly = { 0 }; disassembly.address = instructions[instr].address; disassembly.offset = this->m_codeOffset + address + usedBytes; + disassembly.size = instructions[instr].size; disassembly.opcodeString = instructions[instr].mnemonic + " "s + instructions[instr].op_str; for (u8 i = 0; i < instructions[instr].size; i++) @@ -120,6 +121,9 @@ namespace hex { this->m_micoMode = false; this->m_sparcV9Mode = false; + if (this->m_modeBasicARM == cs_mode(0)) + this->m_modeBasicARM = CS_MODE_ARM; + if (ImGui::RadioButton("ARM mode", this->m_modeBasicARM == CS_MODE_ARM)) this->m_modeBasicARM = CS_MODE_ARM; ImGui::SameLine(); @@ -142,6 +146,9 @@ namespace hex { this->m_modeBasicPPC = cs_mode(0); this->m_sparcV9Mode = false; + if (this->m_modeBasicMIPS == cs_mode(0)) + this->m_modeBasicMIPS = CS_MODE_MIPS32; + if (ImGui::RadioButton("MIPS32 mode", this->m_modeBasicMIPS == CS_MODE_MIPS32)) this->m_modeBasicMIPS = CS_MODE_MIPS32; ImGui::SameLine(); @@ -161,6 +168,9 @@ namespace hex { this->m_micoMode = false; this->m_sparcV9Mode = false; + if (this->m_modeBasicX86 == cs_mode(0)) + this->m_modeBasicX86 = CS_MODE_16; + if (ImGui::RadioButton("16-bit mode", this->m_modeBasicX86 == CS_MODE_16)) this->m_modeBasicX86 = CS_MODE_16; ImGui::SameLine(); @@ -178,6 +188,9 @@ namespace hex { this->m_micoMode = false; this->m_sparcV9Mode = false; + if (m_modeBasicPPC == cs_mode(0)) + this->m_modeBasicPPC = CS_MODE_32; + if (ImGui::RadioButton("32-bit mode", this->m_modeBasicPPC == CS_MODE_32)) this->m_modeBasicPPC = CS_MODE_32; ImGui::SameLine(); @@ -236,6 +249,11 @@ namespace hex { for (u64 i = clipper.DisplayStart; i < clipper.DisplayEnd; i++) { ImGui::TableNextRow(); ImGui::TableNextColumn(); + if (ImGui::Selectable(("##DisassemblyLine"s + std::to_string(i)).c_str(), false, ImGuiSelectableFlags_SpanAllColumns)) { + Region selectRegion = { this->m_disassembly[i].offset, this->m_disassembly[i].size }; + View::postEvent(Events::SelectionChangeRequest, &selectRegion); + } + ImGui::SameLine(); ImGui::Text("0x%llx", this->m_disassembly[i].address); ImGui::TableNextColumn(); ImGui::Text("0x%llx", this->m_disassembly[i].offset); diff --git a/source/views/view_hexeditor.cpp b/source/views/view_hexeditor.cpp index 5b8819a9f..fe46a2fff 100644 --- a/source/views/view_hexeditor.cpp +++ b/source/views/view_hexeditor.cpp @@ -56,6 +56,19 @@ namespace hex { if (filePath != nullptr) this->openFile(filePath); }); + + View::subscribeEvent(Events::SelectionChangeRequest, [this](const void *userData) { + const Region ®ion = *reinterpret_cast(userData); + + auto page = this->m_dataProvider->getPageOfAddress(region.address); + if (!page.has_value()) + return; + + this->m_dataProvider->setCurrentPage(page.value()); + this->m_memoryEditor.GotoAddr = region.address; + this->m_memoryEditor.DataPreviewAddr = region.address; + this->m_memoryEditor.DataPreviewAddrEnd = region.address + region.size - 1; + }); } ViewHexEditor::~ViewHexEditor() { diff --git a/source/views/view_strings.cpp b/source/views/view_strings.cpp index 397fe0617..6cef1d103 100644 --- a/source/views/view_strings.cpp +++ b/source/views/view_strings.cpp @@ -1,9 +1,12 @@ #include "views/view_strings.hpp" #include "providers/provider.hpp" +#include "utils.hpp" #include +using namespace std::literals::string_literals; + namespace hex { ViewStrings::ViewStrings(prv::Provider* &dataProvider) : View(), m_dataProvider(dataProvider) { @@ -122,6 +125,11 @@ namespace hex { ImGui::TableNextRow(); ImGui::TableNextColumn(); + if (ImGui::Selectable(("##StringLine"s + std::to_string(i)).c_str(), false, ImGuiSelectableFlags_SpanAllColumns)) { + Region selectRegion = { foundString.offset, foundString.size }; + View::postEvent(Events::SelectionChangeRequest, &selectRegion); + } + ImGui::SameLine(); ImGui::Text("0x%08lx : 0x%08lx", foundString.offset, foundString.offset + foundString.size); ImGui::TableNextColumn(); ImGui::Text("0x%04lx", foundString.size);