Skip to content

taowu82/LuraphDeobfuscator

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 

Repository files navigation

Luraph_Deobfuscator

Automatically deobfuscate Luraph scripts. Tested on Luraph scripts between v11.5 and v11.8.1 (May 1, 2020 release)

Requires Java 8 to run.

Binary Release (Version 1.0.0)

https://github.com/TheGreatSageEqualToHeaven/LuraphDeobfuscator/releases/download/v1.0.0/LuraphDevirtualizer.jar

Discord Group

Come discuss this project in my Lua discord

https://discord.gg/cdhcryv

Add me on discord

The Great Sage Equal To Heaven#7780

Motivation

This project was created for intellectual purposes as a way to explore code deobfuscation techniques on Lua scripts obfuscated by Luraph, which is a tool used to obfuscate Lua scripts. This Lua obfuscator has been used by cybercriminals as a way of protecting malicious exploits they sell for Robolox or bots for World of Warcraft. This project may be of interest to game security developers to prevent cheating in their games by discovering how hackers are breaking their code.

Luraph scripts are extremely complicated to tackle, especially in an automated matter. The process is essentially.

  • Lex and parse input Lua file to generate parse tree
  • Convert parse tree into abstract syntax treee
  • Optimize the abstract syntax tree
  • Rename variables, populate symbol table.
  • Detect and rename variables and function names into names such as get_float64, etc
  • Detect VM handlers
  • Find all encryption information in Lua VM
  • Load and decrypt bytecode using above information.
  • Decrypt and populate chunks by symbolically executing Lua code (constants, instructions, prototypes).
  • Process VM handler redirection and decryption (bytecode redirection).
  • Remove antidecompiler tricks from optimized bytecode
  • Remove junk code and further optimize bytecode using various techniques and algorithms.
  • Generate luac file

LuraphDeobfuscator provides a Lua deobfuscation engine which can be ported to other Lua obfuscators trivially. This source code can be used, with minor modifications, for a vast array of things related to Lua. I emplore the community to reuse my code and engine to create other Lua deobfuscators, as long as they state they are using my code and provide a link back to this project.

Simple usage

Generate a .luac file from an obfuscated Luraph VM script

java -jar LuraphDeobfuscator.jar -i obfuscated.lua -o obfuscated.luac

You may now use a Lua decompiler such as unluac to decompile the code back into Lua. I recommend unluac for decompilation and luadec for generating disassemblies with pseudocode.

Advanced Use: Introduction

I have written the sample Lua code below:

local x = 0

local name = "name: "

for i = 0, 10 do
	x = x + i
end

for i = 0, 10 do
	name = name .. i .. ","
end

print(x)
print(name)

Ive uploaded the obfuscated version of that Luraph script to pastebin here: https://pastebin.com/SubyTCBL

Here is a screenshot of what the obfuscated code looks like:

Luraph VM

We are now going to explore all of Luraph Deobfuscator's features:

Advanced Use: Deobfuscation

Download the above script as file.lua and run the deobfuscator

java -jar LuraphDeobfuscator.java -i file.lua -o file.luac

Use unluac to decompile the generated bytecode and save it to file.lua

java -jar unluac.jar file.luac > file.lua

Deobfuscated code using luadec

local l_0_0 = 0
local l_0_1 = "name: "
for l_0_5 = 0, 10 do
  l_0_0 = l_0_0 + l_0_5
end
for l_0_9 = 0, 10 do
  l_0_1 = l_0_1 .. l_0_9 .. ","
end
print(l_0_0)
print(l_0_1)

Deobfuscated code using unluac

local L0_0, L1_1, L2_2, L3_3, L4_4, L5_5
L0_0 = 0
L1_1 = "name: "
for L5_5 = 0, 10 do
  L0_0 = L0_0 + L5_5
end
for L5_5 = 0, 10 do
  L1_1 = L1_1 .. L5_5 .. ","
end
L2_2(L3_3)
L2_2(L3_3)

Of course, we know that using a decompiler we can't always expect to get back a complete version of the source code. In this case luadec generates the complete source code but unluac misses assigning print to L2_2

To get an accurate dissasembly listing, we can also use luadec's disassembler

luadec -dis file.lua > file.dis.txt

-dis file.lua 

