Skip to content

v0.6.5 — whole-app UI/UX overhaul + IL2CPP dissector depth

Choose a tag to compare

@wleeaf wleeaf released this 18 Jul 00:29
· 211 commits to main since this release

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 : Bar in 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 05 and 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 ?? 05 for 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 shows 0x… 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 the module+offset it 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. --settings opens 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.md in 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, so getMemoryRecord/readInteger etc. 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 analyze surfaces the
    static RE toolkit from the shell. New docs/SCRIPTING.md + examples/.
  • cescan scan gained --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 disasm annotates a direct call/jmp target with its symbol, or its
    module+offset when 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+offset note for what the
    effective address points at (e.g. mov rax, [0x…] ; -> libc!environ).
  • cescan write gained --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 --type it still hex-dumps as before.