unidecompiler-gui
unidecompiler-gui is a read-only PySide6 workbench for the public
unidecompiler.DecompilerEngine API. It accepts one artifact, a directory, or
a ZIP/JAR archive and shows pseudocode, AST, bytecode, and diagnostics together.
Install from PyPI; cloning this repository is not required for normal use.
Install the base GUI with its Qt dependency:
python -m pip install unidecompiler-gui
Install all separately published frontend plugins when needed:
python -m pip install 'unidecompiler-gui[all-formats]'
The GUI never imports frontend plugin packages directly. It discovers installed
plugins through DecompilerEngine and does not modify input artifacts or save
workspace state. Its optional Simulation tab uses the separate generic IR
simulator and can load a trusted Python runtime file for unresolved functions.
The Symbolic tab performs bounded path exploration over recovered generic
IR. Targets come from the selected frontend's opaque, data-only query list;
the GUI does not infer names, overloads, or dynamic call targets. The parameter
table displays the frontend's parameters and lets you choose bool, int,
real, or fixed-width bitvec sorts. Concrete accepts a JSON object such
as {} or {"value": 5} for values that should not be symbolic. Press
Explore to inspect path constraints, solver models, returns or raises, and
the concrete CFG block/edge trace. Path, step, loop-unroll, call-depth, and
solver-timeout limits keep exploration bounded; unsupported, limit,
timeout, cancellation, and invalid-request outcomes remain visible instead of
being presented as successful execution.
For example, a choose(value) function explored with {"value":{"sort":"int"}}
produces separate paths for each branch. Supplying Concrete {"value":5}
constrains the same target to the paths feasible for that value. The tab
consumes only the public SymbolicResult and never receives Z3 runners,
simulator frames, frontend decoders, or private IR objects.
Structure and Hex analysis
Structure / Hex is a read-only, IR-first provenance view. It shows the
generic recovered structure beside a virtualized hexadecimal view of the
original input. Selecting a structure node highlights every exact artifact byte
range known for its source instructions. When a frontend only has a logical VM
offset, the GUI shows that offset and deliberately does not guess a file byte
location. The view is analysis-only: it does not edit bytes, re-encode opcodes,
or execute frontend bytecode.
Extension templates
Use Tools -> Export extension template to create a self-contained starter
project for either a VM frontend or a GUI plugin. The exporter writes a new
directory only and never overwrites an existing path. Each project includes its
matching full development guide, a focused AGENTS.md, a README containing the
requested feature, packaging metadata, and test skeletons.
The VM frontend template keeps decoding and thin-IR submission separate from
core recovery. Its optional simulation adapter is data-only; the generic IR
simulator remains responsible for execution. The GUI plugin template depends
only on unidecompiler-gui-sdk and remains a read-only application extension.
The exported frontend guide also documents edge-aware CFG recovery. Core keeps parallel edges distinct and performs Phi/fallthrough simplification only when the exact control-flow and exception-state proof succeeds; generated frontend code must submit facts and never recover or rewrite CFGs itself.
Frontend persistence
Custom VM frontend folders registered from View -> Frontends are persisted by
the GUI host. After the first successful registration, the GUI restores the
folder on the next startup before opening input files. The frontend registry
and core remain runtime-only; the GUI stores only the normalized source path
and frontend ID.
Unload selected removes a frontend from the current process but keeps its
startup record. Remove from startup removes it from the current process and
from the GUI startup records, but never deletes the frontend directory from
disk. Built-in entry-point frontends are not stored as user records.
If a saved directory is missing or its manifest/module is invalid, startup
continues. The frontend manager marks the record unavailable and shows the
diagnostic so the path can be repaired or removed. Frontend source is trusted
Python code and is not sandboxed.
GUI plugins
The Plugins menu manages optional Python GUI plugins. A plugin is an
application-layer extension, separate from bytecode frontend plugins. It can
inspect immutable snapshots of open documents, functions, AST/reference
summaries and selections; add commands and declarative panels; request
navigation through stable IDs/source locations; and start asynchronous
simulation jobs.
Plugins cannot modify artifacts, generic IR, AST, pseudocode, frontend
registration, or simulator execution. They never receive a Qt Workbench,
frontend decoder payload, ModuleIR/FunctionIR, simulator frame, or stack.
Function lookup remains frontend-owned: a plugin submits an opaque query while
the GUI host delegates execution to the generic simulator.
Plugins are trusted in-process Python code, with the same permissions as the GUI process. Review every local folder or GitHub repository before installing. Dependencies in the manifest are checked at load time but never installed automatically. Install, update, enable, disable, and removal take effect after restart.
Plugin layout
Install a folder with plugin.toml through Plugins -> Manage plugins, or
install a GitHub owner/repository or /tree/ref URL.
[plugin]
id = "example.function-browser"
name = "Function browser"
version = "1.0.0"
api = "1"
entry = "function_browser:register"
[python]
requires = []
from unidecompiler_gui_sdk import Command, Panel, PanelState
def register(context):
context.panels.register(Panel("functions", "Functions"))
def refresh(ctx):
document = ctx.active_document
rows = () if document is None else tuple((item.name, item.status) for item in document.functions)
ctx.set_panel_state("functions", PanelState.table(("Function", "Status"), rows))
context.commands.register(Command("refresh", "Refresh function browser", refresh))
context.subscribe("document_selected", lambda _document: refresh(context))
Use only unidecompiler_gui_sdk types. Its API is Qt-neutral and versioned;
plugin.toml must declare the matching API version. The repository includes
unidecompiler-gui-test-plugin/ as a complete working example.
To simulate, first call context.request_simulation_targets(document_id). It
returns immediately with a target-discovery job; observe
simulation_targets_completed, obtain its SimulationTargetSnapshot values
through context.get_target_job(job_id), then pass a selected snapshot's
opaque query to context.submit_simulation(...). Observe
simulation_completed and use the SDK's SimulationResultSnapshot; plugins
never receive simulator runner objects or frontend adapters.
Metadata
Release files for unidecompiler-gui 0.2.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| unidecompiler_gui-0.2.3.tar.gz | 70.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| unidecompiler_gui-0.2.3-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 140.8 kB
Release files / unidecompiler_gui-0.2.3.tar.gz
| Download URL | unidecompiler_gui-0.2.3.tar.gz |
|---|---|
| Size | 70.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
5f6d879b20bf4322fa45a63cd294751d886f8dc3ce0fce6b6557d6e370122115
|
|
BLAKE2b-256 checksum How to use checksums |
37cf569610da193d5487132955f0ec8561113e01b6c34b52b69dde5ebe6e6bf2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.12
|
Release files / unidecompiler_gui-0.2.3-py3-none-any.whl
| Download URL | unidecompiler_gui-0.2.3-py3-none-any.whl |
|---|---|
| Size | 69.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
4d55fb3ae013e94dc4efdccdff1718c5bf42e2e6a4424f6c2d89833497f5b2ec
|
|
BLAKE2b-256 checksum How to use checksums |
cd0568ea4ad053bd208659ce742111b42b408295525d432f5bc5bf2931878899
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.12
|