private void decryptfile()
        {
            FileStream originalStream = File.OpenRead(path + "Enc_" + filename);
            Blowfish   alg            = new Blowfish(Encoding.Unicode.GetBytes(myKey));

            Byte[] buffer = new byte[originalStream.Length];
            originalStream.Read(buffer, 0, buffer.Length);
            originalStream.Close();
            alg.Decipher(buffer, buffer.Length);
            FileStream stream = new FileStream(path + "Dec_" + filename, FileMode.Create);

            stream.Write(buffer, 0, (int)m_originalLength); //Dangerous casting - Write in chunks.
            stream.Close();
            WebClient    wclient  = new WebClient();
            HttpResponse response = HttpContext.Current.Response;

            response.Clear();
            response.ClearContent();
            response.ClearHeaders();
            response.Buffer = true;
            response.AddHeader("Content-Disposition", "attachment;filename=\"" + filename + "\"");
            byte[] data = wclient.DownloadData(path + "Dec_" + filename);
            File.Delete(path + "Dec_" + filename);
            response.BinaryWrite(data);
            response.End();
        }
示例#2
0
 /// <summary>
 /// Parse certain executable resources for encryption passphrase.
 /// Returns null if no passphrase found.
 /// </summary>
 public static string GetPassFromExe(string filename)
 {
     using (var exe = new ExeFile.ResourceAccessor(filename))
     {
         var code = exe.GetResource("DATA", "V_CODE2");
         if (null == code || code.Length < 8)
         {
             return(null);
         }
         var key = exe.GetResource("KEY", "KEY_CODE");
         if (null != key)
         {
             for (int i = 0; i < key.Length; ++i)
             {
                 key[i] ^= 0xCD;
             }
         }
         else
         {
             key = Encoding.ASCII.GetBytes("windmill");
         }
         var blowfish = new Blowfish(key);
         blowfish.Decipher(code, code.Length / 8 * 8);
         int length = Array.IndexOf <byte> (code, 0);
         if (-1 == length)
         {
             length = code.Length;
         }
         return(Encodings.cp932.GetString(code, 0, length));
     }
 }
示例#3
0
文件: ArcPCK.cs 项目: ziyuejun/GARbro
        public override ArcFile TryOpen(ArcView file)
        {
            if (!file.View.AsciiEqual(4, "_FILE001"))
            {
                return(null);
            }
            int count = file.View.ReadInt32(0xC);

            if (!IsSaneCount(count))
            {
                return(null);
            }
            var key = QueryKey(file.Name);

            if (null == key)
            {
                return(null);
            }
            uint index_length = file.View.ReadUInt32(0x10);
            var  index        = file.View.ReadBytes(0x14, index_length);

            if (index.Length != index_length)
            {
                return(null);
            }
            var bf = new Blowfish(key);

            bf.Decipher(index, index.Length);

            long data_offset = 0x14 + index_length;
            int  pos         = 0;
            var  dir         = new List <Entry> (count);

            for (int i = 0; i < count; ++i)
            {
                uint size = index.ToUInt32(pos);
                pos += 4;
                int name_end = Array.IndexOf <byte> (index, 0, pos);
                if (-1 == name_end)
                {
                    return(null);
                }
                var name = Encodings.cp932.GetString(index, pos, name_end - pos);
                pos = name_end + 1;
                uint enc_size = index.ToUInt32(pos);
                pos += 4;
                var entry = Create <PackedEntry> (name);
                entry.Offset       = data_offset;
                entry.Size         = enc_size;
                entry.UnpackedSize = size;
                entry.IsPacked     = enc_size != size;
                if (!entry.CheckPlacement(file.MaxOffset))
                {
                    return(null);
                }
                dir.Add(entry);
                data_offset += enc_size + 1;
            }
            return(new PckArchive(file, this, dir, key));
        }
