mirror of
https://github.com/NohamR/Reclass.git
synced 2026-05-10 19:59:21 +00:00
fix: rescan performance overhaul, background thread, WinDbg regions
Move rescan to background thread via ScanEngine::startRescan() to prevent UI freeze. Fix populateTable bottleneck caused by QHeaderView::ResizeToContents iterating all rows (6s -> 0ms for 512 results). Add chunked batch reads (256KB spans), enumerateRegions() for WinDbg/ProcessMemory providers, cancel support, and diagnostic logging throughout the scanner pipeline.
This commit is contained in:
@@ -124,6 +124,51 @@ void ProcessMemoryProvider::cacheModules()
|
||||
}
|
||||
}
|
||||
|
||||
QVector<rcx::MemoryRegion> ProcessMemoryProvider::enumerateRegions() const
|
||||
{
|
||||
QVector<rcx::MemoryRegion> regions;
|
||||
if (!m_handle) return regions;
|
||||
|
||||
MEMORY_BASIC_INFORMATION mbi;
|
||||
uint64_t addr = 0;
|
||||
|
||||
while (VirtualQueryEx(m_handle, (LPCVOID)addr, &mbi, sizeof(mbi)) == sizeof(mbi)) {
|
||||
if (mbi.State == MEM_COMMIT &&
|
||||
!(mbi.Protect & PAGE_NOACCESS) &&
|
||||
!(mbi.Protect & PAGE_GUARD))
|
||||
{
|
||||
rcx::MemoryRegion region;
|
||||
region.base = (uint64_t)mbi.BaseAddress;
|
||||
region.size = mbi.RegionSize;
|
||||
region.readable = true;
|
||||
region.writable = (mbi.Protect & PAGE_READWRITE) ||
|
||||
(mbi.Protect & PAGE_WRITECOPY) ||
|
||||
(mbi.Protect & PAGE_EXECUTE_READWRITE) ||
|
||||
(mbi.Protect & PAGE_EXECUTE_WRITECOPY);
|
||||
region.executable = (mbi.Protect & PAGE_EXECUTE) ||
|
||||
(mbi.Protect & PAGE_EXECUTE_READ) ||
|
||||
(mbi.Protect & PAGE_EXECUTE_READWRITE) ||
|
||||
(mbi.Protect & PAGE_EXECUTE_WRITECOPY);
|
||||
|
||||
// Match module name from cached module list
|
||||
for (const auto& mod : m_modules) {
|
||||
if (region.base >= mod.base && region.base < mod.base + mod.size) {
|
||||
region.moduleName = mod.name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
regions.append(region);
|
||||
}
|
||||
|
||||
uint64_t next = (uint64_t)mbi.BaseAddress + mbi.RegionSize;
|
||||
if (next <= addr) break; // overflow protection
|
||||
addr = next;
|
||||
}
|
||||
|
||||
return regions;
|
||||
}
|
||||
|
||||
#elif defined(__linux__)
|
||||
|
||||
ProcessMemoryProvider::ProcessMemoryProvider(uint32_t pid, const QString& processName)
|
||||
@@ -282,6 +327,58 @@ void ProcessMemoryProvider::cacheModules()
|
||||
}
|
||||
}
|
||||
|
||||
QVector<rcx::MemoryRegion> ProcessMemoryProvider::enumerateRegions() const
|
||||
{
|
||||
QVector<rcx::MemoryRegion> regions;
|
||||
if (m_fd < 0) return regions;
|
||||
|
||||
QString mapsPath = QStringLiteral("/proc/%1/maps").arg(m_pid);
|
||||
std::ifstream mapsFile(mapsPath.toStdString());
|
||||
if (!mapsFile.is_open()) return regions;
|
||||
|
||||
std::string line;
|
||||
while (std::getline(mapsFile, line)) {
|
||||
std::istringstream iss(line);
|
||||
std::string addrRange, perms, offset, dev, inode, pathname;
|
||||
iss >> addrRange >> perms >> offset >> dev >> inode;
|
||||
std::getline(iss, pathname);
|
||||
|
||||
auto dash = addrRange.find('-');
|
||||
if (dash == std::string::npos) continue;
|
||||
uint64_t addrStart = std::stoull(addrRange.substr(0, dash), nullptr, 16);
|
||||
uint64_t addrEnd = std::stoull(addrRange.substr(dash + 1), nullptr, 16);
|
||||
|
||||
if (perms.size() < 4) continue;
|
||||
bool readable = (perms[0] == 'r');
|
||||
bool writable = (perms[1] == 'w');
|
||||
bool executable = (perms[2] == 'x');
|
||||
|
||||
if (!readable) continue;
|
||||
|
||||
rcx::MemoryRegion region;
|
||||
region.base = addrStart;
|
||||
region.size = addrEnd - addrStart;
|
||||
region.readable = readable;
|
||||
region.writable = writable;
|
||||
region.executable = executable;
|
||||
|
||||
// Extract module name from pathname
|
||||
size_t start = pathname.find_first_not_of(" \t");
|
||||
if (start != std::string::npos) {
|
||||
QString qpath = QString::fromStdString(pathname.substr(start));
|
||||
if (qpath.startsWith('/') && !qpath.startsWith("/dev/") &&
|
||||
!qpath.startsWith("/memfd:")) {
|
||||
QFileInfo fi(qpath);
|
||||
region.moduleName = fi.fileName();
|
||||
}
|
||||
}
|
||||
|
||||
regions.append(region);
|
||||
}
|
||||
|
||||
return regions;
|
||||
}
|
||||
|
||||
#endif // platform
|
||||
|
||||
uint64_t ProcessMemoryProvider::symbolToAddress(const QString& name) const
|
||||
|
||||
@@ -28,6 +28,7 @@ public:
|
||||
|
||||
bool isLive() const override { return true; }
|
||||
uint64_t base() const override { return m_base; }
|
||||
QVector<rcx::MemoryRegion> enumerateRegions() const override;
|
||||
bool isReadable(uint64_t, int len) const override {
|
||||
#ifdef _WIN32
|
||||
return m_handle && len >= 0;
|
||||
|
||||
Reference in New Issue
Block a user