public static LOL Load(string path) { FileInfo fi = new FileInfo(path); Logger.LogToFile(Logger.LogLevel.Info, "{0}", path); LOL lol = new LOL(); byte[] data = File.ReadAllBytes(path); if (data[0] == 0x1b && data[1] == 0x4c && data[2] == 0x75 && data[3] == 0x61 && data[4] == 0x51) { StringBuilder sb = new StringBuilder(); data[5] = 0; ByteBuffer buffer = new ByteBuffer(data); BHeader header = new BHeader(buffer); Decompiler d = new Decompiler(header.function.parse(buffer, header)); d.decompile(); d.print(new Output((s) => { sb.Append(s); }, () => { sb.Append("\r\n"); })); lol.document = sb.ToString(); } else { lol.document = Encoding.Default.GetString(data); } return lol; }
public override LLocal Parse(BinaryReaderEx reader, BHeader header) { LString name = header.String.Parse(reader, header); BInteger start = header.Integer.Parse(reader, header), end = header.Integer.Parse(reader, header); return(new LLocal(name, start, end)); }
private static LFunction FileToFunction(string fn) { using (var fs = File.Open(fn, FileMode.Open, FileAccess.Read, FileShare.Read)) { var header = new BHeader(fs); return(header.Function.Parse(fs, header)); } }
public override LUpvalue Parse(BinaryReaderEx reader, BHeader header) { LUpvalue upvalue = new() { InStack = reader.ReadByte() != 0, Index = reader.ReadByte() }; return(upvalue); } }
public BList <T> ParseList(BinaryReaderEx reader, BHeader header) { BInteger length = header.Integer.Parse(reader, header); List <T> values = new(); length.Iterate(Run); void Run() => values.Add(Parse(reader, header)); return(new BList <T>(length, values)); }
public void MemFree(int index) { if (!CheckIndex(index)) { throw new IndexOutOfRangeException(); } BHeader blockHeader = GetBlockHeader(index); blockHeader.IsFree = true; CreateBlockHeader(index, blockHeader); }
public override void ParseMain(BinaryReaderEx reader, BHeader header, LFunctionParseState s) { s.LineBegin = header.Integer.Parse(reader, header).AsInt(); s.LineEnd = header.Integer.Parse(reader, header).AsInt(); s.LenParameter = reader.ReadByte(); s.Vararg = reader.ReadByte(); s.MaximumStackSize = reader.ReadByte(); ParseCode(reader, header, s); ParseConstants(reader, header, s); ParseUpvalues(reader, header, s); ParseDebug(reader, header, s); }
public LFunction(BHeader header, int[] code, LLocal[] locals, LObject[] constants, LUpvalue[] upvalues, LFunction[] functions, int maximumStackSize, int numUpValues, int numParams, int vararg) { this.header = header; this.code = code; this.locals = locals; this.constants = constants; this.upvalues = upvalues; this.functions = functions; this.maximumStackSize = maximumStackSize; this.numUpvalues = numUpValues; this.numParams = numParams; this.vararg = vararg; }
public override LBoolean Parse(BinaryReaderEx reader, BHeader header) { int value = reader.ReadByte(); if ((value & 0xFFFFFFFE) != 0) { throw new Exception(); } else { return(value == 0 ? LBoolean.LFALSE : LBoolean.LTRUE); } }
public LFunction(BHeader header, int[] code, LLocal[] locals, LObject[] constants, LUpvalue[] upvalues, LFunction[] functions, int maximumStackSize, int numUpvalues, int numParams, int vararg) { Header = header; Code = code; Locals = locals; Constants = constants; Upvalues = upvalues; Functions = functions; MaximumStackSize = maximumStackSize; NumUpvalues = numUpvalues; NumParams = numParams; Vararg = vararg; }
private void FillPage(int index, PHeader pageHeader) { TypeOfPage pageType = pageHeader.pageType; CreatePageHeader(index, pageHeader); BHeader blockHeader = new BHeader(); int blockHeaderIndex = index + PHeader.PAGE_HEADER_SIZE; while (blockHeaderIndex < index + PHeader.PAGE_TOTAL_SIZE) { CreateBlockHeader(blockHeaderIndex, blockHeader); blockHeaderIndex += BHeader.BLOCK_HEADER_SIZE + pageType.Size; } }
private int GetPageFreeBlockIndex(int index) { PHeader pageHeader = GetPageHeader(index); TypeOfPage pageType = pageHeader.pageType; int blockHeaderIndex = index + PHeader.PAGE_HEADER_SIZE; while (blockHeaderIndex < index + PHeader.PAGE_TOTAL_SIZE) { BHeader blockHeader = GetBlockHeader(blockHeaderIndex); if (blockHeader.IsFree) { return(blockHeaderIndex); } blockHeaderIndex += BHeader.BLOCK_HEADER_SIZE + pageType.Size; } return(-1); }
public int MemAllocate(int size) { TypeOfPage pageType = PHeader.GetTypeBySize(size); int pageIndex = 0; int index = -1; while (index == -1 && pageIndex < _size - PHeader.PAGE_HEADER_SIZE) { PHeader pageHeader = GetPageHeader(pageIndex); TypeOfPage currentPageType = pageHeader.pageType; if (currentPageType == pageType) { int freeBlockPosition = GetPageFreeBlockIndex(pageIndex); index = freeBlockPosition >= 0 ? freeBlockPosition : index; } else if (currentPageType == TypeOfPage.EMPTY) { pageHeader.pageType = pageType; FillPage(pageIndex, pageHeader); index = pageIndex + PHeader.PAGE_HEADER_SIZE; } pageIndex += PHeader.PAGE_TOTAL_SIZE; } if (index >= 0) { BHeader blockHeader = GetBlockHeader(index); blockHeader.IsFree = false; CreateBlockHeader(index, blockHeader); } return(index); }
public int MemRealloc(int index, int size) { if (!CheckIndex(index)) { throw new IndexOutOfRangeException(); } BHeader blockHeader = GetBlockHeader(index); blockHeader.IsFree = true; CreateBlockHeader(index, blockHeader); byte[] data = ReadArray(index); int reallocIndex = MemAllocate(size); WriteArray(reallocIndex, data); return(reallocIndex); }
private List <string> DecompileLuac(byte[] data) { data[5] = 0x00; ByteBuffer buffer = new ByteBuffer(data); var header = new BHeader(buffer); LFunction lmain = header.function.parse(buffer, header); decryptcode(lmain); Decompiler d = new Decompiler(lmain); d.decompile(); MemoryStream outs = new MemoryStream(); StreamWriter writer = new StreamWriter(outs); d.print(new Output(writer.Write, writer.WriteLine)); var text = Encoding.UTF8.GetString(outs.ToArray()); return(new List <string>(text.Split('\n'))); }
public string DecompileLuc(Byte[] input, string destfile) { Stream stream = new MemoryStream(input); var header = new BHeader(stream); LFunction lmain = header.Function.Parse(stream, header); Decompiler d = new Decompiler(lmain); d.Decompile(); using (var writer = new StreamWriter(destfile, false, new UTF8Encoding(false))) { d.Print(new Output(writer)); writer.Flush(); } return(null); }
public override LObject Parse(BinaryReaderEx reader, BHeader header) { int type = reader.ReadByte(); switch (type) { case 0: return(LNil.NIL); case 1: return(header.Bool.Parse(reader, header)); case 3: return(header.Number.Parse(reader, header)); case 4: return(header.String.Parse(reader, header)); default: throw new Exception(); } }
public override LNumber Parse(BinaryReaderEx reader, BHeader header) { LNumber value = null; if (Integral) { switch (Size) { case 4: value = new LIntNumber(reader.ReadInt32()); break; case 8: value = new LLongNumber(reader.ReadInt64()); break; } } else { switch (Size) { case 4: value = new LFloatNumber(reader.ReadSingle()); break; case 8: value = new LDoubleNumber(reader.ReadDouble()); break; } } if (value == null) { throw new Exception("The input chunk has an unsupported Lua number format"); } return(value); }
public override void ParseMain(BinaryReaderEx reader, BHeader header, LFunctionParseState s) { s.Name = header.String.Parse(reader, header); s.LineBegin = header.Integer.Parse(reader, header).AsInt(); s.LineEnd = 0; int lenUpvalues = reader.ReadByte(); s.Upvalues = new LUpvalue[lenUpvalues]; for (int i = 0; i < lenUpvalues; i++) { s.Upvalues[i] = new LUpvalue(); } s.LenParameter = reader.ReadByte(); s.Vararg = reader.ReadByte(); s.MaximumStackSize = reader.ReadByte(); ParseDebug(reader, header, s); ParseConstants(reader, header, s); ParseCode(reader, header, s); }
/// <summary> /// Writes the KOM File entry to file. /// </summary> /// <param name="reader">The reader for the kom file.</param> /// <param name="outpath">The output folder for every entry in the kom file.</param> /// <param name="entry">The kom file entry instance.</param> /// <param name="version">The kom file version.</param> /// <param name="xmldata">The crc.xml data to write.</param> /// <param name="kOMFileName">The name of the kom file the entry is from.</param> public static void WriteOutput(BinaryReader reader, string outpath, EntryVer entry, int version, string xmldata, string kOMFileName) { if (reader == null) { throw new ArgumentNullException(nameof(reader)); } if (entry == null) { throw new ArgumentNullException(nameof(entry)); } if (version > 2) { if (!Directory.Exists(outpath)) { Directory.CreateDirectory(outpath); } var xmldatabuffer = Encoding.ASCII.GetBytes(xmldata); if (!File.Exists($"{outpath}{Path.DirectorySeparatorChar}crc.xml")) { using (var fs = File.Create(outpath + Path.DirectorySeparatorChar + "crc.xml")) { fs.Write(xmldatabuffer, 0, xmldatabuffer.Length); } } var entrydata = new byte[entry.CompressedSize]; reader.Read(entrydata, 0, entrydata.Length); if (entry.Algorithm == 0) { using (var entryData = new MemoryStream()) { try { int i = 0; MemoryZlib.Decompress(entrydata, entryData); } catch (ArgumentException ex) { throw new NotUnpackableException("Something failed...", ex); } catch (NotUnpackableException ex) { throw new NotUnpackableException("decompression failed...", ex); } if (entry.Name.EndsWith(".lua", StringComparison.OrdinalIgnoreCase) || entry.Name.EndsWith(".txt", StringComparison.OrdinalIgnoreCase)) { // the particles and the lua files seem to share the same encryption in alg 0. // Decrypt the data from a encryption plugin. if (Encryptionplugins != null && Encryptionplugins.Count > 0) { // only use the first encryption/decryption plugin. Encryptionplugins[0].DecryptEntry(entryData, GetFileBaseName(kOMFileName), entry.Algorithm); } } if (entry.Name.EndsWith(".lua", StringComparison.OrdinalIgnoreCase)) { try { LFunction lMain; using (var ms = new MemoryStream(entryData.ToArray())) { var header = new BHeader(ms); lMain = header.Function.Parse(ms, header); } var d = new Decompiler(lMain); d.Decompile(); entryData.Clear(); using (var writer = new StreamWriter(entryData, Encoding.UTF8)) { d.Print(new Output(writer)); writer.Flush(); } } catch (InvalidOperationException) { // save decrypted data. File.WriteAllBytes($"{outpath}{Path.DirectorySeparatorChar}{entry.Name}", entryData.GetBuffer()); } } else // is particle or any other file. { File.WriteAllBytes($"{outpath}{Path.DirectorySeparatorChar}{entry.Name}", entryData.GetBuffer()); } } } else { if (entry.Algorithm == 2 || entry.Algorithm == 3) { // algorithm 2 and 3 code. var path = $"{outpath}{Path.DirectorySeparatorChar}{entry.Name}"; using (var entryfile = File.Create(path)) using (var entryData = new MemoryStream()) using (var tmpStream = new MemoryStream(entrydata, 0, entrydata.Length, true, true)) { // Decrypt the data from a encryption plugin. if (Encryptionplugins != null && Encryptionplugins.Count > 0) { // only use the first encryption/decryption plugin. Encryptionplugins[0].DecryptEntry(tmpStream, GetFileBaseName(kOMFileName), entry.Algorithm); } try { MemoryZlib.Decompress(tmpStream.GetBuffer(), entryData); } catch (ArgumentException ex) { throw new NotUnpackableException("Something failed...", ex); } catch (NotUnpackableException ex) { throw new NotUnpackableException("decompression failed...", ex); } if (entry.Name.EndsWith(".lua", StringComparison.OrdinalIgnoreCase)) { try { LFunction lMain; using (var ms = new MemoryStream(entryData.ToArray())) { var header = new BHeader(ms); lMain = header.Function.Parse(ms, header); } var d = new Decompiler(lMain); d.Decompile(); entryfile.Close(); entryData.Clear(); using (var writer = new StreamWriter(path, false, new UTF8Encoding(false))) { d.Print(new Output(writer)); writer.Flush(); } } catch (InvalidOperationException) { entryData.CopyTo(entryfile); } } else { entryData.CopyTo(entryfile); } } } } } else { // Write KOM V2 output to file. if (!Directory.Exists(outpath)) { Directory.CreateDirectory(outpath); } var entrydata = reader.ReadBytes((int)entry.CompressedSize); using (var entryfile = File.Create($"{outpath}{Path.DirectorySeparatorChar}{entry.Name}")) using (var entryData = new MemoryStream()) { try { MemoryZlib.Decompress(entrydata, entryData); } catch (NotUnpackableException) { // copyright symbols... Really funny xor key... var xorkey = Encoding.UTF8.GetBytes("\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9\xa9"); // xor this shit then try again... BlowFish.XorBlock(ref entrydata, xorkey); try { entryData.Clear(); MemoryZlib.Decompress(entrydata, entryData); using (File.Create($"{outpath}{Path.DirectorySeparatorChar}XoRNeeded.dummy")) { // dummy comment here. } } catch (NotUnpackableException ex) { throw new NotUnpackableException("failed with zlib decompression of entries.", ex); } } entryData.CopyTo(entryfile); } } }
public override void ParseDebug(BinaryReaderEx reader, BHeader header, LFunctionParseState s) { s.Name = header.String.Parse(reader, header); ParseDebug(reader, header, s); }
private void CreateBlockHeader(int index, BHeader blockHeader) { byte[] blockHeaderByteArray = blockHeader.ToByteArray(); Array.Copy(blockHeaderByteArray, 0, _buffer, index, blockHeaderByteArray.Length); }
public abstract T Parse(BinaryReaderEx reader, BHeader header);
public override BSizeT Parse(BinaryReaderEx reader, BHeader header) => new(_integerType.RawParse(reader, header));