From 33b70a550f265ebeb5d63ccfdca715cb05d1e9f4 Mon Sep 17 00:00:00 2001 From: WerWolv Date: Sat, 28 Nov 2020 15:53:11 +0100 Subject: [PATCH] Improved look and feel of hash window. Added "Match selection" feature --- include/event.hpp | 2 +- include/views/view_hashes.hpp | 4 +- libs/ImGui/include/imgui_memory_editor.h | 7 +- source/views/view_data_inspector.cpp | 10 +- source/views/view_hashes.cpp | 118 +++++++++++++++-------- source/views/view_hexeditor.cpp | 10 +- 6 files changed, 98 insertions(+), 53 deletions(-) diff --git a/include/event.hpp b/include/event.hpp index b39108f7f..a4a6dc69f 100644 --- a/include/event.hpp +++ b/include/event.hpp @@ -10,7 +10,7 @@ namespace hex { DataChanged, PatternChanged, FileDropped, - ByteSelected, + RegionSelected, SelectionChangeRequest, diff --git a/include/views/view_hashes.hpp b/include/views/view_hashes.hpp index cfa0db89d..282e4b509 100644 --- a/include/views/view_hashes.hpp +++ b/include/views/view_hashes.hpp @@ -21,7 +21,9 @@ namespace hex { bool m_shouldInvalidate = true; int m_currHashFunction = 0; - int m_hashStart = 0, m_hashEnd = 0; + u64 m_hashRegion[2] = { 0 }; + bool m_shouldMatchSelection = false; + static constexpr const char* HashFunctionNames[] = { "CRC16", "CRC32", "MD4", "MD5", "SHA-1", "SHA-224", "SHA-256", "SHA-384", "SHA-512" }; }; diff --git a/libs/ImGui/include/imgui_memory_editor.h b/libs/ImGui/include/imgui_memory_editor.h index 86d7e0e0b..cff430f35 100644 --- a/libs/ImGui/include/imgui_memory_editor.h +++ b/libs/ImGui/include/imgui_memory_editor.h @@ -46,6 +46,7 @@ #include // sprintf, scanf #include // uint8_t, etc. +#include "utils.hpp" #include "views/view.hpp" @@ -420,14 +421,16 @@ struct MemoryEditor DataPreviewAddr = addr; DataPreviewAddrEnd = addr; - hex::View::postEvent(hex::Events::ByteSelected, &DataPreviewAddr); + hex::Region selectionRegion { addr, 1 }; + hex::View::postEvent(hex::Events::RegionSelected, &selectionRegion); } if (!ReadOnly && ImGui::IsItemHovered() && ((ImGui::IsMouseClicked(0) && ImGui::GetIO().KeyShift) || ImGui::IsMouseDragging(0))) { DataPreviewAddrEnd = addr; size_t dataPreviewStart = std::min(DataPreviewAddr, DataPreviewAddrEnd); - hex::View::postEvent(hex::Events::ByteSelected, &dataPreviewStart); + hex::Region selectionRegion { std::min(DataPreviewAddr, DataPreviewAddrEnd), std::max(DataPreviewAddr, DataPreviewAddrEnd) - std::min(DataPreviewAddr, DataPreviewAddrEnd) + 1 }; + hex::View::postEvent(hex::Events::RegionSelected, &selectionRegion); } } } diff --git a/source/views/view_data_inspector.cpp b/source/views/view_data_inspector.cpp index da1fe5137..0c239b5cc 100644 --- a/source/views/view_data_inspector.cpp +++ b/source/views/view_data_inspector.cpp @@ -10,19 +10,19 @@ extern int ImTextCharFromUtf8(unsigned int* out_char, const char* in_text, const namespace hex { ViewDataInspector::ViewDataInspector(prv::Provider* &dataProvider) : View("Data Inspector"), m_dataProvider(dataProvider) { - View::subscribeEvent(Events::ByteSelected, [this](const void* userData){ - size_t offset = *static_cast(userData); + View::subscribeEvent(Events::RegionSelected, [this](const void* userData){ + Region region = *static_cast(userData); - this->m_validBytes = std::min(this->m_dataProvider->getSize() - offset, sizeof(PreviewData)); + this->m_validBytes = std::min(this->m_dataProvider->getSize() - region.address, sizeof(PreviewData)); std::memset(&this->m_previewData, 0x00, sizeof(PreviewData)); - this->m_dataProvider->read(offset, &this->m_previewData, sizeof(PreviewData)); + this->m_dataProvider->read(region.address, &this->m_previewData, sizeof(PreviewData)); this->m_shouldInvalidate = true; }); } ViewDataInspector::~ViewDataInspector() { - View::unsubscribeEvent(Events::ByteSelected); + View::unsubscribeEvent(Events::RegionSelected); } void ViewDataInspector::createView() { diff --git a/source/views/view_hashes.cpp b/source/views/view_hashes.cpp index 179701d91..6ecc25d22 100644 --- a/source/views/view_hashes.cpp +++ b/source/views/view_hashes.cpp @@ -14,10 +14,21 @@ namespace hex { View::subscribeEvent(Events::DataChanged, [this](const void*){ this->m_shouldInvalidate = true; }); + + View::subscribeEvent(Events::RegionSelected, [this](const void *userData) { + Region region = *static_cast(userData); + + if (this->m_shouldMatchSelection) { + this->m_hashRegion[0] = region.address; + this->m_hashRegion[1] = region.address + region.size - 1; + this->m_shouldInvalidate = true; + } + }); } ViewHashes::~ViewHashes() { View::unsubscribeEvent(Events::DataChanged); + View::unsubscribeEvent(Events::RegionSelected); } @@ -29,32 +40,31 @@ namespace hex { void ViewHashes::createView() { if (ImGui::Begin("Hashing", &this->getWindowOpenState(), ImGuiWindowFlags_NoCollapse)) { ImGui::BeginChild("##scrolling", ImVec2(0, 0), false, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoNav); - ImGui::NewLine(); if (this->m_dataProvider != nullptr && this->m_dataProvider->isAvailable()) { + ImGui::TextUnformatted("Region"); + ImGui::Separator(); + + ImGui::InputScalarN("##nolabel", ImGuiDataType_U64, this->m_hashRegion, 2, nullptr, nullptr, "%08X", ImGuiInputTextFlags_CharsHexadecimal); + if (ImGui::IsItemEdited()) this->m_shouldInvalidate = true; + + ImGui::Checkbox("Match selection", &this->m_shouldMatchSelection); + if (ImGui::IsItemEdited()) this->m_shouldInvalidate = true; + + ImGui::NewLine(); + ImGui::TextUnformatted("Settings"); + ImGui::Separator(); + if (ImGui::Combo("Hash Function", &this->m_currHashFunction, HashFunctionNames,sizeof(HashFunctionNames) / sizeof(const char *))) this->m_shouldInvalidate = true; - ImGui::NewLine(); - ImGui::Separator(); - ImGui::NewLine(); - - ImGui::InputInt("Begin", &this->m_hashStart, 0, 0, ImGuiInputTextFlags_CharsHexadecimal); - if (ImGui::IsItemEdited()) this->m_shouldInvalidate = true; - - ImGui::InputInt("End", &this->m_hashEnd, 0, 0, ImGuiInputTextFlags_CharsHexadecimal); - if (ImGui::IsItemEdited()) this->m_shouldInvalidate = true; - size_t dataSize = this->m_dataProvider->getSize(); - if (this->m_hashEnd >= dataSize) - this->m_hashEnd = dataSize - 1; + if (this->m_hashRegion[1] >= dataSize) + this->m_hashRegion[1] = dataSize - 1; - ImGui::NewLine(); - ImGui::Separator(); - ImGui::NewLine(); - if (this->m_hashEnd >= this->m_hashStart) { + if (this->m_hashRegion[1] >= this->m_hashRegion[0]) { switch (this->m_currHashFunction) { case 0: // CRC16 @@ -67,18 +77,19 @@ namespace hex { ImGui::InputInt("Polynomial", &polynomial, 0, 0, ImGuiInputTextFlags_CharsHexadecimal); if (ImGui::IsItemEdited()) this->m_shouldInvalidate = true; - ImGui::NewLine(); - ImGui::Separator(); ImGui::NewLine(); static u16 result = 0; if (this->m_shouldInvalidate) - result = crc16(this->m_dataProvider, this->m_hashStart, this->m_hashEnd - this->m_hashStart + 1, polynomial, init); + result = crc16(this->m_dataProvider, this->m_hashRegion[0], this->m_hashRegion[1] - this->m_hashRegion[0] + 1, polynomial, init); char buffer[sizeof(result) * 2 + 1]; snprintf(buffer, sizeof(buffer), "%04X", result); - ImGui::InputText("Hash value", buffer, ImGuiInputTextFlags_ReadOnly); + + ImGui::TextUnformatted("Result"); + ImGui::Separator(); + ImGui::InputText("##nolabel", buffer, ImGuiInputTextFlags_ReadOnly); } break; case 1: // CRC32 @@ -91,18 +102,19 @@ namespace hex { ImGui::InputInt("Polynomial", &polynomial, 0, 0, ImGuiInputTextFlags_CharsHexadecimal); if (ImGui::IsItemEdited()) this->m_shouldInvalidate = true; - ImGui::NewLine(); - ImGui::Separator(); ImGui::NewLine(); static u32 result = 0; if (this->m_shouldInvalidate) - result = crc32(this->m_dataProvider, this->m_hashStart, this->m_hashEnd - this->m_hashStart + 1, polynomial, init); + result = crc32(this->m_dataProvider, this->m_hashRegion[0], this->m_hashRegion[1] - this->m_hashRegion[0] + 1, polynomial, init); char buffer[sizeof(result) * 2 + 1]; snprintf(buffer, sizeof(buffer), "%08X", result); - ImGui::InputText("Hash value", buffer, ImGuiInputTextFlags_ReadOnly); + + ImGui::TextUnformatted("Result"); + ImGui::Separator(); + ImGui::InputText("##nolabel", buffer, ImGuiInputTextFlags_ReadOnly); } break; case 2: // MD4 @@ -110,11 +122,15 @@ namespace hex { static std::array result; if (this->m_shouldInvalidate) - result = md4(this->m_dataProvider, this->m_hashStart, this->m_hashEnd - this->m_hashStart + 1); + result = md4(this->m_dataProvider, this->m_hashRegion[0], this->m_hashRegion[1] - this->m_hashRegion[0] + 1); char buffer[sizeof(result) * 2 + 1]; formatBigHexInt(result, buffer, sizeof(buffer)); - ImGui::InputText("Hash value", buffer, ImGuiInputTextFlags_ReadOnly); + + ImGui::NewLine(); + ImGui::TextUnformatted("Result"); + ImGui::Separator(); + ImGui::InputText("##nolabel", buffer, ImGuiInputTextFlags_ReadOnly); } break; case 3: // MD5 @@ -122,11 +138,15 @@ namespace hex { static std::array result = { 0 }; if (this->m_shouldInvalidate) - result = md5(this->m_dataProvider, this->m_hashStart, this->m_hashEnd - this->m_hashStart + 1); + result = md5(this->m_dataProvider, this->m_hashRegion[0], this->m_hashRegion[1] - this->m_hashRegion[0] + 1); char buffer[sizeof(result) * 2 + 1]; formatBigHexInt(result, buffer, sizeof(buffer)); - ImGui::InputText("Hash value", buffer, ImGuiInputTextFlags_ReadOnly); + + ImGui::NewLine(); + ImGui::TextUnformatted("Result"); + ImGui::Separator(); + ImGui::InputText("##nolabel", buffer, ImGuiInputTextFlags_ReadOnly); } break; case 4: // SHA-1 @@ -134,11 +154,15 @@ namespace hex { static std::array result = { 0 }; if (this->m_shouldInvalidate) - result = sha1(this->m_dataProvider, this->m_hashStart, this->m_hashEnd - this->m_hashStart + 1); + result = sha1(this->m_dataProvider, this->m_hashRegion[0], this->m_hashRegion[1] - this->m_hashRegion[0] + 1); char buffer[sizeof(result) * 2 + 1]; formatBigHexInt(result, buffer, sizeof(buffer)); - ImGui::InputText("Hash value", buffer, ImGuiInputTextFlags_ReadOnly); + + ImGui::NewLine(); + ImGui::TextUnformatted("Result"); + ImGui::Separator(); + ImGui::InputText("##nolabel", buffer, ImGuiInputTextFlags_ReadOnly); } break; case 5: // SHA-224 @@ -146,11 +170,15 @@ namespace hex { static std::array result = { 0 }; if (this->m_shouldInvalidate) - result = sha224(this->m_dataProvider, this->m_hashStart, this->m_hashEnd - this->m_hashStart + 1); + result = sha224(this->m_dataProvider, this->m_hashRegion[0], this->m_hashRegion[1] - this->m_hashRegion[0] + 1); char buffer[sizeof(result) * 2 + 1]; formatBigHexInt(result, buffer, sizeof(buffer)); - ImGui::InputText("Hash value", buffer, ImGuiInputTextFlags_ReadOnly); + + ImGui::NewLine(); + ImGui::TextUnformatted("Result"); + ImGui::Separator(); + ImGui::InputText("##nolabel", buffer, ImGuiInputTextFlags_ReadOnly); } break; case 6: // SHA-256 @@ -158,11 +186,15 @@ namespace hex { static std::array result; if (this->m_shouldInvalidate) - result = sha256(this->m_dataProvider, this->m_hashStart, this->m_hashEnd - this->m_hashStart + 1); + result = sha256(this->m_dataProvider, this->m_hashRegion[0], this->m_hashRegion[1] - this->m_hashRegion[0] + 1); char buffer[sizeof(result) * 2 + 1]; formatBigHexInt(result, buffer, sizeof(buffer)); - ImGui::InputText("Hash value", buffer, ImGuiInputTextFlags_ReadOnly); + + ImGui::NewLine(); + ImGui::TextUnformatted("Result"); + ImGui::Separator(); + ImGui::InputText("##nolabel", buffer, ImGuiInputTextFlags_ReadOnly); } break; case 7: // SHA-384 @@ -170,11 +202,15 @@ namespace hex { static std::array result; if (this->m_shouldInvalidate) - result = sha384(this->m_dataProvider, this->m_hashStart, this->m_hashEnd - this->m_hashStart + 1); + result = sha384(this->m_dataProvider, this->m_hashRegion[0], this->m_hashRegion[1] - this->m_hashRegion[0] + 1); char buffer[sizeof(result) * 2 + 1]; formatBigHexInt(result, buffer, sizeof(buffer)); - ImGui::InputText("Hash value", buffer, ImGuiInputTextFlags_ReadOnly); + + ImGui::NewLine(); + ImGui::TextUnformatted("Result"); + ImGui::Separator(); + ImGui::InputText("##nolabel", buffer, ImGuiInputTextFlags_ReadOnly); } break; case 8: // SHA-512 @@ -182,11 +218,15 @@ namespace hex { static std::array result; if (this->m_shouldInvalidate) - result = sha512(this->m_dataProvider, this->m_hashStart, this->m_hashEnd - this->m_hashStart + 1); + result = sha512(this->m_dataProvider, this->m_hashRegion[0], this->m_hashRegion[1] - this->m_hashRegion[0] + 1); char buffer[sizeof(result) * 2 + 1]; formatBigHexInt(result, buffer, sizeof(buffer)); - ImGui::InputText("Hash value", buffer, ImGuiInputTextFlags_ReadOnly); + + ImGui::NewLine(); + ImGui::TextUnformatted("Result"); + ImGui::Separator(); + ImGui::InputText("##nolabel", buffer, ImGuiInputTextFlags_ReadOnly); } break; } diff --git a/source/views/view_hexeditor.cpp b/source/views/view_hexeditor.cpp index 595b65803..294914b7e 100644 --- a/source/views/view_hexeditor.cpp +++ b/source/views/view_hexeditor.cpp @@ -74,7 +74,7 @@ namespace hex { this->m_memoryEditor.GotoAddr = region.address; this->m_memoryEditor.DataPreviewAddr = region.address; this->m_memoryEditor.DataPreviewAddrEnd = region.address + region.size - 1; - View::postEvent(Events::ByteSelected, ®ion.address); + View::postEvent(Events::RegionSelected, ®ion); }); } @@ -98,8 +98,8 @@ namespace hex { if (ImGui::ArrowButton("prevPage", ImGuiDir_Left)) { this->m_dataProvider->setCurrentPage(this->m_dataProvider->getCurrentPage() - 1); - size_t dataPreviewStart = std::min(this->m_memoryEditor.DataPreviewAddr, this->m_memoryEditor.DataPreviewAddrEnd); - View::postEvent(Events::ByteSelected, &dataPreviewStart); + Region dataPreview = { std::min(this->m_memoryEditor.DataPreviewAddr, this->m_memoryEditor.DataPreviewAddrEnd), 1 }; + View::postEvent(Events::RegionSelected, &dataPreview); } ImGui::SameLine(); @@ -107,8 +107,8 @@ namespace hex { if (ImGui::ArrowButton("nextPage", ImGuiDir_Right)) { this->m_dataProvider->setCurrentPage(this->m_dataProvider->getCurrentPage() + 1); - size_t dataPreviewStart = std::min(this->m_memoryEditor.DataPreviewAddr, this->m_memoryEditor.DataPreviewAddrEnd); - View::postEvent(Events::ByteSelected, &dataPreviewStart); + Region dataPreview = { std::min(this->m_memoryEditor.DataPreviewAddr, this->m_memoryEditor.DataPreviewAddrEnd), 1 }; + View::postEvent(Events::RegionSelected, &dataPreview); } ImGui::End();