示例#4
0
        /// <summary>
        /// Write the data from the supplied stream to this stream.
        /// </summary>
        /// <param name="inStream">The data to write.</param>
        /// <param name="count">The number of bytes to write.</param>
        /// <param name="actualCount">The number of bytes to write.</param>
        /// <param name="encryptionAlgorithm">Key to encrypt the data with.</param>
        /// <param name="EncryptionKey"></param>
        public void Write(Stream inStream, int count, int actualCount, string encryptionAlgorithm, string EncryptionKey)
        {
            int bytesLeft = count;
            int bytesToWrite;

            while (bytesLeft > 0)
            {
                byte[] buffer      = GetBuffer();
                int    bytesRead   = 0;
                int    bytesToRead = Math.Min(buffer.Length, bytesLeft);

                while (bytesToRead != 0)
                {
                    int currentRead = inStream.Read(buffer, bytesRead, bytesToRead);
                    if (currentRead == 0)
                    {
                        break;
                    }
                    bytesRead   += currentRead;
                    bytesToRead -= currentRead;
                }

                if (bytesRead != 0)
                {
                    if (encryptionAlgorithm != "BlowFish")
                    {
                        throw exception;
                    }

//					UTF8Encoding utf8 = new UTF8Encoding();
                    Blowfish bf = new Blowfish(Convert.FromBase64String(EncryptionKey));
                    bf.Decipher(buffer, buffer.Length);

                    //Discard the bytes padded
                    if ((bytesLeft - bytesRead == 0) && (actualCount != count))
                    {
                        bytesToWrite = bytesRead - (count - actualCount);
                    }
                    else
                    {
                        bytesToWrite = bytesRead;
                    }

                    writeComplete.WaitOne();
                    if (exception != null)
                    {
                        throw exception;
                    }
                    stream.BeginWrite(buffer, 0, bytesToWrite, new AsyncCallback(Write_WriteComplete), buffer);
                    bytesLeft -= bytesRead;
                }
                else
                {
                    break;
                }
            }

            writeComplete.WaitOne();
            writeComplete.Set();
        }
示例#5
0
    public override int Read(byte[] buffer, int offset, int count)
    {
        if (_totalIndex == 0)
        {
            _iv   ^= _ivXor;
            _ivXor = 0;
        }

        for (int i = 0; i < count; i++)
        {
            if (_bufferIndex % 8 == 0)
            {
                if (_bufferIndex == 0x100)
                {
                    _iv         ^= _ivXor;
                    _ivXor       = 0;
                    _bufferIndex = 0;
                }

                stream.Read(_buffer, 0, 8);
                ulong nextIV = BitConverter.ToUInt64(_buffer, 0);
                _blowfish.Decipher(_buffer, 8);
                ulong block = BitConverter.ToUInt64(_buffer, 0);
                block  ^= _iv;
                _buffer = BitConverter.GetBytes(block);
                _iv     = nextIV;
            }
            buffer[offset + i] = _buffer[_bufferIndex % 8];
            _bufferIndex++;
            _totalIndex++;
        }
        return(count);
    }
示例#6
0
        private IndexEntry[] ReadHeader(Stream stream, out int body_offset)
        {
            BinaryReader reader = new BinaryReader(stream);
            uint         flags  = (this.version == MixFileVersion.CNC) ? 0 : reader.ReadUInt32();
            int          nfiles = 0;

            IndexEntry[] index;

            // The mix is encrypted.
            if ((flags & FlagEncrypted) != 0)
            {
                // Read the Mix key and convert it to a Blowfish key.
                byte[]   key_source = reader.ReadBytes(80);
                byte[]   key        = new BlowfishKeyProvider().DecryptKey(key_source);
                Blowfish bf         = new Blowfish(key);

                // Parse the header.
                byte[] header_buf = stream.ReadBytes(8);
                bf.Decipher(header_buf, 8);
                this.ParseHeader(header_buf, out nfiles);

                // Parse the index.
                int    index_size = (12 * nfiles + 5) & ~7;
                byte[] index_buf  = stream.ReadBytes(index_size);
                bf.Decipher(index_buf, index_size);
                Array.Copy(index_buf, 0, index_buf, 2, index_size - 2);
                Array.Copy(header_buf, 6, index_buf, 0, 2);
                this.ParseIndex(index_buf, nfiles, out index);
            }
            else
            {
                byte[] header_buf = new byte[6];
                stream.Read(header_buf, 0, 6);
                this.ParseHeader(header_buf, out nfiles);

                byte[] index_buf = new byte[12 * nfiles];
                stream.Read(index_buf, 0, 12 * nfiles);
                this.ParseIndex(index_buf, nfiles, out index);
            }

            body_offset = (int)stream.Position;
            return(index);
        }
