diff --git a/include/views/view_hexeditor.hpp b/include/views/view_hexeditor.hpp index 6c883d67c..631cf293b 100644 --- a/include/views/view_hexeditor.hpp +++ b/include/views/view_hexeditor.hpp @@ -25,13 +25,17 @@ namespace hex { void createView() override; void createMenu() override; + bool handleShortcut(int key, int mods) override; private: MemoryEditor m_memoryEditor; prv::Provider* &m_dataProvider; - std::vector &m_highlights; + + char m_searchBuffer[0xFFFF] = { 0 }; + s64 m_lastSearchIndex = 0; + std::vector> m_lastSearch; }; } \ No newline at end of file diff --git a/source/views/view_entropy.cpp b/source/views/view_entropy.cpp index 2cab40042..168ec52bf 100644 --- a/source/views/view_entropy.cpp +++ b/source/views/view_entropy.cpp @@ -57,6 +57,7 @@ namespace hex { if (this->m_entropy > 0.99) ImGui::TextUnformatted("This file is most likely encrypted or compressed!"); + ImGui::NewLine(); ImGui::Separator(); ImGui::NewLine(); ImGui::PlotHistogram("Byte Distribution", this->m_valueCounts, 256, 0, nullptr, FLT_MAX, FLT_MAX, ImVec2(0, 100)); diff --git a/source/views/view_hexeditor.cpp b/source/views/view_hexeditor.cpp index 53eec55af..7bc00cd64 100644 --- a/source/views/view_hexeditor.cpp +++ b/source/views/view_hexeditor.cpp @@ -3,6 +3,8 @@ #include "providers/provider.hpp" #include "providers/file_provider.hpp" +#include + namespace hex { ViewHexEditor::ViewHexEditor(prv::Provider* &dataProvider, std::vector &highlights) @@ -50,8 +52,87 @@ namespace hex { ViewHexEditor::~ViewHexEditor() {} + auto findString(prv::Provider* &provider, std::string string) { + std::vector> results; + + u32 foundCharacters = 0; + + std::vector buffer(1024, 0x00); + size_t dataSize = provider->getSize(); + for (u64 offset = 0; offset < dataSize; offset += 1024) { + size_t usedBufferSize = std::min(buffer.size(), dataSize - offset); + provider->read(offset, buffer.data(), usedBufferSize); + + for (u64 i = 0; i < usedBufferSize; i++) { + if (buffer[i] == string[foundCharacters]) + foundCharacters++; + else + foundCharacters = 0; + + if (foundCharacters == string.size()) { + results.push_back({ offset + i - foundCharacters + 1, offset + i + 1 }); + foundCharacters = 0; + } + } + } + + + + return results; + } + void ViewHexEditor::createView() { this->m_memoryEditor.DrawWindow("Hex Editor", this, (this->m_dataProvider == nullptr || !this->m_dataProvider->isReadable()) ? 0x00 : this->m_dataProvider->getSize()); + + if (ImGui::BeginPopup("Search")) { + ImGui::TextUnformatted("Search"); + ImGui::InputText("##nolabel", this->m_searchBuffer, 0xFFFF, ImGuiInputTextFlags_CallbackEdit, + [](ImGuiInputTextCallbackData* data) -> int { + auto lastSearch = static_cast>*>(data->UserData); + + lastSearch->clear(); + + return 0; + }, &this->m_lastSearch); + + + if (ImGui::Button("Find")) { + this->m_lastSearch = findString(this->m_dataProvider, this->m_searchBuffer); + this->m_lastSearchIndex = 0; + + if (this->m_lastSearch.size() > 0) + this->m_memoryEditor.GotoAddrAndHighlight(this->m_lastSearch[0].first, this->m_lastSearch[0].second); + } + + if (this->m_lastSearch.size() > 0) { + + if ((ImGui::Button("Find Next"))) { + if (this->m_lastSearch.size() > 0) { + ++this->m_lastSearchIndex %= this->m_lastSearch.size(); + this->m_memoryEditor.GotoAddrAndHighlight(this->m_lastSearch[this->m_lastSearchIndex].first, + this->m_lastSearch[this->m_lastSearchIndex].second); + } + } + + ImGui::SameLine(); + + if ((ImGui::Button("Find Prev"))) { + if (this->m_lastSearch.size() > 0) { + this->m_lastSearchIndex--; + + if (this->m_lastSearchIndex < 0) + this->m_lastSearchIndex = this->m_lastSearch.size() - 1; + + this->m_lastSearchIndex %= this->m_lastSearch.size(); + + this->m_memoryEditor.GotoAddrAndHighlight(this->m_lastSearch[this->m_lastSearchIndex].first, + this->m_lastSearch[this->m_lastSearchIndex].second); + } + } + } + + ImGui::EndPopup(); + } } void ViewHexEditor::createMenu() { @@ -76,4 +157,13 @@ namespace hex { } } + bool ViewHexEditor::handleShortcut(int key, int mods) { + if (mods & GLFW_MOD_CONTROL && key == GLFW_KEY_F) { + ImGui::OpenPopup("Search"); + return true; + } + + return false; + } + } \ No newline at end of file