From 14adcc0e510a30375aaba755889b3b1da360ecc4 Mon Sep 17 00:00:00 2001 From: WerWolv Date: Mon, 11 Jan 2021 13:50:04 +0100 Subject: [PATCH] Added set base address function to hex editor This resolves #19 --- external/ImGui/include/imgui_memory_editor.h | 2 +- include/views/view_hexeditor.hpp | 2 ++ .../libimhex/include/providers/provider.hpp | 4 ++- .../libimhex/source/providers/provider.cpp | 8 ++++-- source/providers/file_provider.cpp | 27 +++++++++---------- source/views/view_hexeditor.cpp | 20 ++++++++++++++ 6 files changed, 45 insertions(+), 18 deletions(-) diff --git a/external/ImGui/include/imgui_memory_editor.h b/external/ImGui/include/imgui_memory_editor.h index 412ed61ad..916b6d98a 100644 --- a/external/ImGui/include/imgui_memory_editor.h +++ b/external/ImGui/include/imgui_memory_editor.h @@ -580,7 +580,7 @@ struct MemoryEditor auto selectionEnd = std::max(DataPreviewAddr, DataPreviewAddrEnd); size_t regionSize = (selectionEnd - selectionStart) + 1; - ImGui::Text(format_selection, s.AddrDigitsCount, selectionStart, s.AddrDigitsCount, selectionEnd, regionSize, regionSize == 1 ? "byte" : "bytes"); + ImGui::Text(format_selection, s.AddrDigitsCount, base_display_addr + selectionStart, s.AddrDigitsCount, base_display_addr + selectionEnd, regionSize, regionSize == 1 ? "byte" : "bytes"); } if (GotoAddr != (size_t)-1) diff --git a/include/views/view_hexeditor.hpp b/include/views/view_hexeditor.hpp index 7faf08a0e..71576cbd0 100644 --- a/include/views/view_hexeditor.hpp +++ b/include/views/view_hexeditor.hpp @@ -45,6 +45,8 @@ namespace hex { s64 m_gotoAddress = 0; + char m_baseAddressBuffer[0x20] = { 0 }; + std::vector m_dataToSave; std::string m_loaderScriptScriptPath; diff --git a/plugins/libimhex/include/providers/provider.hpp b/plugins/libimhex/include/providers/provider.hpp index 108702930..ce73c3825 100644 --- a/plugins/libimhex/include/providers/provider.hpp +++ b/plugins/libimhex/include/providers/provider.hpp @@ -36,7 +36,8 @@ namespace hex::prv { u32 getCurrentPage() const; void setCurrentPage(u32 page); - virtual size_t getBaseAddress(); + virtual void setBaseAddress(u64 address); + virtual u64 getBaseAddress(); virtual size_t getSize(); virtual std::optional getPageOfAddress(u64 address); @@ -44,6 +45,7 @@ namespace hex::prv { protected: u32 m_currPage = 0; + u64 m_baseAddress = 0; std::vector> m_patches; }; diff --git a/plugins/libimhex/source/providers/provider.cpp b/plugins/libimhex/source/providers/provider.cpp index 1b202faaf..65701e00d 100644 --- a/plugins/libimhex/source/providers/provider.cpp +++ b/plugins/libimhex/source/providers/provider.cpp @@ -46,8 +46,12 @@ namespace hex::prv { } - size_t Provider::getBaseAddress() { - return PageSize * this->m_currPage; + void Provider::setBaseAddress(u64 address) { + this->m_baseAddress = address; + } + + u64 Provider::getBaseAddress() { + return this->m_baseAddress + PageSize * this->m_currPage; } size_t Provider::getSize() { diff --git a/source/providers/file_provider.cpp b/source/providers/file_provider.cpp index 71a52b1ac..95449d48a 100644 --- a/source/providers/file_provider.cpp +++ b/source/providers/file_provider.cpp @@ -21,13 +21,12 @@ namespace hex::prv { #if defined(OS_WINDOWS) std::wstring widePath; { - int len; - int slength = (int)path.length() + 1; - len = MultiByteToWideChar(CP_UTF8, 0, path.data(), slength, 0, 0); - wchar_t* buf = new wchar_t[len]; - MultiByteToWideChar(CP_UTF8, 0, path.data(), slength, buf, len); - widePath = buf; - delete[] buf; + auto length = path.length() + 1; + auto wideLength = MultiByteToWideChar(CP_UTF8, 0, path.data(), length, 0, 0); + wchar_t* buffer = new wchar_t[wideLength]; + MultiByteToWideChar(CP_UTF8, 0, path.data(), length, buffer, wideLength); + widePath = buffer; + delete[] buffer; } LARGE_INTEGER fileSize = { 0 }; @@ -129,35 +128,35 @@ namespace hex::prv { if ((offset + size) > this->getSize() || buffer == nullptr || size == 0) return; - std::memcpy(buffer, reinterpret_cast(this->m_mappedFile) + offset, size); + std::memcpy(buffer, reinterpret_cast(this->m_mappedFile) + PageSize * this->m_currPage + offset, size); for (u64 i = 0; i < size; i++) if (this->m_patches.back().contains(offset + i)) - reinterpret_cast(buffer)[i] = this->m_patches.back()[offset + i]; + reinterpret_cast(buffer)[i] = this->m_patches.back()[offset + PageSize * this->m_currPage + i]; } void FileProvider::write(u64 offset, const void *buffer, size_t size) { - if (buffer == nullptr || size == 0) + if ((offset + size) > this->getSize() || buffer == nullptr || size == 0) return; this->m_patches.push_back(this->m_patches.back()); for (u64 i = 0; i < size; i++) - this->m_patches.back()[offset + i] = reinterpret_cast(buffer)[i]; + this->m_patches.back()[offset + this->getBaseAddress() + i] = reinterpret_cast(buffer)[i]; } void FileProvider::readRaw(u64 offset, void *buffer, size_t size) { if ((offset + size) > this->getSize() || buffer == nullptr || size == 0) return; - std::memcpy(buffer, reinterpret_cast(this->m_mappedFile) + offset, size); + std::memcpy(buffer, reinterpret_cast(this->m_mappedFile) + PageSize * this->m_currPage + offset, size); } void FileProvider::writeRaw(u64 offset, const void *buffer, size_t size) { - if (buffer == nullptr || size == 0) + if ((offset + size) > this->getSize() || buffer == nullptr || size == 0) return; - std::memcpy(reinterpret_cast(this->m_mappedFile) + offset, buffer, size); + std::memcpy(reinterpret_cast(this->m_mappedFile) + PageSize * this->m_currPage + offset, buffer, size); } size_t FileProvider::getActualSize() { return this->m_fileSize; diff --git a/source/views/view_hexeditor.cpp b/source/views/view_hexeditor.cpp index 17b714a36..5c5f145a4 100644 --- a/source/views/view_hexeditor.cpp +++ b/source/views/view_hexeditor.cpp @@ -210,6 +210,20 @@ namespace hex { } + if (ImGui::BeginPopupModal("Set base address", nullptr, ImGuiWindowFlags_AlwaysAutoResize)) { + ImGui::InputText("Address", this->m_baseAddressBuffer, 16, ImGuiInputTextFlags_CharsHexadecimal); + ImGui::NewLine(); + + if (ImGui::Button("Set")) + provider->setBaseAddress(strtoull(this->m_baseAddressBuffer, nullptr, 16)); + ImGui::SameLine(); + + if (ImGui::Button("Cancel")) + ImGui::CloseCurrentPopup(); + + ImGui::EndPopup(); + } + if (this->m_fileBrowser.showFileDialog("Open File", imgui_addons::ImGuiFileBrowser::DialogMode::OPEN)) { this->openFile(this->m_fileBrowser.selected_path); @@ -988,6 +1002,12 @@ R"( View::postEvent(Events::AddBookmark, &bookmark); } + + auto provider = *SharedData::get().currentProvider; + if (ImGui::MenuItem("Set base address", nullptr, false, provider != nullptr && provider->isReadable())) { + std::memset(this->m_baseAddressBuffer, sizeof(this->m_baseAddressBuffer), 0x00); + View::doLater([]{ ImGui::OpenPopup("Set base address"); }); + } } } \ No newline at end of file