Ejemplo n.º 1
0
        public void Encrypt(IFileDataWrapper data, byte xorByte = 0x56)
        {
            data.XOR(0, data.Size, xorByte);

            if (_encrypterData.FixFirstByte)
            {
                byte firstByte;
                if (_encrypterData.FirstByteXOR.HasValue)
                {
                    firstByte = (byte)(xorByte ^ _encrypterData.FirstByteXOR.Value);
                }
                else
                {
                    firstByte = xorByte;
                }
                data.PutByte(0, firstByte);
            }

            if (_encrypterData.BaseByteXOR.HasValue)
            {
                xorByte = (byte)(xorByte ^ _encrypterData.BaseByteXOR.Value);
            }

            int baseByteOffset = _encrypterData.BaseByteOffset < 0 ? data.Size + _encrypterData.BaseByteOffset : _encrypterData.BaseByteOffset;

            data.PutByte(baseByteOffset, xorByte);
        }
Ejemplo n.º 2
0
        public byte Decrypt(IFileDataWrapper data)
        {
            int  baseByteOffset = _encrypterData.BaseByteOffset < 0 ? data.Size + _encrypterData.BaseByteOffset : _encrypterData.BaseByteOffset;
            byte xorByte        = data.GetByte(baseByteOffset);

            if (_encrypterData.BaseByteXOR.HasValue)
            {
                xorByte = (byte)(xorByte ^ _encrypterData.BaseByteXOR.Value);
            }

            if (_encrypterData.FixFirstByte)
            {
                byte firstByte;
                if (_encrypterData.FirstByteXOR.HasValue)
                {
                    firstByte = (byte)(xorByte ^ _encrypterData.FirstByteXOR.Value);
                }
                else
                {
                    firstByte = xorByte;
                }
                data.PutByte(0, firstByte);
            }

            data.XOR(0, data.Size, xorByte);

            return(xorByte);
        }
Ejemplo n.º 3
0
        private void ExtractOriginalData(string gameDirectory, string workingDirectory, string file)
        {
            string sourceFile      = Path.Combine(gameDirectory, file);
            string targetDirectory = Path.Combine(workingDirectory, Path.GetFileName(file) + ".extracted");
            string infoDirectory   = Path.Combine(workingDirectory, Path.GetFileName(file) + ".info");

            using (IFileDataWrapper data = StreamFileDataWrapper.FromFile(sourceFile))
            {
                ArchiveExtractor archiveExtractor = new ArchiveExtractor(targetDirectory, infoDirectory, data);
                archiveExtractor.Unpack();
            }
        }
        public ArchiveExtractor(string baseDirectory, string infoDirectory, IFileDataWrapper data)
        {
            this._baseDirectory = baseDirectory;
            this._infoDirectory = infoDirectory;
            this._data          = data;

            string id = _data.GetString(3);

            if (id != "XP3")
            {
                throw new InvalidDataException("Invalid archive format");
            }
            _data.GoTo(0);
        }
        public void Unpack()
        {
            if (Directory.Exists(_baseDirectory))
            {
                Directory.Delete(_baseDirectory, true);
            }

            _data.GoTo(0x20);
            int offset = _data.GetInt();

            _data.GoTo(offset);

            byte zip   = _data.GetByte();
            int  zSize = _data.GetLong();
            int  size  = _data.GetLong();

            offset = _data.Location;
            using (IFileDataWrapper archive = zip != 0 ? _data.GetCompressedData(offset, zSize, size) : _data.GetData(offset, zSize))
                Extract(archive, archive.Size, string.Empty);
        }
        private void Extract(IFileDataWrapper archive, int chunkSize, string name)
        {
            int chunkOffset = archive.Location;
            int chunkLimit  = chunkOffset + chunkSize;

            while (chunkOffset != chunkLimit)
            {
                string chunkType = archive.GetString(4);
                chunkSize = archive.GetLong();
                int location = archive.Location;
                switch (chunkType)
                {
                case "File":
                    Extract(archive, chunkSize, name);
                    break;

                case "neko":
                case "eliF":
                    int   adlr   = archive.GetInt();
                    short namesz = archive.GetShort();

                    if (namesz <= 0x100)
                    {
                        name = archive.GetUnicodeString(namesz);
                    }
                    else
                    {
                        archive.GetUnicodeString(namesz);
                    }

                    break;

                case "adlr":
                    if (!string.IsNullOrEmpty(name))
                    {
                        WriteToFile(Path.Combine(_infoDirectory, name + ".crc"), archive.GetBytes(sizeof(int)));
                    }
                    else
                    {
                        archive.GetInt();
                    }
                    break;

                case "time":
                    int timestamp = archive.GetLong();
                    break;

                case "segm":
                    int zip    = archive.GetInt();
                    int offset = archive.GetLong();
                    int size   = archive.GetLong();
                    int zSize  = archive.GetLong();

                    using (IFileDataWrapper segment = zip != 0 ? _data.GetCompressedData(offset, zSize, size) : _data.GetData(offset, zSize))
                        if (!string.IsNullOrEmpty(name))
                        {
                            string targetFile = Path.Combine(_baseDirectory, name);
                            byte   key        = 0;
                            if (!name.EndsWith(".ini"))
                            {
                                key = Encrypter.ForFile(name).Decrypt(segment);
                            }
                            WriteToFile(targetFile, segment.Bytes);

                            string keyFile = Path.Combine(_infoDirectory, name + ".key");
                            WriteToFile(keyFile, new[] { key });

                            if (zip != 0)
                            {
                                using (File.Create(Path.Combine(_infoDirectory, name + ".zip")));
                            }
                        }
                    break;

                case "info":
                    if (!string.IsNullOrEmpty(name))
                    {
                        string infoFile = Path.Combine(_infoDirectory, name);
                        Directory.CreateDirectory(Path.GetDirectoryName(infoFile));
                        WriteToFile(infoFile, archive.GetBytes(chunkSize));
                    }
                    break;
                }
                chunkOffset = location + chunkSize;
                archive.GoTo(chunkOffset);
            }
        }