feat: 32-bit process support, scanner rescan filtering, suppress flash on navigate

- Add pointerSize() to Provider base; WoW64/ELF detection in ProcessMemory,
  WinDbg, and RemoteProcessMemory plugins
- Wire pointer size through NodeTree, source/XML imports, C++ generator,
  controller, compose, address parser, and RPC protocol header
- Add is32Bit to PluginProcessInfo and ProcessInfo; show (32-bit) in picker
- Scanner rescan now filters results against the current input value
- Go-to-address from scanner resets change tracking to prevent false flashing
This commit is contained in:
IChooseYou
2026-03-01 07:42:40 -07:00
committed by IChooseYou
parent ecfac3decf
commit ed8a44917b
28 changed files with 761 additions and 98 deletions

View File

@@ -56,8 +56,13 @@ ProcessMemoryProvider::ProcessMemoryProvider(uint32_t pid, const QString& proces
m_writable = false;
}
if (m_handle)
if (m_handle) {
// Detect 32-bit (WoW64) process
BOOL isWow64 = FALSE;
if (IsWow64Process(m_handle, &isWow64) && isWow64)
m_pointerSize = 4;
cacheModules();
}
}
bool ProcessMemoryProvider::read(uint64_t addr, void* buf, int len) const
@@ -192,9 +197,20 @@ ProcessMemoryProvider::ProcessMemoryProvider(uint32_t pid, const QString& proces
m_writable = false;
}
if (m_fd >= 0)
if (m_fd >= 0) {
// Detect 32-bit ELF process
QString exePath = QStringLiteral("/proc/%1/exe").arg(pid);
QByteArray exePathUtf8 = exePath.toUtf8();
int exeFd = ::open(exePathUtf8.constData(), O_RDONLY);
if (exeFd >= 0) {
unsigned char elfClass = 0;
// ELF e_ident[EI_CLASS] is at offset 4
if (::pread(exeFd, &elfClass, 1, 4) == 1 && elfClass == 1) // ELFCLASS32
m_pointerSize = 4;
::close(exeFd);
}
cacheModules();
}
}
bool ProcessMemoryProvider::read(uint64_t addr, void* buf, int len) const
@@ -525,6 +541,7 @@ bool ProcessMemoryPlugin::selectTarget(QWidget* parent, QString* target)
info.name = pinfo.name;
info.path = pinfo.path;
info.icon = pinfo.icon;
info.is32Bit = pinfo.is32Bit;
processes.append(info);
}
@@ -586,6 +603,11 @@ QVector<PluginProcessInfo> ProcessMemoryPlugin::enumerateProcesses()
}
}
// Detect 32-bit (WoW64) process
BOOL isWow64 = FALSE;
if (IsWow64Process(hProcess, &isWow64) && isWow64)
info.is32Bit = true;
CloseHandle(hProcess);
}
@@ -632,6 +654,16 @@ QVector<PluginProcessInfo> ProcessMemoryPlugin::enumerateProcesses()
info.name = procName;
info.path = resolvedPath;
info.icon = defaultIcon;
// Detect 32-bit ELF process
int exeFd = ::open(exePath.toUtf8().constData(), O_RDONLY);
if (exeFd >= 0) {
unsigned char elfClass = 0;
if (::pread(exeFd, &elfClass, 1, 4) == 1 && elfClass == 1) // ELFCLASS32
info.is32Bit = true;
::close(exeFd);
}
processes.append(info);
}
#endif

View File

@@ -28,6 +28,7 @@ public:
bool isLive() const override { return true; }
uint64_t base() const override { return m_base; }
int pointerSize() const override { return m_pointerSize; }
QVector<rcx::MemoryRegion> enumerateRegions() const override;
bool isReadable(uint64_t, int len) const override {
#ifdef _WIN32
@@ -54,6 +55,7 @@ private:
QString m_processName;
bool m_writable;
uint64_t m_base;
int m_pointerSize = 8;
struct ModuleInfo {
QString name;