feat: Further improve process memory provider
This commit is contained in:
parent
90df4413c3
commit
d7d19d7594
@ -126,7 +126,6 @@ set(LIBIMHEX_SOURCES
|
||||
source/helpers/encoding_file.cpp
|
||||
source/helpers/logger.cpp
|
||||
source/helpers/tar.cpp
|
||||
source/helpers/types.cpp
|
||||
|
||||
source/providers/provider.cpp
|
||||
|
||||
|
@ -23,14 +23,33 @@ namespace hex {
|
||||
u64 address;
|
||||
size_t size;
|
||||
|
||||
[[nodiscard]] bool isWithin(const Region &other) const;
|
||||
[[nodiscard]] bool overlaps(const Region &other) const;
|
||||
[[nodiscard]] constexpr bool isWithin(const Region &other) const {
|
||||
if (*this == Invalid() || other == Invalid())
|
||||
return false;
|
||||
|
||||
[[nodiscard]] u64 getStartAddress() const;
|
||||
[[nodiscard]] u64 getEndAddress() const;
|
||||
[[nodiscard]] size_t getSize() const;
|
||||
if (this->getStartAddress() >= other.getStartAddress() && this->getEndAddress() <= other.getEndAddress())
|
||||
return true;
|
||||
|
||||
bool operator==(const Region &other) const;
|
||||
return false;
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr bool overlaps(const Region &other) const {
|
||||
if (*this == Invalid() || other == Invalid())
|
||||
return false;
|
||||
|
||||
if (this->getEndAddress() >= other.getStartAddress() && this->getStartAddress() <= other.getEndAddress())
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
[[nodiscard]] constexpr u64 getStartAddress() const { return this->address; }
|
||||
[[nodiscard]] constexpr u64 getEndAddress() const { return this->address + this->size - 1;}
|
||||
[[nodiscard]] constexpr size_t getSize() const { return this->size; }
|
||||
|
||||
[[nodiscard]] constexpr bool operator==(const Region &other) const {
|
||||
return this->address == other.address && this->size == other.size;
|
||||
}
|
||||
|
||||
constexpr static Region Invalid() {
|
||||
return { 0, 0 };
|
||||
|
@ -1,41 +0,0 @@
|
||||
#include <hex/helpers/types.hpp>
|
||||
|
||||
namespace hex {
|
||||
|
||||
[[nodiscard]] bool Region::isWithin(const Region &other) const {
|
||||
if (*this == Invalid() || other == Invalid())
|
||||
return false;
|
||||
|
||||
if (this->getStartAddress() >= other.getStartAddress() && this->getEndAddress() <= other.getEndAddress())
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
[[nodiscard]] bool Region::overlaps(const Region &other) const {
|
||||
if (*this == Invalid() || other == Invalid())
|
||||
return false;
|
||||
|
||||
if (this->getEndAddress() >= other.getStartAddress() && this->getStartAddress() <= other.getEndAddress())
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
[[nodiscard]] u64 Region::getStartAddress() const {
|
||||
return this->address;
|
||||
}
|
||||
|
||||
[[nodiscard]] u64 Region::getEndAddress() const {
|
||||
return this->address + this->size - 1;
|
||||
}
|
||||
|
||||
[[nodiscard]] size_t Region::getSize() const {
|
||||
return this->size;
|
||||
}
|
||||
|
||||
bool Region::operator==(const Region &other) const {
|
||||
return this->address == other.address && this->size == other.size;
|
||||
}
|
||||
|
||||
}
|
@ -197,6 +197,8 @@ namespace hex::plugin::builtin::ui {
|
||||
|
||||
std::optional<EncodingFile> m_currCustomEncoding;
|
||||
|
||||
std::pair<Region, bool> m_currValidRegion = { Region::Invalid(), false };
|
||||
|
||||
static inline std::optional<color_t> defaultColorCallback(u64, const u8 *, size_t) { return std::nullopt; }
|
||||
static inline void defaultTooltipCallback(u64, const u8 *, size_t) { }
|
||||
std::function<std::optional<color_t>(u64, const u8 *, size_t)> m_foregroundColorCallback = defaultColorCallback, m_backgroundColorCallback = defaultColorCallback;
|
||||
|
@ -379,11 +379,10 @@ namespace hex::plugin::builtin::ui {
|
||||
|
||||
if (this->m_provider != nullptr && this->m_provider->isReadable()) {
|
||||
|
||||
std::pair<Region, bool> validRegion = { Region::Invalid(), false };
|
||||
const auto isCurrRegionValid = [this, &validRegion](u64 address){
|
||||
auto &[currRegion, currRegionValid] = validRegion;
|
||||
const auto isCurrRegionValid = [this](u64 address){
|
||||
auto &[currRegion, currRegionValid] = this->m_currValidRegion;
|
||||
if (!Region{ address, 1 }.isWithin(currRegion)) {
|
||||
validRegion = this->m_provider->getRegionValidity(address);
|
||||
this->m_currValidRegion = this->m_provider->getRegionValidity(address);
|
||||
}
|
||||
|
||||
return currRegionValid;
|
||||
@ -541,7 +540,7 @@ namespace hex::plugin::builtin::ui {
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0, 0));
|
||||
ImGui::PushItemWidth(CharacterSize.x);
|
||||
if (!isCurrRegionValid(byteAddress))
|
||||
ImGui::TextFormatted("?");
|
||||
ImGui::TextDisabled("?");
|
||||
else
|
||||
this->drawCell(byteAddress, &bytes[x], 1, cellHovered, CellType::ASCII);
|
||||
ImGui::PopItemWidth();
|
||||
|
@ -64,15 +64,19 @@ namespace hex::plugin::windows {
|
||||
std::string name;
|
||||
};
|
||||
|
||||
struct Module {
|
||||
struct MemoryRegion {
|
||||
Region region;
|
||||
std::string name;
|
||||
|
||||
constexpr bool operator<(const MemoryRegion &other) const {
|
||||
return this->region.getStartAddress() < other.region.getStartAddress();
|
||||
}
|
||||
};
|
||||
|
||||
std::vector<Process> m_processes;
|
||||
std::optional<Process> m_selectedProcess;
|
||||
|
||||
std::vector<Module> m_modules;
|
||||
std::set<MemoryRegion> m_memoryRegions;
|
||||
|
||||
HANDLE m_processHandle = nullptr;
|
||||
|
||||
|
@ -5,6 +5,7 @@
|
||||
|
||||
#include <imgui.h>
|
||||
#include <hex/helpers/utils.hpp>
|
||||
#include <hex/helpers/fmt.hpp>
|
||||
|
||||
namespace hex::plugin::windows {
|
||||
|
||||
@ -35,7 +36,23 @@ namespace hex::plugin::windows {
|
||||
if (GetModuleFileNameExA(this->m_processHandle, module, moduleName, MAX_PATH) == FALSE)
|
||||
continue;
|
||||
|
||||
this->m_modules.push_back({ { (u64)moduleInfo.lpBaseOfDll, (u64)moduleInfo.lpBaseOfDll + moduleInfo.SizeOfImage }, std::fs::path(moduleName).filename().string() });
|
||||
this->m_memoryRegions.insert({ { (u64)moduleInfo.lpBaseOfDll, (u64)moduleInfo.lpBaseOfDll + moduleInfo.SizeOfImage }, std::fs::path(moduleName).filename().string() });
|
||||
}
|
||||
|
||||
MEMORY_BASIC_INFORMATION memoryInfo;
|
||||
for (u64 address = 0; address < 0xFFFF'FFFF'FFFF; address += memoryInfo.RegionSize) {
|
||||
if (VirtualQueryEx(this->m_processHandle, (LPCVOID)address, &memoryInfo, sizeof(MEMORY_BASIC_INFORMATION)) == 0)
|
||||
break;
|
||||
|
||||
std::string name;
|
||||
if (memoryInfo.State & MEM_IMAGE) continue;
|
||||
if (memoryInfo.State & MEM_FREE) continue;
|
||||
if (memoryInfo.State & MEM_COMMIT) name += "Commit ";
|
||||
if (memoryInfo.State & MEM_RESERVE) name += "Reserve ";
|
||||
if (memoryInfo.State & MEM_PRIVATE) name += "Private ";
|
||||
if (memoryInfo.State & MEM_MAPPED) name += "Mapped ";
|
||||
|
||||
this->m_memoryRegions.insert({ { (u64)memoryInfo.BaseAddress, (u64)memoryInfo.BaseAddress + memoryInfo.RegionSize }, name });
|
||||
}
|
||||
|
||||
return true;
|
||||
@ -54,9 +71,18 @@ namespace hex::plugin::windows {
|
||||
}
|
||||
|
||||
std::pair<Region, bool> ProcessMemoryProvider::getRegionValidity(u64 address) const {
|
||||
for (const auto &module : this->m_modules) {
|
||||
if (module.region.overlaps({ address, 1 }))
|
||||
return { module.region, true };
|
||||
for (const auto &memoryRegion : this->m_memoryRegions) {
|
||||
if (memoryRegion.region.overlaps({ address, 1 }))
|
||||
return { memoryRegion.region, true };
|
||||
}
|
||||
|
||||
Region lastRegion = Region::Invalid();
|
||||
for (const auto &memoryRegion : this->m_memoryRegions) {
|
||||
|
||||
if (address < memoryRegion.region.getStartAddress())
|
||||
return { Region { lastRegion.getEndAddress() + 1, memoryRegion.region.getStartAddress() - lastRegion.getEndAddress() }, false };
|
||||
|
||||
lastRegion = memoryRegion.region;
|
||||
}
|
||||
|
||||
return { Region::Invalid(), false };
|
||||
@ -127,16 +153,16 @@ namespace hex::plugin::windows {
|
||||
ImGui::TableSetupColumn("Name");
|
||||
ImGui::TableHeadersRow();
|
||||
|
||||
for (auto &module : this->m_modules) {
|
||||
ImGui::PushID(module.region.getStartAddress());
|
||||
for (auto &memoryRegion : this->m_memoryRegions) {
|
||||
ImGui::PushID(memoryRegion.region.getStartAddress());
|
||||
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("0x%016llX - 0x%016llX", module.region.getStartAddress(), module.region.getEndAddress());
|
||||
ImGui::Text("0x%016llX - 0x%016llX", memoryRegion.region.getStartAddress(), memoryRegion.region.getEndAddress());
|
||||
|
||||
ImGui::TableNextColumn();
|
||||
if (ImGui::Selectable(module.name.c_str(), false, ImGuiSelectableFlags_SpanAllColumns))
|
||||
ImHexApi::HexEditor::setSelection(module.region);
|
||||
if (ImGui::Selectable(memoryRegion.name.c_str(), false, ImGuiSelectableFlags_SpanAllColumns))
|
||||
ImHexApi::HexEditor::setSelection(memoryRegion.region);
|
||||
|
||||
ImGui::PopID();
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user