cLuaDecompiler is a Free Pascal/Lazarus Lua bytecode disassembler and decompiler for Lua 5.1, 5.2, 5.3, 5.4, and 5.5 binary chunks.
The project focuses on version-aware bytecode parsing, semantic opcode mapping, SSA-based analysis, and Lua source emission that can be validated against the original program behavior when source is available.
- Disassembles Lua bytecode with version-aware opcode names and operands.
- Decompiles
.luacfiles to Lua-like source. - Dumps SSA IR for debugging control flow, register lifetimes, phi nodes, and decompiler decisions.
- Supports built-in opcode tables for Lua 5.1 through 5.5.
- Supports custom opcode-table loading for patched or obfuscated bytecode.
- Includes runtime validation that compares original source output with decompiled output under the matching Lua version.
- Includes source-less bytecode validation for cases where opcode/disassembly coverage is the source of truth.
- Includes an optional VS Code extension for opening
.luacfiles as decompiled Lua text.
- Check the
examplesfolder.
- Download it from Releases
- Windows or another platform supported by Free Pascal/Lazarus.
- Lazarus with
LazBuildavailable inPATH. - Python 3 for the validation scripts.
- Lua and
luacbinaries for validation, placed under the expected local layout when running the full suite:
lua/lua5.1/lua5.1.exe
lua/lua5.1/luac5.1.exe
lua/lua5.2/lua52.exe
lua/lua5.2/luac52.exe
lua/lua5.3/lua53.exe
lua/lua5.3/luac53.exe
lua/lua5.4/lua54.exe
lua/lua5.4/luac54.exe
lua/lua5.5/lua55.exe
lua/lua5.5/luac55.exe
Build from the repository root with Lazarus:
LazBuild cLuaDecompiler.lpiThe main executable is produced as:
cLuaDecompiler.exe
.\cLuaDecompiler.exe [options] <file.luac>Common commands:
.\cLuaDecompiler.exe --dis sample.luac
.\cLuaDecompiler.exe --dec sample.luac
.\cLuaDecompiler.exe --ssa-dump sample.luac
.\cLuaDecompiler.exe --dec --annotate sample.luacOptions:
--dis Disassemble bytecode
--dec Decompile to Lua-like source; default mode
--ssa-dump Dump SSA IR for all protos
--annotate Add disassembly comments during decompilation
--debug Emit debug trace to stderr
--lua-version VER Override detected Lua version: 51, 52, 53, 54, or 55
--opcode-table F Load a custom opcode mapping from file F
--help Show CLI help
Examples:
.\cLuaDecompiler.exe --dec script.luac > script.decompiled.lua
.\cLuaDecompiler.exe --dis script.luac > script.dis.txt
.\cLuaDecompiler.exe --ssa-dump script.luac > script.ssa.txt
.\cLuaDecompiler.exe --lua-version 51 --opcode-table opcode_tables\custom.txt patched.luacRun the runtime and bytecode validation suite:
python run_decompiler_validation.pyCompile local Lua 5.1 fixtures manually:
tests\compile_luac.batrun_decompiler_validation.py is the preferred validation path for decompiler
correctness because it can:
- compile source fixtures with the matching Lua version,
- run the original source,
- decompile the compiled bytecode,
- run the decompiled output,
- compare runtime output,
- compile stripped-bytecode fixtures,
- validate source-less bytecode through disassembly and opcode signatures.
Useful validation filters:
python run_decompiler_validation.py --versions 51
python run_decompiler_validation.py --timeout 10 --out-dir decompiled\validation_tmpRuntime-equivalence fixtures should either live in:
validation/fixtures/runtime/
or be referenced from:
validation/runtime_cases.json
Fixtures can declare supported versions at the top of the Lua file:
-- versions: 51 52 53 54 55Source-less bytecode cases belong in:
validation/bytecode_cases.json
Use validation/stubs/ for small fake environments needed to load or compile
decompiled source outside the original host application. For bytecode without
source, compare disassembly and opcode signatures rather than pretending there
is a source-level oracle.
Do not commit generated .luac files from compiled/ or decompiler output from
decompiled/.
The main pipeline is:
LuaChunk.pas -> LuaOpcodes.pas -> LuaSSA.pas -> LuaDecomp.pas/LuaDecomp*.inc
When adding support for a Lua version or opcode pattern:
- Verify chunk and instruction decoding in
LuaChunk.pas. - Add or correct semantic opcode mapping in
LuaOpcodes.pas. - Lift the semantic operation in
LuaSSA.pas. - Prefer fixing value/control-flow facts in SSA before patching emitted text.
- Update decompiler emission in the matching
LuaDecomp*.incfile. - Add runtime validation or source-less bytecode validation.
Useful debug flow:
.\cLuaDecompiler.exe --dis sample.luac > sample.dis.txt
.\cLuaDecompiler.exe --ssa-dump sample.luac > sample.ssa.txt
.\cLuaDecompiler.exe --dec --annotate sample.luac > sample.luaThe official Lua source browser is useful when opcode behavior or chunk format details are unclear:
https://www.lua.org/source/
The optional extension in vscode_plugin/ opens .luac files through
cLuaDecompiler.exe and presents the result as normal Lua text so the existing
Lua syntax highlighter can be used.
The extension can auto-detect cLuaDecompiler.exe near the workspace, or you can
set:
cluaDecompiler.executablePath
Decompiler output is best treated as recovered source, not guaranteed original source formatting. Local variable names, closure names, control-flow shape, and expression ordering may differ from the original program while still preserving runtime behavior.
Stripped bytecode and source-less application bytecode should be validated with runtime stubs when possible and with disassembly/opcode coverage when no source oracle exists.
Some Of the analyses and algorithms in this project are based on the following public sources:
- Keith D. Cooper, Timothy J. Harvey, and Ken Kennedy, A Simple, Fast Dominance Algorithm, Rice University, 2001 - iterative dominator and immediate-dominator computation.
- Ron Cytron, Jeanne Ferrante, Barry K. Rosen, Mark N. Wegman, and F. Kenneth Zadeck, Efficiently Computing Static Single Assignment Form and the Control Dependence Graph, ACM TOPLAS 13(4), 1991 - dominance frontiers, φ-function placement, and the SSA rename pass.
- Keith D. Cooper and Linda Torczon, Engineering a Compiler - background material on iterative dataflow analysis used as the basis for the dominator and SSA construction passes.
- The official Lua source browser at https://www.lua.org/source/, including
the
lopcodes.h,lopcodes.c, andlvm.cfiles for Lua 5.1, 5.2, 5.3, 5.4, and 5.5 - authoritative opcode tables, instruction formats, and VM semantics. - The
unluacLua decompiler project - used as an external comparison oracle for output formatting and structural recovery on shared fixtures.
Copyright (C) 2019-present XENOM-X TECHNOLOGY LLC.
This project is licensed under the GNU Affero General Public License version 3. See LICENSE.txt for the full license text.