diff --git a/external/ImGui/include/imgui_memory_editor.h b/external/ImGui/include/imgui_memory_editor.h index 0b71ab248..b0108f84d 100644 --- a/external/ImGui/include/imgui_memory_editor.h +++ b/external/ImGui/include/imgui_memory_editor.h @@ -156,6 +156,13 @@ struct MemoryEditor HighlightMax = addr_max; } + void GotoAddrAndSelect(size_t addr_min, size_t addr_max) + { + GotoAddr = addr_min; + DataPreviewAddr = addr_min; + DataPreviewAddrEnd = addr_max; + } + struct Sizes { int AddrDigitsCount; @@ -222,7 +229,7 @@ struct MemoryEditor if (ImGui::Begin(title, p_open, ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoNavInputs)) { if (DataPreviewAddr != DataPreviewAddrOld || DataPreviewAddrEnd != DataPreviewAddrEndOld) { - hex::Region selectionRegion = { std::min(DataPreviewAddr, DataPreviewAddrEnd), std::max(DataPreviewAddr, DataPreviewAddrEnd) - std::min(DataPreviewAddr, DataPreviewAddrEnd) }; + hex::Region selectionRegion = { std::min(DataPreviewAddr, DataPreviewAddrEnd) + base_display_addr, std::max(DataPreviewAddr, DataPreviewAddrEnd) - std::min(DataPreviewAddr, DataPreviewAddrEnd) }; hex::EventManager::post(selectionRegion); } diff --git a/plugins/libimhex/include/hex/lang/pattern_data.hpp b/plugins/libimhex/include/hex/lang/pattern_data.hpp index b534a6ec4..adbc1ed9b 100644 --- a/plugins/libimhex/include/hex/lang/pattern_data.hpp +++ b/plugins/libimhex/include/hex/lang/pattern_data.hpp @@ -123,8 +123,8 @@ namespace hex::lang { size_t biggerSize = std::max(left->getSize(), right->getSize()); std::vector leftBuffer(biggerSize, 0x00), rightBuffer(biggerSize, 0x00); - provider->read(left->getOffset() - provider->getBaseAddress(), leftBuffer.data(), left->getSize()); - provider->read(right->getOffset() - provider->getBaseAddress(), rightBuffer.data(), right->getSize()); + provider->read(left->getOffset(), leftBuffer.data(), left->getSize()); + provider->read(right->getOffset(), rightBuffer.data(), right->getSize()); if (left->m_endian != std::endian::native) std::reverse(leftBuffer.begin(), leftBuffer.end()); @@ -237,7 +237,7 @@ namespace hex::lang { void createEntry(prv::Provider* &provider) override { u64 data = 0; - provider->read(this->getOffset() - provider->getBaseAddress(), &data, this->getSize()); + provider->read(this->getOffset(), &data, this->getSize()); data = hex::changeEndianess(data, this->getSize(), this->getEndian()); ImGui::TableNextRow(); @@ -319,7 +319,7 @@ namespace hex::lang { void createEntry(prv::Provider* &provider) override { u64 data = 0; - provider->read(this->getOffset() - provider->getBaseAddress(), &data, this->getSize()); + provider->read(this->getOffset(), &data, this->getSize()); data = hex::changeEndianess(data, this->getSize(), this->getEndian()); this->createDefaultEntry(hex::format("{:d} (0x{:0{}X})", data, data, this->getSize() * 2)); @@ -348,7 +348,7 @@ namespace hex::lang { void createEntry(prv::Provider* &provider) override { u128 data = 0; - provider->read(this->getOffset() - provider->getBaseAddress(), &data, this->getSize()); + provider->read(this->getOffset(), &data, this->getSize()); data = hex::changeEndianess(data, this->getSize(), this->getEndian()); switch (this->getSize()) { @@ -409,13 +409,13 @@ namespace hex::lang { void createEntry(prv::Provider* &provider) override { if (this->getSize() == 4) { u32 data = 0; - provider->read(this->getOffset() - provider->getBaseAddress(), &data, 4); + provider->read(this->getOffset(), &data, 4); data = hex::changeEndianess(data, 4, this->getEndian()); this->createDefaultEntry(hex::format("{:e} (0x{:0{}X})", *reinterpret_cast(&data), data, this->getSize() * 2)); } else if (this->getSize() == 8) { u64 data = 0; - provider->read(this->getOffset() - provider->getBaseAddress(), &data, 8); + provider->read(this->getOffset(), &data, 8); data = hex::changeEndianess(data, 8, this->getEndian()); this->createDefaultEntry(hex::format("{:e} (0x{:0{}X})", *reinterpret_cast(&data), data, this->getSize() * 2)); @@ -442,7 +442,7 @@ namespace hex::lang { void createEntry(prv::Provider* &provider) override { u8 boolean; - provider->read(this->getOffset() - provider->getBaseAddress(), &boolean, 1); + provider->read(this->getOffset(), &boolean, 1); if (boolean == 0) this->createDefaultEntry("false"); @@ -468,7 +468,7 @@ namespace hex::lang { void createEntry(prv::Provider* &provider) override { char character; - provider->read(this->getOffset() - provider->getBaseAddress(), &character, 1); + provider->read(this->getOffset(), &character, 1); this->createDefaultEntry(hex::format("'{0}'", character)); } @@ -489,7 +489,7 @@ namespace hex::lang { void createEntry(prv::Provider* &provider) override { std::vector buffer(this->getSize() + 1, 0x00); - provider->read(this->getOffset() - provider->getBaseAddress(), buffer.data(), this->getSize()); + provider->read(this->getOffset(), buffer.data(), this->getSize()); buffer[this->getSize()] = '\0'; this->createDefaultEntry(hex::format("\"{0}\"", makeDisplayable(buffer.data(), this->getSize()).c_str())); @@ -808,7 +808,7 @@ namespace hex::lang { void createEntry(prv::Provider* &provider) override { u64 value = 0; - provider->read(this->getOffset() - provider->getBaseAddress(), &value, this->getSize()); + provider->read(this->getOffset(), &value, this->getSize()); value = hex::changeEndianess(value, this->getSize(), this->getEndian()); std::string valueString = PatternData::getTypeName() + "::"; @@ -880,7 +880,7 @@ namespace hex::lang { void createEntry(prv::Provider* &provider) override { std::vector value(this->getSize(), 0); - provider->read(this->getOffset() - provider->getBaseAddress(), &value[0], value.size()); + provider->read(this->getOffset(), &value[0], value.size()); if (this->m_endian == std::endian::big) std::reverse(value.begin(), value.end()); diff --git a/plugins/libimhex/include/hex/providers/provider.hpp b/plugins/libimhex/include/hex/providers/provider.hpp index 9df85fe74..72ddf05ee 100644 --- a/plugins/libimhex/include/hex/providers/provider.hpp +++ b/plugins/libimhex/include/hex/providers/provider.hpp @@ -24,7 +24,9 @@ namespace hex::prv { virtual bool isWritable() = 0; virtual void read(u64 offset, void *buffer, size_t size, bool overlays = true); + virtual void readRelative(u64 offset, void *buffer, size_t size, bool overlays = true); virtual void write(u64 offset, const void *buffer, size_t size); + virtual void writeRelative(u64 offset, const void *buffer, size_t size); virtual void readRaw(u64 offset, void *buffer, size_t size) = 0; virtual void writeRaw(u64 offset, const void *buffer, size_t size) = 0; diff --git a/plugins/libimhex/source/lang/evaluator.cpp b/plugins/libimhex/source/lang/evaluator.cpp index 483b37ba5..6dca40af9 100644 --- a/plugins/libimhex/source/lang/evaluator.cpp +++ b/plugins/libimhex/source/lang/evaluator.cpp @@ -843,7 +843,7 @@ namespace hex::lang { size_t pointerSize = sizeType->getSize(); u128 pointedAtOffset = 0; - this->m_provider->read(pointerOffset - this->m_provider->getBaseAddress(), &pointedAtOffset, pointerSize); + this->m_provider->read(pointerOffset, &pointedAtOffset, pointerSize); this->m_currOffset = hex::changeEndianess(pointedAtOffset, pointerSize, underlyingType->getEndian().value_or(this->m_defaultDataEndian)); delete sizeType; diff --git a/plugins/libimhex/source/providers/provider.cpp b/plugins/libimhex/source/providers/provider.cpp index ae0706bd8..7f75d88bd 100644 --- a/plugins/libimhex/source/providers/provider.cpp +++ b/plugins/libimhex/source/providers/provider.cpp @@ -22,10 +22,18 @@ namespace hex::prv { this->readRaw(offset, buffer, size); } + void Provider::readRelative(u64 offset, void *buffer, size_t size, bool overlays) { + this->read(offset + this->getBaseAddress(), buffer, size); + } + void Provider::write(u64 offset, const void *buffer, size_t size) { this->writeRaw(offset, buffer, size); } + void Provider::writeRelative(u64 offset, const void *buffer, size_t size) { + this->write(offset + this->getBaseAddress(), buffer, size); + } + void Provider::applyOverlays(u64 offset, void *buffer, size_t size) { for (auto &overlay : this->m_overlays) { auto overlayOffset = overlay->getAddress(); @@ -90,7 +98,7 @@ namespace hex::prv { } std::optional Provider::getPageOfAddress(u64 address) { - u32 page = std::floor(address / double(PageSize)); + u32 page = std::floor((address - this->getBaseAddress()) / double(PageSize)); if (page >= this->getPageCount()) return { }; @@ -107,7 +115,7 @@ namespace hex::prv { this->m_patches.push_back(getPatches()); for (u64 i = 0; i < size; i++) - getPatches()[offset + this->getBaseAddress() + i] = reinterpret_cast(buffer)[i]; + getPatches()[offset + i] = reinterpret_cast(buffer)[i]; } void Provider::undo() { diff --git a/source/providers/file_provider.cpp b/source/providers/file_provider.cpp index dbf73c5bb..462687a31 100644 --- a/source/providers/file_provider.cpp +++ b/source/providers/file_provider.cpp @@ -126,10 +126,11 @@ namespace hex::prv { void FileProvider::read(u64 offset, void *buffer, size_t size, bool overlays) { - if ((offset + size) > this->getSize() || buffer == nullptr || size == 0) + + if (((offset - this->getBaseAddress()) + size) > this->getSize() || buffer == nullptr || size == 0) return; - std::memcpy(buffer, reinterpret_cast(this->m_mappedFile) + PageSize * this->m_currPage + offset, size); + std::memcpy(buffer, reinterpret_cast(this->m_mappedFile) + PageSize * this->m_currPage + offset - this->getBaseAddress(), size); for (u64 i = 0; i < size; i++) if (getPatches().contains(offset + i)) @@ -140,13 +141,15 @@ namespace hex::prv { } void FileProvider::write(u64 offset, const void *buffer, size_t size) { - if ((offset + size) > this->getSize() || buffer == nullptr || size == 0) + if (((offset - this->getBaseAddress()) + size) > this->getSize() || buffer == nullptr || size == 0) return; addPatch(offset, buffer, size); } void FileProvider::readRaw(u64 offset, void *buffer, size_t size) { + offset -= this->getBaseAddress(); + if ((offset + size) > this->getSize() || buffer == nullptr || size == 0) return; @@ -154,6 +157,8 @@ namespace hex::prv { } void FileProvider::writeRaw(u64 offset, const void *buffer, size_t size) { + offset -= this->getBaseAddress(); + if ((offset + size) > this->getSize() || buffer == nullptr || size == 0) return; diff --git a/source/views/view_bookmarks.cpp b/source/views/view_bookmarks.cpp index f6790202b..060b76bdf 100644 --- a/source/views/view_bookmarks.cpp +++ b/source/views/view_bookmarks.cpp @@ -75,7 +75,7 @@ namespace hex { { u8 bytes[10] = { 0 }; - (SharedData::currentProvider)->read(region.address, bytes, std::min(region.size, size_t(10))); + SharedData::currentProvider->read(region.address, bytes, std::min(region.size, size_t(10))); std::string bytesString; for (u8 i = 0; i < std::min(region.size, size_t(10)); i++) { diff --git a/source/views/view_hashes.cpp b/source/views/view_hashes.cpp index 4f40e287c..28d068e31 100644 --- a/source/views/view_hashes.cpp +++ b/source/views/view_hashes.cpp @@ -59,8 +59,8 @@ namespace hex { this->m_shouldInvalidate = true; size_t dataSize = provider->getSize(); - if (this->m_hashRegion[1] >= dataSize) - this->m_hashRegion[1] = dataSize - 1; + if (this->m_hashRegion[1] >= provider->getBaseAddress() + dataSize) + this->m_hashRegion[1] = provider->getBaseAddress() + dataSize - 1; if (this->m_hashRegion[1] >= this->m_hashRegion[0]) { diff --git a/source/views/view_hexeditor.cpp b/source/views/view_hexeditor.cpp index 6f66acb16..9b83516e1 100644 --- a/source/views/view_hexeditor.cpp +++ b/source/views/view_hexeditor.cpp @@ -30,7 +30,7 @@ namespace hex { return 0x00; ImU8 byte; - provider->read(off, &byte, sizeof(ImU8)); + provider->readRelative(off, &byte, sizeof(ImU8)); return byte; }; @@ -40,7 +40,7 @@ namespace hex { if (!provider->isAvailable() || !provider->isWritable()) return; - provider->write(off, &d, sizeof(ImU8)); + provider->writeRelative(off, &d, sizeof(ImU8)); EventManager::post(); ProjectFile::markDirty(); }; @@ -114,7 +114,7 @@ namespace hex { size_t size = std::min(_this->m_currEncodingFile.getLongestSequence(), provider->getActualSize() - addr); std::vector buffer(size); - provider->read(addr, buffer.data(), size); + provider->readRelative(addr, buffer.data(), size); auto [decoded, advance] = _this->m_currEncodingFile.getEncodingFor(buffer); @@ -135,13 +135,16 @@ namespace hex { EventManager::subscribe(this, [this](Region region) { auto provider = SharedData::currentProvider; - auto page = provider->getPageOfAddress(region.address - provider->getBaseAddress()); + auto page = provider->getPageOfAddress(region.address); + if (!page.has_value()) return; + if (region.size == 0) + return; provider->setCurrentPage(page.value()); - u64 start = region.address - provider->getBaseAddress(); - this->m_memoryEditor.GotoAddrAndHighlight(start, start + region.size - 1); + u64 start = region.address; + this->m_memoryEditor.GotoAddrAndSelect(start - provider->getBaseAddress(), start + region.size - provider->getBaseAddress() - 1); EventManager::post(region); }); @@ -266,7 +269,7 @@ namespace hex { if (bufferSize > provider->getActualSize() - offset) bufferSize = provider->getActualSize() - offset; - provider->read(offset, buffer.data(), bufferSize); + provider->readRelative(offset, buffer.data(), bufferSize); fwrite(buffer.data(), 1, bufferSize, file); } @@ -650,7 +653,7 @@ namespace hex { size_t copySize = (end - start) + 1; std::vector buffer(copySize, 0x00); - provider->read(start, buffer.data(), buffer.size()); + provider->readRelative(start, buffer.data(), buffer.size()); std::string str; for (const auto &byte : buffer) @@ -699,7 +702,7 @@ namespace hex { } // Write bytes - provider->write(start - provider->getBaseAddress(), buffer.data(), std::min(end - start + 1, buffer.size())); + provider->writeRelative(start, buffer.data(), std::min(end - start + 1, buffer.size())); } void ViewHexEditor::copyString() { @@ -712,7 +715,7 @@ namespace hex { std::string buffer(copySize, 0x00); buffer.reserve(copySize + 1); - provider->read(start, buffer.data(), copySize); + provider->readRelative(start, buffer.data(), copySize); ImGui::SetClipboardText(buffer.c_str()); } @@ -726,7 +729,7 @@ namespace hex { size_t copySize = (end - start) + 1; std::vector buffer(copySize, 0x00); - provider->read(start, buffer.data(), buffer.size()); + provider->readRelative(start, buffer.data(), buffer.size()); std::string str; switch (language) { @@ -828,7 +831,7 @@ namespace hex { size_t copySize = (end - start) + 1; std::vector buffer(copySize, 0x00); - provider->read(start, buffer.data(), buffer.size()); + provider->readRelative(start, buffer.data(), buffer.size()); std::string str = "Hex View 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F\n\n"; @@ -875,7 +878,7 @@ namespace hex { size_t copySize = (end - start) + 1; std::vector buffer(copySize, 0x00); - provider->read(start, buffer.data(), buffer.size()); + provider->readRelative(start, buffer.data(), buffer.size()); std::string str = R"( @@ -940,7 +943,7 @@ R"( size_t dataSize = provider->getSize(); for (u64 offset = 0; offset < dataSize; offset += 1024) { size_t usedBufferSize = std::min(u64(buffer.size()), dataSize - offset); - provider->read(offset, buffer.data(), usedBufferSize); + provider->readRelative(offset, buffer.data(), usedBufferSize); for (u64 i = 0; i < usedBufferSize; i++) { if (buffer[i] == string[foundCharacters]) @@ -978,7 +981,7 @@ R"( size_t dataSize = provider->getSize(); for (u64 offset = 0; offset < dataSize; offset += 1024) { size_t usedBufferSize = std::min(u64(buffer.size()), dataSize - offset); - provider->read(offset, buffer.data(), usedBufferSize); + provider->readRelative(offset, buffer.data(), usedBufferSize); for (u64 i = 0; i < usedBufferSize; i++) { if (buffer[i] == hex[foundCharacters]) @@ -1006,7 +1009,7 @@ R"( _this->m_lastSearchIndex = 0; if (_this->m_lastSearchBuffer->size() > 0) - _this->m_memoryEditor.GotoAddrAndHighlight((*_this->m_lastSearchBuffer)[0].first, (*_this->m_lastSearchBuffer)[0].second); + _this->m_memoryEditor.GotoAddrAndSelect((*_this->m_lastSearchBuffer)[0].first, (*_this->m_lastSearchBuffer)[0].second); return 0; }; @@ -1018,13 +1021,13 @@ R"( this->m_lastSearchIndex = 0; if (this->m_lastSearchBuffer->size() > 0) - this->m_memoryEditor.GotoAddrAndHighlight((*this->m_lastSearchBuffer)[0].first, (*this->m_lastSearchBuffer)[0].second); + this->m_memoryEditor.GotoAddrAndSelect((*this->m_lastSearchBuffer)[0].first, (*this->m_lastSearchBuffer)[0].second); }; static auto FindNext = [this]() { if (this->m_lastSearchBuffer->size() > 0) { ++this->m_lastSearchIndex %= this->m_lastSearchBuffer->size(); - this->m_memoryEditor.GotoAddrAndHighlight((*this->m_lastSearchBuffer)[this->m_lastSearchIndex].first, + this->m_memoryEditor.GotoAddrAndSelect((*this->m_lastSearchBuffer)[this->m_lastSearchIndex].first, (*this->m_lastSearchBuffer)[this->m_lastSearchIndex].second); } }; @@ -1038,7 +1041,7 @@ R"( this->m_lastSearchIndex %= this->m_lastSearchBuffer->size(); - this->m_memoryEditor.GotoAddrAndHighlight((*this->m_lastSearchBuffer)[this->m_lastSearchIndex].first, + this->m_memoryEditor.GotoAddrAndSelect((*this->m_lastSearchBuffer)[this->m_lastSearchIndex].first, (*this->m_lastSearchBuffer)[this->m_lastSearchIndex].second); } }; diff --git a/source/views/view_information.cpp b/source/views/view_information.cpp index 034e79e66..0d7cf533f 100644 --- a/source/views/view_information.cpp +++ b/source/views/view_information.cpp @@ -76,7 +76,7 @@ namespace hex { for (u64 i = 0; i < provider->getSize(); i += this->m_blockSize) { std::array blockValueCounts = { 0 }; - provider->read(i, buffer.data(), std::min(u64(this->m_blockSize), provider->getSize() - i)); + provider->readRelative(i, buffer.data(), std::min(u64(this->m_blockSize), provider->getSize() - i)); for (size_t j = 0; j < this->m_blockSize; j++) { blockValueCounts[buffer[j]]++; @@ -91,7 +91,7 @@ namespace hex { { std::vector buffer(provider->getSize(), 0x00); - provider->read(0x00, buffer.data(), buffer.size()); + provider->readRelative(0x00, buffer.data(), buffer.size()); this->m_fileDescription.clear(); this->m_mimeType.clear(); @@ -216,7 +216,7 @@ namespace hex { ImPlot::PlotLine("##entropy_line", this->m_blockEntropy.data(), this->m_blockEntropy.size()); if (ImPlot::DragLineX("Position", &this->m_entropyHandlePosition, false)) { - EventManager::post( Region{ u64(this->m_entropyHandlePosition * this->m_blockSize), 1 }); + EventManager::post( Region{ u64(this->m_entropyHandlePosition * this->m_blockSize) + provider->getBaseAddress(), 1 }); } ImPlot::EndPlot(); diff --git a/source/views/view_pattern.cpp b/source/views/view_pattern.cpp index 26a1bd55c..3dca99d42 100644 --- a/source/views/view_pattern.cpp +++ b/source/views/view_pattern.cpp @@ -123,7 +123,7 @@ namespace hex { return; std::vector buffer(std::min(provider->getSize(), size_t(0xFFFF)), 0x00); - provider->read(0, buffer.data(), buffer.size()); + provider->readRelative(0, buffer.data(), buffer.size()); std::string mimeType; diff --git a/source/views/view_strings.cpp b/source/views/view_strings.cpp index d059bec4a..c00aaa7ab 100644 --- a/source/views/view_strings.cpp +++ b/source/views/view_strings.cpp @@ -57,7 +57,7 @@ namespace hex { for (u64 offset = 0; offset < provider->getSize(); offset += buffer.size()) { size_t readSize = std::min(u64(buffer.size()), provider->getSize() - offset); - provider->read(offset, buffer.data(), readSize); + provider->readRelative(offset, buffer.data(), readSize); for (u32 i = 0; i < readSize; i++) { if (buffer[i] >= 0x20 && buffer[i] <= 0x7E) @@ -66,7 +66,7 @@ namespace hex { if (foundCharacters >= this->m_minimumLength) { FoundString foundString; - foundString.offset = offset + i - foundCharacters; + foundString.offset = offset + i - foundCharacters + provider->getBaseAddress(); foundString.size = foundCharacters; foundString.string.reserve(foundCharacters); foundString.string.resize(foundCharacters); @@ -88,7 +88,6 @@ namespace hex { void ViewStrings::drawContent() { auto provider = SharedData::currentProvider; - if (ImGui::Begin(View::toWindowName("hex.view.strings.name").c_str(), &this->getWindowOpenState(), ImGuiWindowFlags_NoCollapse)) { if (provider != nullptr && provider->isReadable()) { ImGui::Disabled([this]{ diff --git a/source/views/view_yara.cpp b/source/views/view_yara.cpp index 3421c2e63..8278abc4f 100644 --- a/source/views/view_yara.cpp +++ b/source/views/view_yara.cpp @@ -172,7 +172,7 @@ namespace hex { if (context.buffer.empty()) return nullptr; - provider->read(context.currBlock.base, context.buffer.data(), context.buffer.size()); + provider->readRelative(context.currBlock.base, context.buffer.data(), context.buffer.size()); return context.buffer.data(); };