Oninit Phoenix Recover: Informix 4GL Decompiler
Lost the source code for an Informix 4GL application? Oninit Phoenix
Recover decompiles compiled 4GL programs (.4ge) back into readable,
re-compilable .4gl source. Upload a program and the tool
rebuilds its functions, call graph, control flow, MENU/INPUT/CONSTRUCT
blocks, REPORT sections and embedded SQL, then shows the
recovered source directly on the page. There's nothing to install and nothing
is stored. Every release is checked against the real IBM Informix 4GL
compiler, so the output isn't just readable, it compiles.
What it recovers
Upload an Informix 4GL compiled program (.4ge) file, and the tool
will reverse-engineer the binary and reconstruct readable
.4gl source. The decompiler recovers the module's functions and
their call graph; control flow including IF/ELSE,
WHILE, CASE / WHEN,
FOR and FOREACH with their
EXIT / CONTINUE statements;
MENU, INPUT and CONSTRUCT interaction
blocks with their per-key ON KEY sections; REPORT
definitions including the procedural code inside each FORMAT
section; embedded SQL and cursor operations; expressions, function calls with
their RETURNING targets; and the variable definitions it can
resolve — making it easier to inspect, document, maintain, or migrate legacy
applications when the original source is no longer available.
Supported programs and limits
Recovery works on not-stripped programs — the ordinary
output of c4gl. As a deliberate policy the tool
refuses stripped binaries, whose symbols have been removed;
it is intended for recovering your own builds, not for reading
programs whose authors chose to strip them. Uploads are limited to a single
not-stripped program of up to 100 KiB.
Recovery currently supports Linux builds only — 64-bit
x86 programs as produced by c4gl on Linux. A program compiled for
another platform uses a different executable format and instruction set, so it
cannot be read by this release even when it is not stripped. Support for further
platforms is under consideration; if you have compiled programs on another Unix
and need them recovered, please get in touch.
Single-file uploads are supported, and once processing is complete, the reconstructed .4gl source is rendered directly on the page for immediate review. No additional software, configuration, or manual extraction steps are required.
Output: one combined .4gl file
A compiled program is normally linked from several source
modules together with the GLOBALS files they share, and the
compiled form keeps no record of which module each routine came from. The
recovery therefore returns everything the program contains as a
single .4gl source — every module and the global
declarations combined in one file, which for a substantial program can be
large. The content is complete; it is the original division into separate
files that cannot be recovered, so the recovered source is a starting point
for re-splitting into modules rather than a like-for-like replacement of the
original file set. This makes the tool useful beyond one-off recovery too —
for documenting, auditing, or planning a legacy Informix migration
where the original 4GL source has been lost.
How we verify recovery, not just claim it
A decompiler is easy to demo and hard to trust, so we don't just show a plausible-looking result — we compile it. Every recovered .4gl is checked against the original, unmodified 4GL source the compiled program was built from, then handed to the real, unmodified IBM Informix 4GL compiler to confirm the recovered source is genuinely valid 4GL — not merely readable, but re-compilable. Both checks run automatically, on every change to the recovery engine, against a reference program built from public, non-customer 4GL source.
The verification checks four independent things against the known-correct
original: the recovered program's function inventory (every
routine present, none invented), its call graph (which
routine calls which), its embedded SQL (the static
DELETE/INSERT/UPDATE operations the
program issues), and its statement-type coverage (the mix of
4GL verbs — DISPLAY, FETCH,
CURSOR, control flow, and the rest — the recovered source
actually contains). The current reference run: 14/14
functions recovered, 17/17 call-graph edges, 3/3
static SQL operations, 8/8 statement verbs — then a
clean compile against the real compiler with zero errors.
Beyond the single reference program, the recovery engine is regression-tested against a corpus of 350 real-world compiled Informix 4GL programs spanning 139 distinct applications — not synthetic test cases, but programs originally built and shipped by real 4GL codebases. For each one, we decompile the .4ge to .4gl, then hand that recovered source straight back to the same real, unmodified IBM Informix compiler with no edits in between. As of the current build, 18 of those programs — 7,031 lines of recovered 4GL in total — round-trip completely cleanly: decompiled straight back into a fresh, genuinely runnable compiled binary, with zero compiler errors. That is a full loop, not a syntax check: .4ge in, .4gl out, and a working .4ge-equivalent binary back out the other end. The remaining programs in the corpus recover partially today — most compile down to a short, specific list of remaining errors rather than failing outright — and that count is climbing as each remaining gap is found and fixed. (Program names and source are not shown here, as the corpus is drawn from real third-party codebases, not public samples.)
Here is a short excerpt, side by side: the original hand-written source on
the left, what the recovery engine reconstructs from the compiled binary
alone (no source, no debug symbols) on the right. Recovered stack-local
names (p_1) and cursor identifiers (cursor_1) are
synthetic — a compiled binary keeps no record of the programmer's
original local-variable or cursor names — but the logic, the SQL, the
control flow, and every field reference reconstruct exactly.
Original source
FUNCTION getrow(l_currpos)
DEFINE l_currpos INTEGER
FETCH ABSOLUTE l_currpos rwd_cur INTO m_current_rowid
OPEN table_cur USING m_current_rowid
FETCH table_cur INTO
m_current.id,
m_current.name,
m_current.desc,
m_current.cmd,
m_current.dest,
m_current.active
IF STATUS = NOTFOUND THEN
MESSAGE " Recently Deleted"
CALL init_buf()
SLEEP 1
ELSE
DISPLAY BY NAME m_current.id
DISPLAY BY NAME m_current.name
DISPLAY BY NAME m_current.desc
DISPLAY BY NAME m_current.cmd
DISPLAY BY NAME m_current.dest
DISPLAY BY NAME m_current.active
END IF
CLOSE table_cur
MESSAGE ""
END FUNCTION
Recovered from the compiled binary
FUNCTION getrow(p_1)
DEFINE p_1 INTEGER
FETCH ABSOLUTE p_1 cursor_3 INTO m_current_rowid
OPEN cursor_1 USING m_current_rowid
FETCH cursor_1 INTO m_current.*
IF STATUS = NOTFOUND THEN
MESSAGE " Recently Deleted"
CALL init_buf()
SLEEP 1
ELSE
DISPLAY BY NAME m_current.id
DISPLAY BY NAME m_current.name
DISPLAY BY NAME m_current.desc
DISPLAY BY NAME m_current.cmd
DISPLAY BY NAME m_current.dest
DISPLAY BY NAME m_current.active
END IF
CLOSE cursor_1
MESSAGE ""
END FUNCTION
(This reference program's original source and its identifiers are already public — a small stand-alone maintenance utility used only as our verification baseline. Real customer programs recovered through this feature are never used as examples here.)
Source Code Recovery Authorization
Please read carefully before continuing.
This feature is intended solely for recovering source code from executable programs that you own or are otherwise legally authorized to analyze.
By clicking “I Accept” or otherwise continuing, you acknowledge and agree that:
- You own the software being decompiled, or you have obtained all necessary rights and permissions from the copyright owner.
- You are legally authorized to decompile and reconstruct the source code from the submitted executable.
- Your use of this feature complies with all applicable laws, software license agreements, contracts, and intellectual property rights.
- You understand that unauthorized decompilation of software owned by others may violate copyright, contractual obligations, or other applicable laws.
- You accept full responsibility for your use of this feature and for any recovered source code.
By selecting “I Accept” and continuing, you certify that the above statements are true and agree that you are solely responsible for ensuring you have the legal authority to use this feature.
The decompiler runs server-side; nothing is stored. Some fine detail cannot be recovered from a compiled binary — un-named stack locals appear as synthetic names, and a few pure-data statements leave no trace — so the reconstructed source is intended for reading and re-authoring, not as a byte-for-byte round trip. See also the companion form decompiler, Oninit Phoenix Forms.