; Function:        0
; Defined at line: 0
; #Upvalues:       0
; #Parameters:     0
; Is_vararg:       2
; Max Stack Size:  13

    0 [-]: LOADK     R0 K0        ; R0 := 0
    1 [-]: LOADK     R1 K1        ; R1 := "name: "
    2 [-]: LOADK     R6 K0        ; R6 := 0
    3 [-]: LOADK     R7 K2        ; R7 := 10
    4 [-]: LOADK     R8 K3        ; R8 := 1
    5 [-]: FORPREP   R6 1         ; R6 -= R8; pc += 1 (goto 7)
    6 [-]: ADD       R0 R0 R9     ; R0 := R0 + R9
    7 [-]: FORLOOP   R6 -2        ; R6 += R8; if R6 <= R7 then R9 := R6; PC += -2 , goto 6 end
    8 [-]: LOADK     R6 K0        ; R6 := 0
    9 [-]: LOADK     R7 K2        ; R7 := 10
   10 [-]: LOADK     R8 K3        ; R8 := 1
   11 [-]: FORPREP   R6 4         ; R6 -= R8; pc += 4 (goto 16)
   12 [-]: MOVE      R10 R1       ; R10 := R1
   13 [-]: MOVE      R11 R9       ; R11 := R9
   14 [-]: LOADK     R12 K4       ; R12 := ","
   15 [-]: CONCAT    R1 R10 R12   ; R1 := concat(R10 to R12)
   16 [-]: FORLOOP   R6 -5        ; R6 += R8; if R6 <= R7 then R9 := R6; PC += -5 , goto 12 end
   17 [-]: MOVE      R6 R2        ; R6 := R2
   18 [-]: MOVE      R7 R3        ; R7 := R3
   19 [-]: CALL      R6 2 1       ;  := R6(R7)
   20 [-]: MOVE      R6 R2        ; R6 := R2
   21 [-]: MOVE      R7 R3        ; R7 := R3
   22 [-]: CALL      R6 2 1       ;  := R6(R7)
   23 [-]: RETURN    R0 1         ; return 

Advanced Use: Inspecting Luraph VM

If we are curious about manually inspecting the VM ourselves, we can use LuraphDeobfuscator to generate a pseudocode source listing of the Luraph VM either in psuedocode or with its graphical display

To save the VM to a file

java -jar LuraphDeobfuscator -i file.lua -s > file.vm.lua

To copy the VM to your clipboard (CTRL+C/CTRL+P)

java -jar LuraphDeobfuscator -i file.lua -c

The contents of running that command on the script we are interested can be found here:

https://pastebin.com/eK0Tu0QM

And when we look at a screenshot we can now easily read the VM code. This process is used internally by LuraphDeobfuscator in order to fully deobfuscate Luraph code.

We can see it even assigns names to functions and variables. Pretty neat!

Optimized VM

Advanced Use: Viewing Abstract Syntax Trees

We can also view the optimized VM graphically:

java -jar LuraphDeobfuscator -i file.lua -s

The following window will be displayed:

Luraph AST

Advanced Use: Dumping Bytecode

It is normally better to use luadec to generate a disassembly of bytecode, but for whatever reason if that doesn't happen or you are curious about exploring LuraphDeobfuscator's features, you can also use it to dump optimized bytecode.

java -jar LuraphDeobfuscator -i file.lua -b > file.bytecode.txt

DUMPING CHUNK
#UPVALUES = 0.0
#PARAMS = 0.0
#MAXSTACKSIZE = 9.0
#CONSTANTS = 7
#INSTRUCTIONS = 24
#PROTOTYPES = 0

Constant 0 = 0.0
Constant 1 = name: 
Constant 2 = 10.0
Constant 3 = 1.0
Constant 4 = ,
Constant 5 = print
Constant 6 = 

[0] LOADK 0.0 0.0
[1] LOADK 1.0 1.0
[2] LOADK 2.0 0.0
[3] LOADK 3.0 2.0
[4] LOADK 4.0 3.0
[5] FORPREP 2.0 1.0
[6] ADD 0.0 0.0 5.0
[7] FORLOOP 2.0 -2.0
[8] LOADK 2.0 0.0
[9] LOADK 3.0 2.0
[10] LOADK 4.0 3.0
[11] FORPREP 2.0 4.0
[12] MOVE 6.0 1.0
[13] MOVE 7.0 5.0
[14] LOADK 8.0 4.0
[15] CONCAT 1.0 6.0 8.0
[16] FORLOOP 2.0 -5.0
[17] GETGLOBAL 2.0 5.0
[18] MOVE 3.0 0.0
[19] CALL 2.0 2.0 1.0
[20] GETGLOBAL 2.0 5.0
[21] MOVE 3.0 1.0
[22] CALL 2.0 2.0 1.0
[23] RETURN 0.0 1.0


END CHUNK

About

Deobfuscate Luraph scripts

Resources

Stars

Watchers

Forks

Packages

No packages published

Languages

  • Java 98.2%
  • ANTLR 1.8%