示例#7
0
        public override void InitSequence()
        {
            var connect = new LobbyC2SConnect();

            SendPacket(connect, 3);
            Key = new Blowfish(new NetworkKey {
                Time = connect.Time, Seed = connect.Seed
            }.ToArray());

            var encryptedZero = BitConverter.GetBytes(((UInt64)0));

            Key.Decipher(encryptedZero, 0, 8);
            EncryptedZero = BitConverter.ToUInt64(encryptedZero, 0);
        }
示例#8
0
        /// <summary>
        /// Decrypts an encrypted TOS file and returns a byte array for the result.
        /// </summary>
        /// <param name="data"></param>
        public byte[] Decrypt(byte[] data)
        {
            // TODO: Use BSR and remove magic numbers.

            var unencryptedSize = BitConverter.ToInt32(data, 0);
            var encryptedSize   = BitConverter.ToInt32(data, 4);

            _cryptor.Decipher(data, 8, encryptedSize);

            var buffer = new byte[unencryptedSize];

            Buffer.BlockCopy(data, 8, buffer, 0, buffer.Length);
            return(buffer);
        }
示例#9
0
        /// <summary>
        /// Decrypt a buffer containing MH4U DLC
        /// </summary>
        /// <param name="buffer"></param>
        /// <returns>Decrypted DLC</returns>
        public byte[] Decrypt(byte[] buffer)
        {
            _cipher = new Blowfish(Key);
            var b = new byte[8];

            //var hash = new byte[20];
            using (var m = new MemoryStream(buffer, true))
            {
                while (m.Position < m.Length - 4) //0x1c //4 //28=24+4
                {
                    //Endian swap 2 sets of 4 bytes
                    for (int i = 3; i >= 0; i--)
                    {
                        b[i] = (byte)m.ReadByte();
                    }
                    for (int i = 7; i >= 4; i--)
                    {
                        b[i] = (byte)m.ReadByte();
                    }
                    //Decrypt the 8 bytes
                    _cipher.Decipher(b, 8);
                    //Reset stream position to prepare for writing.
                    m.Position -= 8;
                    //Endian swap 4 bytes twice
                    for (int i = 3; i >= 0; i--)
                    {
                        m.WriteByte(b[i]);
                    }
                    for (int i = 7; i >= 4; i--)
                    {
                        m.WriteByte(b[i]);
                    }
                }
                //m.Position -= 24;
                ////capture sh1 hash
                //m.Read(hash, 0, 20);
                //var sh1 = System.Security.Cryptography.SHA1.Create(); sh1.ComputeHash(buffer, 0, buffer.Length - 28);
                //if (!sh1.Hash.SequenceEqual(hash))
                //{
                //    MessageBox.Show("Invalid SHA1 hash in footer.");
                //    return;
                //}
            }

            //Trim the hash (24) and other useless data (4) by cloning into a new array.
            return(StripJunk(buffer));
        }
