v0.6.5 — whole-app UI/UX overhaul + IL2CPP dissector depth
A comprehensive, panel-by-panel usability pass over the entire app, on top of
IL2CPP dissector depth and a batch of Cheat-Engine-parity scanning details.
Every panel, window, dialog and settings page was audited (screenshot-verified
in both the light and dark themes via a new --pid / --panel /
--settings-page launch harness).
UI / UX overhaul (every panel audited)
- Table columns stop clipping their contents. Every list/table in the app
(pointer scanner, memory/heap/module/thread regions, find-statics, structure
dissector, code-finder, break-and-trace, register/SIMD editor, code references,
stacktrace, advanced options, settings hotkeys) used to leave its columns at
Qt's 100px default, so 16-digit hex addresses and 64/128-bit register values
were truncated. Each table now sizes its fixed columns to content and lets the
one variable column take the slack. - No more text-less or cryptic controls. Spinbox/combo dropdown arrows were
unstyled and rendered blank app-wide (now drawn); the Structure Dissector's
"Compare" field had collapsed to a bare "..." because its toolbar overflowed a
single row (now a two-row layout with the field spelled out); the Lua console
grew explicit Run and Clear buttons instead of relying on the Enter key. - Analysis tools are findable from the main window. Auto Assemble, Pointer
scan, Dissect data/structures, Find static addresses, the Mono dissector, the
Lua engine and the ELF inspector were only in the Memory Viewer's own menus;
they now also appear in the main window's Tools menu. - Decluttered layout. The Structure Dissector toolbar was split into an
address row and an actions row; the dead Windows-only D3D menu (every item
permanently disabled on Linux) was removed; the Fill Memory dialog's fields are
aligned in a form layout, and the process picker groups Open/Cancel on the right. - Colours fit both themes. The two remaining hardcoded disassembler colours
(DWARF source-line annotations and the breakpoint gutter glyph) washed out on
the light theme; both are now theme-gated. The Lua console dims echoed commands
and shows errors in red. - Code References no longer looks frozen. Analyzing a module drives a
cancelable progress dialog across its eight scan passes instead of hanging. - System theme on first launch, working scrollbars, real breakpoint toggle
(from the same pass): the app follows the desktop's light/dark preference on
first run; the memory-view scrollbars track an absolute flattened-memory model
so dragging no longer snaps back; and Toggle Breakpoint truly toggles.
IL2CPP (Unity) dissector
- Managed field type names resolved offline from the GameAssembly binary:
System.Single,UnityEngine.Vector3(VALUETYPE/CLASS), arrays (MyClass[]),
pointers, and generics spelled out (List`1<System.String>,
Dictionary`2<K, V>). Every field on real v27/v31 games resolves a name. - Base class of each type (parent chain), rendered as
Foo : Barin the
dissector; and full object layouts with inherited fields
(getIl2CppObjectLayout,cescan il2cpp --object <class>), each field tagged
with its declaring type.
Scanning
- Tri-state Writable/Executable region filters (CE's grey/checked/unchecked
boxes): must-have / must-not-have / don't-care. - "Pause target while scanning" — SIGSTOP the target for a consistent snapshot
during each scan, then resume (skips a target that's already stopped). - New Scan flow: First Scan becomes New Scan after scanning and locks the
value type; a Previous column shows the scan-time value next to the live one. - AOB / string result values fixed — they showed "?"; AOB now renders as
48 8B 05and strings as text, in both the results list and the cheat table
(which also keeps AOB/string entry types across save/load). - Enter-to-scan, type-aware value placeholders (
48 8B ?? 05for AOB), the value
box greys out for no-value compares, thousands-separated result counts, clear
status feedback when there's no process, and Save current scanresults to
txt/csv.
UI / memory viewer
- Scan panel rebuilt with real Qt layouts (was absolute pixel coordinates:
dead space, no scaling); results list expands into the reclaimed width. - Memory-view scrollbars work — the disassembly/hex panes had a dead or
missing scrollbar; both now scroll memory, and scrolling up past mapped memory
no longer strands the view ("no memory" with no way back). - Jumping to unmapped memory now says so: a Go / follow / back-forward that
lands on an unreadable address shows0x… is not readable (unmapped or protected page)in the status bar, instead of a silent pane of??. - Memory viewer gives the disassembly/hex more width by default: the register
and stack panels only show placeholders (live registers are in the Debugger
window), so they no longer take a quarter of the width, and the disassembler's
module+offset/ data-reference annotations stop truncating off the edge. - Every "Browse this memory region" opens the full memory viewer. Opening it
from a scan result, a cheat-table entry, Advanced Options, or the Memory
Regions/Heap/Module/referenced-strings windows used to give a stripped-down
viewer with no breakpoints, "add to list", Tools/Debug menus or debugger launch;
all of those now open the same fully-wired viewer as the Memory View button. - No crash when the target exits with a Memory Viewer or Structure Dissector
open. When the attached process ends (or you attach to a different one), open
Memory Viewers and Structure Dissectors are frozen and the Lua engine's process
pointer is cleared before the process handle is destroyed, so a refresh timer or
table script can't read the freed handle. - Dark-theme tree fix — tree widgets (Mono dissector, breakpoint/thread/module
lists, structure dissector) rendered class rows as unreadable white stripes;
now themed. Tool buttons, radios, and the speedhack slider themed to match. - Addresses as
module+offset(game.bin+0x1234) in the cheat table, stable
across restarts; empty-state hints on the results and cheat-table panes; the
window title shows the attached process. - Static scan results shown in green (CE's cue): a result address inside a
loaded module is pointer-stable across restarts, so it is coloured green and
hovering it reveals themodule+offsetit belongs to. - Disassembler annotates unnamed call/jmp targets with
module+offset
(e.g.jmp 0x… ; GameAssembly.so+0x1234) when no symbol exists, so stripped
game binaries are still navigable; conditional jumps stay uncluttered. - Hex view: multi-byte range selection by drag or shift+click (highlighted
in both the hex and ASCII columns), with right-click "Copy selection as AOB"
and "Copy selection (hex, no spaces)". Editing or arrow-navigating collapses
the range back to a single byte. - Scan result count no longer looks truncated: the results table shows at
most 10,000 rows for responsiveness, so when a scan finds more the "Found"
label now says e.g.Found: 2,000,000 (showing first 10,000)instead of
leaving the capped list unexplained. - Disassembler colours fixed for the light theme. The operand text, the
selected/branch-target row highlights, and the user-comment colour were
hardcoded to dark-theme values, so on the light theme operands rendered as
near-invisible pale lavender and a selected row became a dark bar. These are
now theme-aware (readable dark-slate operands and a soft selection tint on
light; unchanged on dark). - Memory viewer debug toolbar decluttered: the six near-identical Run/Step
buttons (which all just opened the separate Debugger window) collapse to a
single "Debugger" button, leaving Toggle BP / Debugger / Preferences. - Memory viewer hides the register/stack panels by default. They only
populate during a debug session (which runs in the separate Debugger window),
so they were dead-placeholders taking a quarter of the width; now the
disassembly and hex use the full width, and a persisted View toggle ("CPU
registers & stack panels") brings them back for CE's layout. - Settings dialog redesigned with a vertical category sidebar. The 15
categories used to overflow a horizontal tab bar (most tab names hidden); they
now sit in an always-visible left-hand list (horizontal text) with the page on
the right, the standard modern settings layout.--settingsopens the dialog
straight on launch. - Zebra-striped result and cheat-table rows for easier scanning of dense
address/value lists. The theme already defined the alternating colour but the
views never enabled it; enabled now, with the light stripe nudged from nearly
invisible to a soft, readable grey. - Scan panel declutters for the value type: the float-only Rounding and
Tolerance controls are now hidden (not just greyed) for integer/text scans, so
the row collapses instead of leaving dead controls under Value Type. They
reappear when you pick Float/Double (Tolerance only in "Extreme" mode). - Percentage scan fields hide until needed: the "Compare by %" value and the
"Percent max" row now appear only when "Compare by %" is ticked (and the max
only for a "between" compare), instead of sitting greyed on every scan. - The main window and Memory Viewer remember their size, position and panel
layout across runs (window geometry and every splitter are saved on close,
restored on launch), instead of always reopening at the default 760x560 /
900x600. - File > Load Recent now works. It was a permanently empty menu; it now
lists the last 10 cheat tables you opened or saved (most recent first, full
path on hover), greys out ones that have since moved, and has a "Clear list". - Paste records copied from Cheat Engine. Ctrl+V in the cheat table now
accepts CE's<CheatEntries>XML clipboard format (addresses, types, pointer
offsets, groups) in addition to our own JSON, so records copied straight from a
CE session or a shared table snippet drop in. - Table > Show Cheat Table Lua Script (Ctrl+Alt+L) now works (was a dead menu
item). View and edit the table-level Lua that runs when the table loads, run it
on demand, and it is saved back into the.CT/JSON, so you can author trainer
logic, not just import a script that already runs. - Help > Cheat Engine Help / Lua documentation now open the shipped README /
docs/SCRIPTING.mdin a rendered Markdown viewer (with an "Open on GitHub"
button), instead of being dead menu items; they fall back to the online copy
when the docs aren't installed next to the binary. - Lua Engine now follows the attached process. Attaching to a new target
re-points the shared Lua engine (and any open Lua Engine console) at it, and the
console binds the address list, sogetMemoryRecord/readIntegeretc. act on
the current process instead of a stale one (or failing when no table was loaded). - Debugger highlights changed registers (CE's cue): after each step or
breakpoint stop, the registers the instruction modified paint red (general
purpose and XMM0-15), so what an instruction touched reads at a glance. The
first stop of a session stays neutral. - One shared Debugger window. Opening it twice (the Memory Viewer's step
buttons, or Debug > Full debugger) used to spawn a second window whose
ptrace-attach then failed; now the existing one is raised instead, and it is
torn down cleanly when you attach to a different process. --pid <N>attaches to a process on launch (no picker dialog).
Scripting / RE
- Wayland global hotkeys wired into
GlobalHotkeyManager(xdg-desktop-portal). - Lua:
findReferencedStrings,findCodeCaves,findAssemblyPattern,
disassembleRange,getIl2CppObjectLayout;cescan analyzesurfaces the
static RE toolkit from the shell. Newdocs/SCRIPTING.md+examples/. cescan scangained--executable/--no-executable(and--no-writable),
exposing the tri-state region filters the GUI already has, so a shell scan can
target code vs data the same way.cescan disasmannotates a direct call/jmp target with its symbol, or its
module+offsetwhen unnamed (e.g.jmp 0x… ; sleep+0x2020), matching the GUI
disassembler; register/indirect branches stay unannotated. RIP-relative data
references also get a; -> symbol/; -> module+offsetnote for what the
effective address points at (e.g.mov rax, [0x…] ; -> libc!environ).cescan writegained--type string(raw text) and--type aob("90 90 05"
hex bytes), so you can patch code (NOP a branch) or write a string from the
shell, not just numeric values. Wildcards are rejected for an in-place byte write.cescan read --type <t>interprets the bytes instead of dumping hex: an integer
(123 (0x7b)), float/double, pointer, or a"string"(with the size argument as
its length cap). Without--typeit still hex-dumps as before.