Skip to content

Commit

Permalink
feat: Added filtering to Process Memory Provider
Browse files Browse the repository at this point in the history
  • Loading branch information
WerWolv committed Jan 5, 2023
1 parent ff9048f commit 763196f
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 16 deletions.
2 changes: 1 addition & 1 deletion lib/libimhex/include/hex/ui/imgui_imhex_extensions.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ namespace ImGui {
return this->m_textureId != nullptr;
}

[[nodiscard]] constexpr operator ImTextureID() {
[[nodiscard]] constexpr operator ImTextureID() const noexcept {
return this->m_textureId;
}

Expand Down
62 changes: 62 additions & 0 deletions lib/libimhex/include/hex/ui/widgets.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#pragma once

#include <hex.hpp>

#include <vector>
#include <string>
#include <atomic>

#include <hex/api/task.hpp>

#include <imgui.h>
#include <hex/ui/imgui_imhex_extensions.h>

namespace hex::ui {

template<typename T>
class SearchableWidget {
public:
SearchableWidget(const std::function<bool(const std::string&, const T&)> &comparator) : m_comparator(comparator) {

}

const std::vector<const T*> &draw(const auto &entries) {
if (this->m_filteredEntries.empty() && this->m_searchBuffer.empty()) {
for (auto &entry : entries)
this->m_filteredEntries.push_back(&entry);
}

if (ImGui::InputText("##search", this->m_searchBuffer)) {
this->m_pendingUpdate = true;
}

if (this->m_pendingUpdate && !this->m_updateTask.isRunning()) {
this->m_pendingUpdate = false;
this->m_filteredEntries.clear();
this->m_filteredEntries.reserve(entries.size());

this->m_updateTask = TaskManager::createBackgroundTask("Searching", [this, &entries, searchBuffer = this->m_searchBuffer](Task&) {
for (auto &entry : entries) {
if (searchBuffer.empty() || this->m_comparator(searchBuffer, entry))
this->m_filteredEntries.push_back(&entry);
}
});

}

return this->m_filteredEntries;
}

void reset() {
this->m_filteredEntries.clear();
}
private:
std::atomic<bool> m_pendingUpdate = false;
TaskHolder m_updateTask;

std::string m_searchBuffer;
std::vector<const T*> m_filteredEntries;
std::function<bool(const std::string&, const T&)> m_comparator;
};

}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

#include <imgui.h>
#include <hex/ui/imgui_imhex_extensions.h>
#include <hex/ui/widgets.hpp>

#include <array>
#include <mutex>
Expand Down Expand Up @@ -81,9 +82,15 @@ namespace hex::plugin::windows {
};

std::vector<Process> m_processes;
Process *m_selectedProcess = nullptr;
const Process *m_selectedProcess = nullptr;

std::set<MemoryRegion> m_memoryRegions;
ui::SearchableWidget<Process> m_processSearchWidget = ui::SearchableWidget<Process>([](const std::string &search, const Process &process) {
return process.name.contains(search);
});
ui::SearchableWidget<MemoryRegion> m_regionSearchWidget = ui::SearchableWidget<MemoryRegion>([](const std::string &search, const MemoryRegion &memoryRegion) {
return memoryRegion.name.contains(search);
});

HANDLE m_processHandle = nullptr;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,27 +127,30 @@ namespace hex::plugin::windows {
if (this->m_enumerationFailed) {
ImGui::TextUnformatted("hex.windows.provider.process_memory.enumeration_failed"_lang);
} else {
if (ImGui::BeginTable("##process_table", 3, ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg | ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_ScrollY, ImVec2(0, 500_scaled))) {
ImGui::PushItemWidth(350_scaled);
const auto &filtered = this->m_processSearchWidget.draw(this->m_processes);
ImGui::PopItemWidth();
if (ImGui::BeginTable("##process_table", 3, ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg | ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_ScrollY, ImVec2(350_scaled, 500_scaled))) {
ImGui::TableSetupColumn("##icon");
ImGui::TableSetupColumn("hex.windows.provider.process_memory.process_id"_lang);
ImGui::TableSetupColumn("hex.windows.provider.process_memory.process_name"_lang);
ImGui::TableSetupScrollFreeze(0, 1);

ImGui::TableHeadersRow();

for (auto &process : this->m_processes) {
ImGui::PushID(process.id);
for (auto &process : filtered) {
ImGui::PushID(process);

ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::Image(process.icon, process.icon.getSize());
ImGui::Image(process->icon, process->icon.getSize());

ImGui::TableNextColumn();
ImGui::Text("%d", process.id);
ImGui::Text("%d", process->id);

ImGui::TableNextColumn();
if (ImGui::Selectable(process.name.c_str(), this->m_selectedProcess != nullptr && process.id == this->m_selectedProcess->id, ImGuiSelectableFlags_SpanAllColumns, ImVec2(0, process.icon.getSize().y)))
this->m_selectedProcess = &process;
if (ImGui::Selectable(process->name.c_str(), this->m_selectedProcess != nullptr && process->id == this->m_selectedProcess->id, ImGuiSelectableFlags_SpanAllColumns, ImVec2(0, process->icon.getSize().y)))
this->m_selectedProcess = process;

ImGui::PopID();
}
Expand All @@ -160,28 +163,33 @@ namespace hex::plugin::windows {

void ProcessMemoryProvider::drawInterface() {
ImGui::Header("hex.windows.provider.process_memory.memory_regions"_lang, true);
if (ImGui::BeginTable("##module_table", 3, ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg | ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_ScrollY, ImVec2(0, 400_scaled))) {

auto availableX = ImGui::GetContentRegionAvail().x;
ImGui::PushItemWidth(availableX);
const auto &filtered = this->m_regionSearchWidget.draw(this->m_memoryRegions);
ImGui::PopItemWidth();
if (ImGui::BeginTable("##module_table", 3, ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg | ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_ScrollY, ImVec2(availableX, 400_scaled))) {
ImGui::TableSetupColumn("hex.builtin.common.region"_lang);
ImGui::TableSetupColumn("hex.builtin.common.size"_lang);
ImGui::TableSetupColumn("hex.builtin.common.name"_lang);
ImGui::TableSetupScrollFreeze(0, 1);

ImGui::TableHeadersRow();

for (auto &memoryRegion : this->m_memoryRegions) {
ImGui::PushID(memoryRegion.region.getStartAddress());
for (auto &memoryRegion : filtered) {
ImGui::PushID(memoryRegion->region.getStartAddress());

ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::Text("0x%016llX - 0x%016llX", memoryRegion.region.getStartAddress(), memoryRegion.region.getEndAddress());
ImGui::Text("0x%016llX - 0x%016llX", memoryRegion->region.getStartAddress(), memoryRegion->region.getEndAddress());

ImGui::TableNextColumn();
ImGui::TextUnformatted(hex::toByteString(memoryRegion.region.getSize()).c_str());
ImGui::TextUnformatted(hex::toByteString(memoryRegion->region.getSize()).c_str());


ImGui::TableNextColumn();
if (ImGui::Selectable(memoryRegion.name.c_str(), false, ImGuiSelectableFlags_SpanAllColumns))
ImHexApi::HexEditor::setSelection(memoryRegion.region);
if (ImGui::Selectable(memoryRegion->name.c_str(), false, ImGuiSelectableFlags_SpanAllColumns))
ImHexApi::HexEditor::setSelection(memoryRegion->region);

ImGui::PopID();
}
Expand Down

0 comments on commit 763196f

Please sign in to comment.