示例#10
0
        private byte[] FindKey(BinReader reader, TellTaleFileStructureInfo fileInfo, IEnumerable <TellTaleKeyInfo> keys)
        {
            const int decompressSize = 4;
            const int readSize       = 4096;

            byte[] readBytes    = new byte[readSize];
            byte[] testBytes    = new byte[readSize];
            byte[] deflateBytes = new byte[decompressSize];
            reader.Position = fileInfo.VirtualBlocksOffset;
            reader.Read(readBytes, 0, readSize);

            using (MemoryStream stream = new MemoryStream(testBytes))
            {
                foreach (var info in keys)
                {
                    var testBlowfish = new Blowfish(info.Key, true);
                    testBlowfish.Decipher(readBytes, testBytes, readSize);

                    stream.Position = 0;
                    using (DeflateStream deflateStream = new DeflateStream(stream, CompressionMode.Decompress, true))
                    {
                        try
                        {
                            int bytesRead = 0;
                            // FIXME: Sometimes DeflateStream.Read reads 0 bytes...
                            while (bytesRead == 0)
                            {
                                bytesRead = deflateStream.Read(deflateBytes, 0, decompressSize);
                            }
                        }
                        catch (InvalidDataException)
                        {
                            // Since a wrong key may cause invalid zlib input,
                            // we catch the exception for that, and continue to the next key
                            continue;
                        }
                    }
                    if (deflateBytes[0] == '3' && deflateBytes[1] == 'A' && deflateBytes[2] == 'T' &&
                        deflateBytes[3] == 'T')
                    {
                        return(info.Key);
                    }
                }
            }
            return(null);
        }
示例#11
0
文件: ArcINT.cs 项目: ziyuejun/GARbro
        private ArcFile OpenEncrypted(ArcView file, int entry_count, uint main_key)
        {
            if (1 == entry_count)
            {
                return(null); // empty archive
            }
            long current_offset = 8;

            uint seed    = file.View.ReadUInt32(current_offset + 0x44);
            var  twister = new MersenneTwister(seed);

            byte[] blowfish_key = BitConverter.GetBytes(twister.Rand());
            if (!BitConverter.IsLittleEndian)
            {
                Array.Reverse(blowfish_key);
            }

            var blowfish = new Blowfish(blowfish_key);
            var dir      = new List <Entry> (entry_count - 1);

            byte[] name_buffer = new byte[0x40];
            for (int i = 1; i < entry_count; ++i)
            {
                current_offset += 0x48;
                file.View.Read(current_offset, name_buffer, 0, 0x40);
                uint offset = file.View.ReadUInt32(current_offset + 0x40) + (uint)i;
                uint size   = file.View.ReadUInt32(current_offset + 0x44);
                blowfish.Decipher(ref offset, ref size);
                twister.SRand(main_key + (uint)i);
                uint   name_key = twister.Rand();
                string name     = DecipherName(name_buffer, name_key);

                var entry = FormatCatalog.Instance.Create <Entry> (name);
                entry.Offset = offset;
                entry.Size   = size;
                if (!entry.CheckPlacement(file.MaxOffset))
                {
                    return(null);
                }
                dir.Add(entry);
            }
            return(new FrontwingArchive(file, this, dir, blowfish));
        }
示例#12
0
        internal static byte[] Cipher(byte[] buffer, ref byte[] key, bool decrypt)
        {
            var cipher = new Blowfish(key);
            var b      = new byte[8];

            using (var m = new MemoryStream(buffer, true))
            {
                while (m.Position < m.Length)
                {
                    //Endian swap 2 sets of 4 bytes
                    for (int i = 3; i >= 0; i--)
                    {
                        b[i] = (byte)m.ReadByte();
                    }
                    for (int i = 7; i >= 4; i--)
                    {
                        b[i] = (byte)m.ReadByte();
                    }
                    //cipher the 8 bytes
                    if (decrypt)
                    {
                        cipher.Decipher(b, 8);
                    }
                    else
                    {
                        cipher.Encipher(b, 8);
                    }
                    //Reset stream position to prepare for writing.
                    m.Position -= 8;
                    //Endian swap 4 bytes twice
                    for (int i = 3; i >= 0; i--)
                    {
                        m.WriteByte(b[i]);
                    }
                    for (int i = 7; i >= 4; i--)
                    {
                        m.WriteByte(b[i]);
                    }
                }
            }
            return(buffer);
        }
