2022-08-11 20:54:19 +00:00
# LuaDecompy
2022-08-11 21:00:41 +00:00
An experimental Lua 5.1 dump decompiler (typically dumped using `luac -o <out.luac> <script.lua>` ).
2022-08-11 20:54:19 +00:00
2022-08-11 21:56:42 +00:00
You will quickly find that only **extremely** simple scripts are decompiled successfully right now. This is an experimental project and not all opcodes are properly handled for now. If you need a real decompiler I would recommend any of the handful of ones that exist already.
## Why?
Lua has a relatively small instruction set (only 38 different opcodes!). This makes it pretty feasible for a weekend decompiler project. (real) Decompilers are extremely complex pieces of software, so being able to write a simpler one helps show the theory without *much* of the headache.
2022-08-11 20:54:19 +00:00
## Example usage
```sh
2022-08-11 21:00:41 +00:00
> cat example.lua && luac5.1 -o example.luac example.lua
2022-08-16 05:12:26 +00:00
local tbl = {"He", "llo", " ", "Wo", "rld", "!"}
local str = ""
2022-08-11 21:00:41 +00:00
2022-08-16 05:12:26 +00:00
for i = 1, #tbl do
str = str .. tbl[i]
end
print(str)
2022-08-11 21:00:41 +00:00
> python main.py example.luac
2022-08-11 20:54:19 +00:00
example.luac
==== [[example.lua's constants]] ====
2022-08-16 05:12:26 +00:00
0: [STRING] He
1: [STRING] llo
2: [STRING]
3: [STRING] Wo
4: [STRING] rld
5: [STRING] !
6: [STRING]
7: [NUMBER] 1.0
8: [STRING] print
2022-08-12 22:08:31 +00:00
==== [[example.lua's locals]] ====
2022-08-16 04:30:32 +00:00
R[0]: tbl
2022-08-16 05:12:26 +00:00
R[1]: str
R[2]: (for index)
R[3]: (for limit)
R[4]: (for step)
R[5]: i
2022-08-11 20:54:19 +00:00
==== [[example.lua's dissassembly]] ====
2022-08-16 05:12:26 +00:00
[ 0] NEWTABLE : 0 6 0 ;
[ 1] LOADK : R[1] K[0] ; load "He" into R[1]
[ 2] LOADK : R[2] K[1] ; load "llo" into R[2]
[ 3] LOADK : R[3] K[2] ; load " " into R[3]
[ 4] LOADK : R[4] K[3] ; load "Wo" into R[4]
[ 5] LOADK : R[5] K[4] ; load "rld" into R[5]
[ 6] LOADK : R[6] K[5] ; load "!" into R[6]
[ 7] SETLIST : 0 6 1 ;
[ 8] LOADK : R[1] K[6] ; load "" into R[1]
[ 9] LOADK : R[2] K[7] ; load 1 into R[2]
[ 10] LEN : 3 0 0 ;
[ 11] LOADK : R[4] K[7] ; load 1 into R[4]
[ 12] FORPREP : R[2] 3 ;
[ 13] MOVE : 6 1 0 ; move R[1] into R[6]
[ 14] GETTABLE : R[7] 0 R[5] ;
[ 15] CONCAT : 1 6 7 ; concat 2 values from R[6] to R[7], store into R[1]
[ 16] FORLOOP : R[2] -4 ;
[ 17] GETGLOBAL : R[2] K[8] ; move _G["print"] into R[2]
[ 18] MOVE : 3 1 0 ; move R[1] into R[3]
[ 19] CALL : 2 2 1 ;
[ 20] RETURN : 0 1 0 ;
2022-08-16 04:30:32 +00:00
==== [[example.lua's pseudo-code]] ====
2022-08-16 05:12:26 +00:00
local tbl = {"He", "llo", " ", "Wo", "rld", "!", }
2022-08-16 05:26:50 +00:00
local str = ""
2022-08-16 05:12:26 +00:00
for i = 1, #tbl , 1 do
2022-08-16 05:26:50 +00:00
str = str .. tbl[i]
2022-08-16 05:12:26 +00:00
end
print(str)
2022-08-11 22:26:48 +00:00
2022-08-11 20:54:19 +00:00
```