Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 14 additions & 9 deletions demo/Recompiler/Compiler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ namespace Recompiler
{
public class Compiler
{
public static string LuacPath = "lua/luac5.1"; // NOTE: make sure the LuaC 5.1 binary is installed right there
public static string CompiledInPath = "lua/in/"; // stores all the Lua files that got uploaded
public static string CompiledOutPath = "lua/out/"; // stores all the Lua files that got compiled
public static string LuacPath = Path.Combine(AppContext.BaseDirectory, "lua", "luac5.1");
public static string InPath = Path.Combine(AppContext.BaseDirectory, "lua", "in");
public static string OutPath = Path.Combine(AppContext.BaseDirectory, "lua", "out");

public List<string> FullFileName;
public List<string> FileName;
Expand All @@ -37,7 +37,8 @@ public void AddFile(byte[] Buffer, string fileName)
this.FileName.Add(fileName);
fileName = this.Owner + "__" + fileName + "__" + DateTime.UtcNow.ToString("yyyy_MM_dd_HH_mm_ss");
this.FullFileName.Add(fileName);
File.WriteAllBytes($"{Directory.GetCurrentDirectory()}/{CompiledInPath}{fileName}", Buffer);
Directory.CreateDirectory(InPath);
File.WriteAllBytes(Path.Combine(InPath, fileName), Buffer);
// TODO: hash = hash(Owner:Date:FileName)
}

Expand All @@ -46,12 +47,15 @@ public bool Compile()
if (!File.Exists(LuacPath))
return false;

Directory.CreateDirectory(OutPath);

Process p = new Process();
//p.StartInfo.UseShellExecute = false;
p.StartInfo.UseShellExecute = false;
p.StartInfo.FileName = LuacPath;
p.StartInfo.Arguments = $"-o {CompiledOutPath}{this.Owner} ";
p.StartInfo.ArgumentList.Add("-o");
p.StartInfo.ArgumentList.Add(Path.Combine(OutPath, this.Owner));
for (int i = 0; i < this.FullFileName.Count; i++)
p.StartInfo.Arguments += $"{CompiledInPath}{this.FullFileName[i]} ";
p.StartInfo.ArgumentList.Add(Path.Combine(InPath, this.FullFileName[i]));
p.Start();
p.WaitForExit(); // timeout this?

Expand All @@ -63,8 +67,9 @@ public bool Compile()

public byte[] GetCompiled()
{
if (File.Exists(CompiledOutPath + this.Owner))
return File.ReadAllBytes(CompiledOutPath + this.Owner);
string compiledPath = Path.Combine(OutPath, this.Owner);
if (File.Exists(compiledPath))
return File.ReadAllBytes(compiledPath);

return null;
}
Expand Down
7 changes: 2 additions & 5 deletions demo/Recompiler/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,8 @@ class Program
static void Main(string[] args)
{
// NOTE: Please download and install Lua 5.1 and link the LuaC binary to ./lua/luac
Console.WriteLine("Please enter the path of your project files: ");
//string path = Console.ReadLine();
//string path = @"H:\games\World of Warcraft\_retail_\Interface\AddOns\dubai";
string path = @"L:\Projects\LuaBytcodeInterpreter\lua_installer\files\testAddon";

string path = Compiler.InPath; // change to whatever path for the files u wanna decompile
if (!Directory.Exists(path))
{
Console.WriteLine("Directory doesn't exist");
Expand Down Expand Up @@ -46,7 +43,7 @@ void discoverDirectory(string dir, ref List<string> paths, ref List<byte[]> buff
comp.AddFiles(Buffers, Paths);
if(!comp.Compile())
{
Console.WriteLine("Compiler error!!");
Console.WriteLine("Compiler error!!" );
Console.ReadKey();
return;
}
Expand Down
47 changes: 44 additions & 3 deletions src/Decompiler/LuaScriptFunction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ public class LuaScriptFunction

public List<LuaScriptBlock> Blocks;
private List<int> UsedLocals;
private Dictionary<int, int> EndCount = new Dictionary<int, int>(); // gonna actually count how many blocks close at each jmp target

public string Name
{
Expand Down Expand Up @@ -87,6 +88,34 @@ private void InitArgs(int count)
}
}

private void AddEnd(int address)
{
if (!EndCount.ContainsKey(address))
EndCount[address] = 0;

EndCount[address]++;
}

public void BuildEnd()
{
EndCount.Clear();

foreach (var block in this.Blocks)
{
var condition = block.GetConditionLine();

if (block.JumpsTo == -1 || block.JumpsNext == -1 || condition == null || !condition.IsCondition())
continue;

int target = block.JumpsTo;
var thenBlock = this.Blocks.FirstOrDefault(x => x.StartAddress == block.JumpsNext);
if (thenBlock != null && thenBlock.JumpsTo != -1 && thenBlock.JumpsNext == -1)
target = thenBlock.JumpsTo;

AddEnd(target);
}
}

public override string ToString()
{
string args = "(";
Expand Down Expand Up @@ -152,6 +181,7 @@ private LuaFunction FindParentFunction(LuaFunction function, LuaFunction search

return null;
}


// NOTE: Please do NOT touch this unless you 110% know what you are doing!!!
private void GenerateBlocks(bool overwriteBlocks = false)
Expand Down Expand Up @@ -264,6 +294,8 @@ private void GenerateBlocks(bool overwriteBlocks = false)
}
}

BuildEnd();

for (int i = 0; i < this.Blocks.Count; i++)
{
// IF: JMP != -1 && ELSE != -1 (&& GetConditionLine != NULL; ELSE; FORLOOP END (dont care))
Expand Down Expand Up @@ -388,11 +420,13 @@ private void GenerateBlocks(bool overwriteBlocks = false)
else if (this.Blocks[i].JumpsTo == -1 && this.Blocks[i].JumpsNext != -1 && this.Blocks[i].GetBranchLine() != null
&& this.Blocks[i].GetBranchLine().Instr.OpCode != LuaOpcode.FORPREP) // also make sure if condifition is set (no forloop)
{

// IF block endings are emitted by GenerateCleanCode using EndCount.
#if false
#if DEBUG
this.Blocks[i].Lines[this.Blocks[i].Lines.Count - 1].Postfix += "\r\nend -- ENDIF";
#else
this.Blocks[i].Lines[this.Blocks[i].Lines.Count - 1].Postfix += "\r\nend";
#endif
#endif
}

Expand Down Expand Up @@ -633,16 +667,23 @@ private string GenerateCleanCode()
string result = "";
for (int b = 0; b < this.Blocks.Count; b++)
{
if (EndCount.TryGetValue(this.Blocks[b].StartAddress, out int endCount))
{
for (int e = 0; e < endCount; e++)
result += "end\r\n";
}

for (int i = 0; i < this.Blocks[b].Lines.Count; i++)
{
if(this.Blocks[b].Lines[i].Instr.OpCode == LuaOpcode.CLOSURE)
if (this.Blocks[b].Lines[i].GetFunctionRef() != null)
result += this.Blocks[b].Lines[i].GetFunctionRef().ScriptFunction.BeautifieCode(); // inline func in parent
result += this.Blocks[b].Lines[i].GetFunctionRef().ScriptFunction.BeautifieCode();

result += this.Blocks[b].Lines[i].Text;
}

if (b == this.Blocks.Count - 1)
result += "\r\n"; // keep it clean?
result += "\r\n";
}
return result;
}
Expand Down
14 changes: 12 additions & 2 deletions src/Decompiler/LuaScriptLine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,15 @@ public LuaScriptLine(LuaInstruction instr, LuaDecoder decoder, LuaFunction func)
SetMain();
}

private string GetClosureName()
{
LuaFunction func = GetFunctionRef();
if (func == null && Instr.Bx >= 0 && Instr.Bx < Func.Functions.Count)
func = Func.Functions[Instr.Bx];

return func?.ScriptFunction?.Name ?? func?.Name ?? $"{Func.Name}_{Instr.Bx}";
}

public void SetMain(LuaInstruction Instr = null)
{
if (Instr == null)
Expand Down Expand Up @@ -391,10 +400,11 @@ public void SetMain(LuaInstruction Instr = null)
// crates closutre for function prototype Bx
this.Op1 = $"{WriteIndex(Instr.A)}";
this.Op2 = " = ";
if(this.Func.Functions[Instr.Bx].ScriptFunction != null)
this.Op3 = GetClosureName(); // better than "IDK_SHIT_WENT_MISSING_BRO" lol
/*if(this.Func.Functions[Instr.Bx].ScriptFunction != null)
this.Op3 = this.Func.Functions[Instr.Bx].ScriptFunction.Name;
else
this.Op3 = $"IDK_SHIT_WENT_MISSING_BRO"; // TODO fix
this.Op3 = $"IDK_SHIT_WENT_MISSING_BRO"; // TODO fix*/
break;
case LuaOpcode.VARARG:
this.Func.ScriptFunction.HasVarargs = true;
Expand Down