示例#13
0
        /// <summary>
        /// Parse certain executable resources for encryption passphrase.
        /// Returns null if no passphrase found.
        /// </summary>
        public static string GetPassFromExe(string filename)
        {
            var exe = NativeMethods.LoadLibraryEx(filename, IntPtr.Zero, 0x20);  // LOAD_LIBRARY_AS_IMAGE_RESOURCE

            if (IntPtr.Zero == exe)
            {
                throw new Win32Exception(Marshal.GetLastWin32Error());
            }
            try
            {
                var code = GetResource(exe, "DATA", "V_CODE2");
                if (null == code || code.Length < 8)
                {
                    return(null);
                }
                var key = GetResource(exe, "KEY", "KEY_CODE");
                if (null != key)
                {
                    for (int i = 0; i < key.Length; ++i)
                    {
                        key[i] ^= 0xCD;
                    }
                }
                else
                {
                    key = Encoding.ASCII.GetBytes("windmill");
                }
                var blowfish = new Blowfish(key);
                blowfish.Decipher(code, code.Length / 8 * 8);
                int length = Array.IndexOf <byte> (code, 0);
                if (-1 == length)
                {
                    length = code.Length;
                }
                return(Encodings.cp932.GetString(code, 0, length));
            }
            finally
            {
                NativeMethods.FreeLibrary(exe);
            }
        }
示例#14
0
        public static PacketResult Process(BinaryReader reader, Blowfish blowfish, out SubPacket subPacket)
        {
            subPacket = null;
            Header header = Header.UnMarshal(reader);

            // not enough data to cover length specified in header
            if (reader.BaseStream.Length - reader.BaseStream.Position < header.Size - Header.Length)
            {
                return(PacketResult.Malformed);
            }

            byte[] payload = reader.ReadBytes((int)(header.Size - Header.Length));

            if (header.Type != SubPacketType.KeepAliveRequest && header.Type != SubPacketType.KeepAliveResponse)
            {
                blowfish?.Decipher(payload, 0, payload.Length);
            }

            using (var stream = new MemoryStream(payload))
            {
                using (var subReader = new BinaryReader(stream))
                {
                    MessageHeader messageHeader = new MessageHeader();
                    if (header.Type == SubPacketType.Message)
                    {
                        messageHeader = MessageHeader.UnMarshal(subReader);

                        Array.Copy(payload, MessageHeader.Length, payload, 0, payload.Length - MessageHeader.Length);
                        Array.Resize(ref payload, payload.Length - (int)MessageHeader.Length);
                        stream.Position = 0L;
                    }

                    subPacket = PacketManager.GetSubPacket(header.Type, (SubPacketClientOpcode)messageHeader.Opcode, SubPacketServerOpcode.None) ?? new SubPacket();
                    subPacket.Initialise(header, messageHeader);
                    subPacket.Read(subReader);
                }
            }

            return(PacketResult.Ok);
        }
示例#15
0
        static void Main(string[] args)
        {
            int    exit = 1;
            string value;
            string key = "{123ABC9F-AFBC-36DC-8FF8-00BDAFF1584DGFQQ}";
            string encrypted;
            string decipher;

            do
            {
                Console.Clear();
                Console.WriteLine("Input value:    ");
                value = Convert.ToString(Console.ReadLine());
                Blowfish blowfish = new Blowfish(key);
                encrypted = blowfish.Encipher(value);
                Console.WriteLine("Encrypted value:     " + encrypted);
                decipher = blowfish.Decipher(encrypted);
                Console.WriteLine("Decipher value:     " + decipher);
                Console.WriteLine("Input 0 to exit:    ");
                exit = Convert.ToInt32(Console.ReadLine());
            }while (exit != 0);
        }
