Beispiel #1
0
        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;
        }
Beispiel #2
0
        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));
        }
Beispiel #3
0
        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));
            }
        }
Beispiel #4
0
        public override LUpvalue Parse(BinaryReaderEx reader, BHeader header)
        {
            LUpvalue upvalue = new()
            {
                InStack = reader.ReadByte() != 0,
                Index   = reader.ReadByte()
            };

            return(upvalue);
        }
    }
Beispiel #5
0
        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));
        }
Beispiel #6
0
        public void MemFree(int index)
        {
            if (!CheckIndex(index))
            {
                throw new IndexOutOfRangeException();
            }

            BHeader blockHeader = GetBlockHeader(index);

            blockHeader.IsFree = true;
            CreateBlockHeader(index, blockHeader);
        }
Beispiel #7
0
        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);
        }
Beispiel #8
0
 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;
 }
Beispiel #9
0
        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);
            }
        }
Beispiel #10
0
	  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;
	  }
Beispiel #11
0
 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;
 }
Beispiel #12
0
        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;
            }
        }
Beispiel #13
0
        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);
        }
Beispiel #14
0
        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);
        }
Beispiel #15
0
        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);
        }
Beispiel #16
0
        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')));
        }
Beispiel #17
0
        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);
        }
Beispiel #18
0
        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();
            }
        }
Beispiel #19
0
        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);
        }
Beispiel #20
0
        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);
        }
Beispiel #21
0
        /// <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);
                    }
            }
        }
Beispiel #22
0
        public override void ParseDebug(BinaryReaderEx reader, BHeader header, LFunctionParseState s)
        {
            s.Name = header.String.Parse(reader, header);

            ParseDebug(reader, header, s);
        }
Beispiel #23
0
 private void CreateBlockHeader(int index, BHeader blockHeader)
 {
     byte[] blockHeaderByteArray = blockHeader.ToByteArray();
     Array.Copy(blockHeaderByteArray, 0, _buffer, index, blockHeaderByteArray.Length);
 }
Beispiel #24
0
 public abstract T Parse(BinaryReaderEx reader, BHeader header);
Beispiel #25
0
 public override BSizeT Parse(BinaryReaderEx reader, BHeader header) => new(_integerType.RawParse(reader, header));