Fork Notice: This is a fork of the original unluac project from SourceForge with bug fixes and improvements.
unluac is a decompiler for Lua bytecode versions 5.0 through 5.4. It converts compiled Lua chunks back into readable Lua source code, making it useful for analyzing, debugging, and understanding Lua bytecode.
- ✅ Multi-version Support: Lua 5.0, 5.1, 5.2, 5.3, and 5.4
- ✅ Command-line Interface: Simple and straightforward usage
- ✅ Java-based: Cross-platform compatibility
- ✅ Debug Info Required: Works with standard Lua compiler output (non-stripped chunks)
Download the latest JAR file from the official SourceForge page, or use the pre-built unluac.jar.
Requirements: JDK 8 or higher
# Clone the repository
git clone https://github.com/Jeong-Min-Cho/unluac.git
cd unluac
# Compile
cd src
javac -d ../build unluac/Main.java
# Create JAR
cd ../build
jar cfm ../unluac.jar ../MANIFEST.MF unluac/java -jar unluac.jar <input.luac> > output.luaDecompile a Lua chunk:
java -jar unluac.jar myfile.luac > myfile_decompiled.luaDecompile with custom opcode mapping (for custom Lua implementations like xlua):
java -jar unluac.jar --opmap opcode_map.txt myfile.luac > output.luaDisassemble instead of decompile:
java -jar unluac.jar --disassemble myfile.luac--opmap <file>- Use custom opcode mapping file (for modified Lua VMs)--disassemble- Output disassembly instead of decompiled code--version- Show version information
- Java: JRE/JDK 8 or higher
- Input: Lua bytecode compiled with debug information (default for
luac) - Supported Lua Versions: 5.0, 5.1, 5.2, 5.3, 5.4
Note: The Lua compiler includes debugging information by default. If chunks are compiled with the
-sflag (strip debug info), decompilation will not work properly.
| Lua Version | Support Level |
|---|---|
| Lua 5.0 | ✅ Very good |
| Lua 5.1 | ✅ Very good |
| Lua 5.2 | ✅ Good |
| Lua 5.3 | ✅ Good |
| Lua 5.4 | ✅ Good (some goto edge cases) |
- Stripped Bytecode: Cannot decompile chunks compiled with
-sflag - Complex Gotos: Lua 5.2+ code with heavy use of goto statements may not decompile perfectly
- Custom Lua VMs: Modified Lua implementations may require custom opcode mappings
This fork includes critical bug fixes not present in the original version:
Problem: Original unluac crashed when decompiling valid Lua bytecode containing CALL or VARARG instructions with variable return values at register boundaries.
Solution:
- Fixed off-by-one error in register count calculation in
Decompiler.java - Added defensive bounds checking in
Registers.java
Impact:
- Fixes crashes on valid Lua bytecode
- Improves compatibility with custom Lua implementations
- tehtmi - Main developer
- Thomas Klaeger - Added support for Lua 5.0
- John Fowler - Contributed closure fix patch
See authors.txt for complete attribution.
Bug fixes and improvements by contributors to this repository.
If you have luac installed:
# Compile test files and run decompiler
cd test/src
luac -o ../compiled/test.luac test.lua
java -jar ../../unluac.jar ../compiled/test.luacMIT License - see license.txt for details.
Copyright (c) 2011-2020 tehtmi Portions Copyright (c) 2014 Thomas Klaeger
- Original Project: SourceForge - unluac
- Lua Official Site: lua.org
- Lua Reference Manual: Lua 5.4 Reference
If you encounter ArrayIndexOutOfBoundsException, NullPointerException, or similar errors:
- Use this fork - The original version has known bugs that are fixed here
- Check debug info - Ensure your
.luacfile was compiled with debug information - Verify Lua version - Make sure the bytecode version is supported (5.0-5.4)
- Custom VM? - If using a modified Lua VM, you may need an opcode mapping file
This can happen due to:
- Control flow complexity - Very complex goto statements in Lua 5.2+
- Bytecode optimization - Some compiler optimizations may not decompile perfectly
- Custom implementations - Non-standard Lua VMs may have quirks
-- original.lua
local function greet(name)
return "Hello, " .. name .. "!"
end
print(greet("World"))# Compile
luac -o original.luac original.lua
# Decompile
java -jar unluac.jar original.luac > decompiled.luaFor modified Lua implementations with shuffled opcodes:
- Create opcode mapping file:
.op 0 getglobal
.op 1 settable
.op 2 getupval
.op 3 setglobal
.op 4 return
.op 5 tforloop
.op 6 loadk
# ... etc
- Decompile with mapping:
java -jar unluac.jar --opmap opcodes.txt custom.luac > output.luaNote: This tool is intended for legitimate purposes such as debugging, learning, and analyzing Lua code. Please respect intellectual property rights and use responsibly.