示例#16
0
        private static byte[] DetermineKeyByInfoTable(BinReader reader, TellTaleFileStructureInfo fileInfo, IEnumerable <TellTaleKeyInfo> keys)
        {
            byte[] encryptedTable = fileInfo.ReadInfoBlock(reader, null);
            byte[] decryptedTable = new byte[encryptedTable.Length];

            foreach (var info in keys)
            {
                var blowfish = new Blowfish(info.Key, fileInfo.FileVersion >= 7);
                blowfish.Decipher(encryptedTable, decryptedTable, (uint)(encryptedTable.Length / 8) * 8);

                // Now we do our assertions which should be true if the key was right:
                using (MemoryStream infoStream = new MemoryStream(decryptedTable))
                {
                    using (var infoReader = new BinReader(infoStream))
                    {
                        uint folderCount = infoReader.ReadU32LE();
                        // The maximum number of folders is somewhat arbitrary.
                        // In games tested, I haven't seen folder counts this high.
                        if (folderCount > 128)
                        {
                            Trace.TraceInformation("Key check - folder count: {0}", folderCount);
                            continue;
                        }

                        // We just check the first folder:
                        uint nameSize = infoReader.ReadU32LE();
                        if (nameSize > 300)
                        {
                            Trace.TraceInformation("Key check - folder name size: {0}", nameSize);
                            continue;
                        }

                        return(info.Key);
                    }
                }
            }

            return(null);
        }
        public static string Decrypt3(string cipherText, string encryptionKey1, string encryptionKey2, out Exception exData)
        {
            exData = null;
            try
            {
                var mainKey = encryptionKey1 + encryptionKey2;

                var blowFish = new Blowfish(mainKey);

                return(blowFish.Decipher(cipherText));
            }
            catch (Exception ex)
            {
                if (InnerExceptionList == null)
                {
                    InnerExceptionList = new List <Exception>();
                }

                InnerExceptionList.Add(ex);
                exData = ex;
                return("NULL");
            }
        }
示例#18
0
        public override ArcFile TryOpen(ArcView file)
        {
            int version;

            if (file.View.AsciiEqual(4, "1.00"))
            {
                version = 100;
            }
            else if (file.View.AsciiEqual(4, "1.10"))
            {
                version = 110;
            }
            else
            {
                return(null);
            }
            int count = file.View.ReadInt32(0x14);

            if (!IsSaneCount(count))
            {
                return(null);
            }

            int  bucket_count = file.View.ReadInt32(0x18);
            uint index_size   = file.View.ReadUInt32(0x1C);
            uint arc_seed     = file.View.ReadUInt32(0x20);
            long index_offset = version >= 110 ? 0x2C : 0x24;
            long base_offset  = index_offset + index_size;
            var  blowfish     = new Blowfish(IndexKey);
            var  packed_bytes = file.View.ReadBytes(index_offset, index_size);

            blowfish.Decipher(packed_bytes, packed_bytes.Length & ~7);

            using (var input = new MemoryStream(packed_bytes))
                using (var unpacked = new ZLibStream(input, CompressionMode.Decompress))
                    using (var index = new BinaryReader(unpacked))
                    {
                        var file_map  = BuildFileNameMap(arc_seed);
                        var dir_table = new List <TacBucket> (bucket_count);
                        for (int i = 0; i < bucket_count; ++i)
                        {
                            var entry = new TacBucket();
                            entry.Hash  = index.ReadUInt16();
                            entry.Count = index.ReadUInt16();
                            entry.Index = index.ReadInt32();
                            dir_table.Add(entry);
                        }
                        var dir = new List <Entry> (count);
                        for (int i = 0; i < count; ++i)
                        {
                            var entry = new TacEntry();
                            entry.Hash         = index.ReadUInt64();
                            entry.IsPacked     = index.ReadInt32() != 0;
                            entry.UnpackedSize = index.ReadUInt32();
                            entry.Offset       = base_offset + index.ReadUInt32();
                            entry.Size         = index.ReadUInt32();
                            if (!entry.CheckPlacement(file.MaxOffset))
                            {
                                return(null);
                            }
                            dir.Add(entry);
                        }
                        var buffer = new byte[8];
                        foreach (var bucket in dir_table)
                        {
                            for (int i = 0; i < bucket.Count; ++i)
                            {
                                var entry = dir[bucket.Index + i] as TacEntry;
                                entry.Hash = entry.Hash << 16 | bucket.Hash;
                                bool known_name = file_map.ContainsKey(entry.Hash);
                                if (known_name)
                                {
                                    entry.Name = file_map[entry.Hash];
                                    entry.Type = FormatCatalog.Instance.GetTypeFromName(entry.Name);
                                }
                                else
                                {
                                    entry.Name = string.Format("{0:X16}", entry.Hash);
                                }
                                if (entry.IsPacked)
                                {
                                    continue;
                                }
                                entry.Key = Encoding.ASCII.GetBytes(string.Format("{0}_tlib_secure_", entry.Hash));
                                if (!known_name)
                                {
                                    var bf = new Blowfish(entry.Key);
                                    file.View.Read(entry.Offset, buffer, 0, 8);
                                    bf.Decipher(buffer, 8);
                                    var res = AutoEntry.DetectFileType(buffer.ToUInt32(0));
                                    if (res != null)
                                    {
                                        entry.ChangeType(res);
                                    }
                                }
                                if ("image" == entry.Type)
                                {
                                    entry.EncryptedSize = Math.Min(10240, entry.Size);
                                }
                                else
                                {
                                    entry.EncryptedSize = entry.Size;
                                }
                            }
                        }
                        return(new ArcFile(file, this, dir));
                    }
        }
