From 45b00c8b5f4ae0d61c112005ba8a9e3a8048d208 Mon Sep 17 00:00:00 2001 From: WerWolv Date: Tue, 13 Apr 2021 21:50:24 +0200 Subject: [PATCH] patterns: Make placements respect set base addresses and discard out of bounds variables --- .../include/hex/lang/pattern_data.hpp | 42 ++++++++++-------- plugins/libimhex/source/lang/evaluator.cpp | 43 +++++++++++++++---- source/views/view_information.cpp | 3 +- 3 files changed, 61 insertions(+), 27 deletions(-) diff --git a/plugins/libimhex/include/hex/lang/pattern_data.hpp b/plugins/libimhex/include/hex/lang/pattern_data.hpp index 31497f973..cc4b9f06e 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(), leftBuffer.data(), left->getSize()); - provider->read(right->getOffset(), rightBuffer.data(), right->getSize()); + provider->read(left->getOffset() - provider->getBaseAddress(), leftBuffer.data(), left->getSize()); + provider->read(right->getOffset() - provider->getBaseAddress(), rightBuffer.data(), right->getSize()); if (left->m_endian != std::endian::native) std::reverse(leftBuffer.begin(), leftBuffer.end()); @@ -238,7 +238,7 @@ namespace hex::lang { void createEntry(prv::Provider* &provider) override { u64 data = 0; - provider->read(this->getOffset(), &data, this->getSize()); + provider->read(this->getOffset() - provider->getBaseAddress(), &data, this->getSize()); data = hex::changeEndianess(data, this->getSize(), this->getEndian()); ImGui::TableNextRow(); @@ -310,7 +310,7 @@ namespace hex::lang { void createEntry(prv::Provider* &provider) override { u64 data = 0; - provider->read(this->getOffset(), &data, this->getSize()); + provider->read(this->getOffset() - provider->getBaseAddress(), &data, this->getSize()); data = hex::changeEndianess(data, this->getSize(), this->getEndian()); this->createDefaultEntry(hex::format("{:d} (0x{:0{}X})", data, data, this->getSize() * 2)); @@ -339,7 +339,7 @@ namespace hex::lang { void createEntry(prv::Provider* &provider) override { u64 data = 0; - provider->read(this->getOffset(), &data, this->getSize()); + provider->read(this->getOffset() - provider->getBaseAddress(), &data, this->getSize()); data = hex::changeEndianess(data, this->getSize(), this->getEndian()); s64 signedData = hex::signExtend(data, this->getSize(), 64); @@ -371,13 +371,13 @@ namespace hex::lang { void createEntry(prv::Provider* &provider) override { if (this->getSize() == 4) { u32 data = 0; - provider->read(this->getOffset(), &data, 4); + provider->read(this->getOffset() - provider->getBaseAddress(), &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(), &data, 8); + provider->read(this->getOffset() - provider->getBaseAddress(), &data, 8); data = hex::changeEndianess(data, 8, this->getEndian()); this->createDefaultEntry(hex::format("{:e} (0x{:0{}X})", *reinterpret_cast(&data), data, this->getSize() * 2)); @@ -404,7 +404,7 @@ namespace hex::lang { void createEntry(prv::Provider* &provider) override { u8 boolean; - provider->read(this->getOffset(), &boolean, 1); + provider->read(this->getOffset() - provider->getBaseAddress(), &boolean, 1); if (boolean == 0) this->createDefaultEntry("false"); @@ -430,7 +430,7 @@ namespace hex::lang { void createEntry(prv::Provider* &provider) override { char character; - provider->read(this->getOffset(), &character, 1); + provider->read(this->getOffset() - provider->getBaseAddress(), &character, 1); this->createDefaultEntry(hex::format("'{0}'", character)); } @@ -451,7 +451,7 @@ namespace hex::lang { void createEntry(prv::Provider* &provider) override { std::vector buffer(this->getSize() + 1, 0x00); - provider->read(this->getOffset(), buffer.data(), this->getSize()); + provider->read(this->getOffset() - provider->getBaseAddress(), buffer.data(), this->getSize()); buffer[this->getSize()] = '\0'; this->createDefaultEntry(hex::format("\"{0}\"", makeDisplayable(buffer.data(), this->getSize()).c_str())); @@ -642,11 +642,14 @@ namespace hex::lang { } void setMembers(const std::vector & members) { - this->m_members = members; - this->m_sortedMembers = members; + for (auto &member : members) { + if (member == nullptr) continue; - for (auto &member : this->m_members) + this->m_members.push_back(member); member->setParent(this); + } + + this->m_sortedMembers = this->m_members; } private: @@ -738,11 +741,14 @@ namespace hex::lang { } void setMembers(const std::vector & members) { - this->m_members = members; - this->m_sortedMembers = members; + for (auto &member : members) { + if (member == nullptr) continue; - for (auto &member : this->m_members) + this->m_members.push_back(member); member->setParent(this); + } + + this->m_sortedMembers = this->m_members; } private: @@ -762,7 +768,7 @@ namespace hex::lang { void createEntry(prv::Provider* &provider) override { u64 value = 0; - provider->read(this->getOffset(), &value, this->getSize()); + provider->read(this->getOffset() - provider->getBaseAddress(), &value, this->getSize()); value = hex::changeEndianess(value, this->getSize(), this->getEndian()); std::string valueString = PatternData::getTypeName() + "::"; @@ -834,7 +840,7 @@ namespace hex::lang { void createEntry(prv::Provider* &provider) override { std::vector value(this->getSize(), 0); - provider->read(this->getOffset(), &value[0], value.size()); + provider->read(this->getOffset() - provider->getBaseAddress(), &value[0], value.size()); if (this->m_endian == std::endian::big) std::reverse(value.begin(), value.end()); diff --git a/plugins/libimhex/source/lang/evaluator.cpp b/plugins/libimhex/source/lang/evaluator.cpp index dab01f0ef..6dca40af9 100644 --- a/plugins/libimhex/source/lang/evaluator.cpp +++ b/plugins/libimhex/source/lang/evaluator.cpp @@ -679,8 +679,13 @@ namespace hex::lang { return static_cast(value); }, valueNode->getValue()); } - if (this->m_currOffset >= this->m_provider->getActualSize()) - this->getConsole().abortEvaluation("variable placed out of range"); + + if (this->m_currOffset < this->m_provider->getBaseAddress() || this->m_currOffset >= this->m_provider->getActualSize() + this->m_provider->getBaseAddress()) { + if (node->getPlacementOffset() != nullptr) + this->getConsole().abortEvaluation("variable placed out of range"); + else + return nullptr; + } PatternData *pattern; if (auto typeDecl = dynamic_cast(node->getType()); typeDecl != nullptr) @@ -708,6 +713,13 @@ namespace hex::lang { }, valueNode->getValue()); } + if (this->m_currOffset < this->m_provider->getBaseAddress() || this->m_currOffset >= this->m_provider->getActualSize() + this->m_provider->getBaseAddress()) { + if (node->getPlacementOffset() != nullptr) + this->getConsole().abortEvaluation("variable placed out of range"); + else + return nullptr; + } + auto startOffset = this->m_currOffset; ASTNodeIntegerLiteral *valueNode; @@ -765,10 +777,13 @@ namespace hex::lang { color = entry->getColor(); entry->setColor(color.value_or(0)); + if (this->m_currOffset > this->m_provider->getActualSize() + this->m_provider->getBaseAddress()) { + delete entry; + break; + } + entries.push_back(entry); - if (this->m_currOffset > this->m_provider->getActualSize()) - this->getConsole().abortEvaluation("array exceeds size of file"); } PatternData *pattern; @@ -807,6 +822,13 @@ namespace hex::lang { pointerOffset = this->m_currOffset; } + if (this->m_currOffset < this->m_provider->getBaseAddress() || this->m_currOffset >= this->m_provider->getActualSize() + this->m_provider->getBaseAddress()) { + if (node->getPlacementOffset() != nullptr) + this->getConsole().abortEvaluation("variable placed out of range"); + else + return nullptr; + } + PatternData *sizeType; auto underlyingType = dynamic_cast(node->getSizeType()); @@ -827,7 +849,7 @@ namespace hex::lang { delete sizeType; - if (this->m_currOffset > this->m_provider->getActualSize()) + if (this->m_currOffset > this->m_provider->getActualSize() + this->m_provider->getBaseAddress()) this->getConsole().abortEvaluation("pointer points past the end of the data"); PatternData *pointedAt; @@ -877,12 +899,14 @@ namespace hex::lang { this->m_endianStack.push_back(this->m_defaultDataEndian); this->m_currRecursionDepth = 0; + PatternData *pattern = nullptr; + if (auto variableDeclNode = dynamic_cast(node); variableDeclNode != nullptr) { - this->m_globalMembers.push_back(this->evaluateVariable(variableDeclNode)); + pattern = this->evaluateVariable(variableDeclNode); } else if (auto arrayDeclNode = dynamic_cast(node); arrayDeclNode != nullptr) { - this->m_globalMembers.push_back(this->evaluateArray(arrayDeclNode)); + pattern = this->evaluateArray(arrayDeclNode); } else if (auto pointerDeclNode = dynamic_cast(node); pointerDeclNode != nullptr) { - this->m_globalMembers.push_back(this->evaluatePointer(pointerDeclNode)); + pattern = this->evaluatePointer(pointerDeclNode); } else if (auto typeDeclNode = dynamic_cast(node); typeDeclNode != nullptr) { // Handled above } else if (auto functionCallNode = dynamic_cast(node); functionCallNode != nullptr) { @@ -890,6 +914,9 @@ namespace hex::lang { delete result; } + if (pattern != nullptr) + this->m_globalMembers.push_back(pattern); + this->m_endianStack.clear(); } } catch (LogConsole::EvaluateError &e) { diff --git a/source/views/view_information.cpp b/source/views/view_information.cpp index d8cc6b437..034e79e66 100644 --- a/source/views/view_information.cpp +++ b/source/views/view_information.cpp @@ -31,7 +31,8 @@ namespace hex { }); EventManager::subscribe(this, [this](Region region) { - this->m_entropyHandlePosition = region.address / this->m_blockSize; + if (this->m_blockSize != 0) + this->m_entropyHandlePosition = region.address / this->m_blockSize; }); }