示例#19
0
        public void DecryptString()
        {
            Blowfish blowfish = new Blowfish(salt);

            Assert.AreEqual(blowfish.Decipher(encrypted), value);
        }
示例#20
0
文件: MIX.cs 项目: johnson2heng/cncpp
        protected override bool ReadFile(BinaryReader r)
        {
            source = r;
            var length = (int)r.BaseStream.Length;

            this.FileLength = (uint)length;

            if (length < 10)
            {
                ParseError("File length too short to contain file header.");
                return(false);
            }

            var fileBytes = r.ReadBytes((int)length);

            UInt32 flags = BitConverter.ToUInt32(fileBytes, 0);

            if ((flags & 0x0000FFFF) != 0)
            {
                var s = new ArraySegment <byte>(fileBytes, 0, 6);
                if (!Header.ReadFile(s))
                {
                    ParseError("Failed to read file header (old style).");
                    return(false);
                }

                var headLen = Header.FileCount * 12;
                if (length < (6 + headLen))
                {
                    ParseError("File length too short to contain entry headers.");
                    return(false);
                }

                HeadLength  = (uint)(6 + headLen);
                headerBytes = new byte[HeadLength];
                Buffer.BlockCopy(fileBytes, 0, headerBytes, 0, (int)HeadLength);
            }
            else
            {
                if ((flags & (uint)MIXFlags.HasChecksum) != 0)
                {
                    Flags |= MIXFlags.HasChecksum;
                }
                if ((flags & (uint)MIXFlags.HasEncryption) != 0)
                {
                    Flags |= MIXFlags.HasEncryption;
                }

                if (Flags.HasFlag(MIXFlags.HasEncryption))
                {
                    // uh oh

                    var key80 = fileBytes.Skip(4).Take(80).ToArray();
                    var key56 = new byte[56];
                    MIX_Magic.get_blowfish_key(key80, ref key56);

                    var bf     = new Blowfish(key56);
                    var header = fileBytes.Skip(84).Take(8).ToArray();
                    bf.Decipher(header, 8);
                    var s = new ArraySegment <byte>(header, 0, 6);
                    if (!Header.ReadFile(s))
                    {
                        ParseError("Failed to read file header (encrypted style, yo).");
                        return(false);
                    }

                    var hSize = Header.FileCount * 12 + 6;
                    hSize += 8 - (hSize % 8);
                    var blockCount = hSize >> 3;
                    HeadLength = (uint)(84 + hSize);

                    if (length < (84 + hSize))
                    {
                        ParseError("File length too short to contain entry headers.");
                        return(false);
                    }

                    var decoded = new byte[hSize];
                    Buffer.BlockCopy(header, 0, decoded, 0, 8);

                    --blockCount;

                    var encoded = new byte[blockCount * 8];
                    Buffer.BlockCopy(fileBytes, 92, encoded, 0, blockCount * 8);
                    for (var i = 0; i < blockCount; ++i)
                    {
                        bf.Decipher(encoded, 8, i * 8);
                    }
                    Buffer.BlockCopy(encoded, 0, decoded, 8, blockCount * 8);

                    headerBytes = decoded;
                }
                else
                {
                    var s = new ArraySegment <byte>(fileBytes, 4, 6);
                    if (!Header.ReadFile(s))
                    {
                        ParseError("Failed to read file header (new style).");
                        return(false);
                    }

                    var headLen = Header.FileCount * 12;
                    if (length < (10 + headLen))
                    {
                        ParseError("File length too short to contain entry headers.");
                        return(false);
                    }

                    HeadLength  = (uint)(10 + headLen);
                    headerBytes = new byte[HeadLength - 4];
                    Buffer.BlockCopy(fileBytes, 4, headerBytes, 0, (int)HeadLength - 4);
                }
            }
            if (!ReadEntryHeaders())
            {
                ParseError("Failed to read entry headers.");
                return(false);
            }

            ParseLMD();

            return(true);
        }
示例#21
0
        public void HandlePacket(Boolean hack = false)
        {
            //try
            {
                var packetBytes = ReadPacket();
                var offset      = 0;
                while (offset < packetBytes.Length - 3)
                //for (int i = 0; i < messageCount; i++)
                {
                    var messageLength = BitConverter.ToInt32(packetBytes, offset);
                    var source        = BitConverter.ToUInt32(packetBytes, offset + 4);
                    var dest          = BitConverter.ToUInt32(packetBytes, offset + 8);
                    var packetType    = (PacketId)BitConverter.ToUInt32(packetBytes, offset + 12);
                    //var messageBytes = packetBytes.Skip(offset + 12).Take(messageLength - 12).ToArray();
                    var messageBytes     = packetBytes.Skip(offset).Take(messageLength).ToArray();
                    var origMessageBytes = messageBytes.ToList().ToArray();
                    var origpacketType   = packetType;
                    var packetHandler    = PacketHandler;
                    if ((packetType == PacketId.Opcode || packetType == PacketId.LobbyS2CAuth))
                    {
                        if (GetType() == typeof(LobbyClient))
                        {
                            Key.Decipher(messageBytes, 4 + 12, messageBytes.Length - 8 - 16);
                        }
                        if (packetType == PacketId.Opcode)
                        {
                            packetHandler = OpcodeHandler;
                        }
                        if (packetType != PacketId.LobbyS2CAuth)
                        {
                            messageBytes = messageBytes.Skip(4 + 12).ToArray();
                            packetType   = (PacketId)BitConverter.ToUInt32(messageBytes, 2);
                        }
                    }
                    var data = BitConverter.ToString(messageBytes);
                    if (!packetHandler.ContainsKey((UInt32)packetType))
                    {
                        Console.WriteLine("unk packet : " + GetType().Name + " : " + packetType.ToString("X") + " : " + BitConverter.ToString(messageBytes));
                    }
                    else
                    {
                        var method = packetHandler[(UInt32)packetType];
                        if (method != null)
                        {
                            var packetName = PacketHeaderEnum.AssemblyQualifiedName.Replace(PacketHeaderEnum.Name, method.Name);
                            if (Debug)
                            {
                                Console.WriteLine("s " + GetType().Name + " : " + Type.GetType(packetName).Name);
                            }
                            Packet packet = (Packet)Activator.CreateInstance(Type.GetType(packetName));
                            packet.Bytes  = messageBytes;
                            packet.Source = source;
                            if (waitingForPacket != null && waitingForPacket(packet))
                            {
                                waitingForPacket = null;
                            }

                            //var t = new Thread(() =>
                            {
                                method.Invoke(this, new object[] { packet });
                            }
                            //);
                            //t.IsBackground = false;
                            //t.Start();
                        }
                        else
                        {
                            Console.WriteLine("no method s " + GetType().Name + " : " + (WorldOpcode)packetType + " : " + packetType.ToString("X") + " : " + BitConverter.ToString(messageBytes));
                        }
                    }
                    offset += messageLength;
                }
            }
            //catch (Exception e)
            {
                //     Console.WriteLine(e.Message);
            }
        }