예제 #1
0
        public static byte[] Decrypt(byte[] src, WZClient client)
        {
            byte[] ret   = Array.Empty <byte>();
            var    bsize = client.BlockSize / 8;

            if (src.Length % bsize == 1)
            {
                var paddingSize = src[src.Length - 1];
                var outLength   = src.Length - paddingSize - 1;

                using (var ms = new MemoryStream(src, 0, src.Length - 1))
                {
                    var cs = new CryptoStream(ms, client.CreateDecryptor(), CryptoStreamMode.Read);
                    using (var br = new BinaryReader(cs))
                    {
                        ret = br.ReadBytes(outLength);
                    }
                }

                //Logger.Debug("Input Buffer {0}, Output Buffer {1}", string.Join("",src.Select(x => x.ToString("X2"))), string.Join("", ret.Select(x => x.ToString("X2"))));
            }
            else
            {
                Logger.Error("Can't decode stream, data size:{1} remainder:{0}", src.Length % bsize, src.Length);
            }

            return(ret);
        }
예제 #2
0
        public virtual void OnDisconnect(WZClient session)
        {
            Logger.Information($"Client at Index {session.ID} closed");
            var element = _clients.FirstOrDefault(c => c.Value == session);

            _clients.Remove(element.Key);
        }
예제 #3
0
        public static void Encrypt(MemoryStream dest, MemoryStream src, WZClient client)
        {
            var  destPos     = dest.Position;
            var  dataLen     = (src.Length - src.Position);
            var  r           = (byte)(dataLen % 16);
            byte paddingSize = 0;

            if (r != 0)
            {
                paddingSize = (byte)(16 - r);
            }

            var tmp = new byte[dataLen + paddingSize];

            src.Read(tmp, 0, (int)dataLen);

            dest.Seek(destPos, SeekOrigin.Begin);
            var cs = new CryptoStream(dest, client.CreateEncryptor(), CryptoStreamMode.Write);

            cs.Write(tmp, 0, tmp.Length);
            dest.WriteByte(paddingSize);
            dest.Seek(0, SeekOrigin.Begin);
        }
예제 #4
0
 protected virtual void OnConnect(WZClient session)
 {
 }
예제 #5
0
파일: WZServer.cs 프로젝트: fos83/MuEmu
 public byte[] Encode(object message, ref short serial, WZClient client) => _encoder.Encode(message, ref serial, client);
예제 #6
0
파일: Packet.cs 프로젝트: fos83/MuEmu
        public byte[] Encode(object message, ref short serial, WZClient client)
        {
            MessageFactory factory = null;

            try
            {
                factory = _factories.First(f => f.ContainsType(message.GetType()));
            }catch (Exception ex)
            {
                throw new Exception("Unregisted message " + message.GetType().ToString(), ex);
            }

            ushort opCode = factory.GetOpCode(message.GetType());

            var att = message
                      .GetType()
                      .GetCustomAttributes(false)
                      .Where(x => x.GetType() == typeof(WZContractAttribute))
                      .FirstOrDefault() as WZContractAttribute;

            if (att == null)
            {
                throw new InvalidOperationException("Invalid message format");
            }

            byte[] res;

            using (var data = new MemoryStream())
            {
                var opCodeSize = (opCode & 0xFF00) == 0xFF00 ? 1 : 2;
                if (att.LongMessage)
                {
                    Serializer.Serialize(data, new WZWPacket(0xC2, (ushort)data.Length, opCode));
                }
                else
                {
                    Serializer.Serialize(data, new WZBPacket(0xC1, (byte)data.Length, opCode));
                }

                var dataStart = (att.LongMessage ? 3 : 2) + opCodeSize;
                data.Position = dataStart;
                Serializer.Serialize(data, message);

                data.Position = dataStart;
                if (att.ExtraEncode != null)
                {
                    var encoder = (IExtraEncoder)Activator.CreateInstance(att.ExtraEncode);
                    encoder.Encoder(data);
                }

                if (att.Serialized)
                {
                    data.Position = (att.LongMessage ? 3 : 2);
                    if (_packetRijndael == true)
                    {
                        PacketEncrypt.Encrypt(data, data, client);
                        //PacketPrint(data);
                    }
                    else
                    {
                        SimpleModulus.Encrypt(data, (byte)serial, data);
                    }

                    serial++;
                    data.Position = 0;
                    data.WriteByte((byte)(att.LongMessage ? 0xC4 : 0xC3));
                }

                data.Position = 1;
                if (att.LongMessage)
                {
                    data.Write(BitConverter.GetBytes(((ushort)data.Length).ShufleEnding()), 0, 2);
                }
                else
                {
                    data.Write(BitConverter.GetBytes((byte)data.Length), 0, 1);
                }
                res = data.ToArray();
                return(res);
            }
        }
예제 #7
0
파일: Packet.cs 프로젝트: fos83/MuEmu
        public int Decode(MemoryStream rawPacket, out short serial, List <object> messages, WZClient client)
        {
            using (var decPacket = new MemoryStream())
                using (var posPacket = new MemoryStream())
                {
                    //var type = rawPacket[0];
                    var    type = (byte)rawPacket.ReadByte();
                    ushort size = 0;
                    serial = -1;

                    if (type == 0xC1 || type == 0xC3)
                    {
                        size = (ushort)rawPacket.ReadByte();
                    }
                    else if (type == 0xC2 || type == 0xC4)
                    {
                        size = (ushort)((rawPacket.ReadByte() << 8) | rawPacket.ReadByte());
                    }
                    else
                    {
                        throw new InvalidProgramException($"Invalid packet type {type:X2}");
                    }

                    // Packet Encrypted
                    byte[] tmp;
                    byte[] dec;
                    switch (type)
                    {
                    case 0xC1:
                        decPacket.WriteByte(type);
                        decPacket.WriteByte((byte)size);
                        tmp = new byte[size - 2];
                        rawPacket.Read(tmp, 0, tmp.Length);
                        decPacket.Write(tmp, 0, tmp.Length);
                        break;

                    case 0xC2:
                        decPacket.WriteByte(type);
                        decPacket.WriteByte((byte)((size >> 8) & 0xff));
                        decPacket.WriteByte((byte)(size & 0xff));
                        tmp = new byte[size - 3];
                        rawPacket.Read(tmp, 0, tmp.Length);
                        decPacket.Write(tmp, 0, tmp.Length);
                        break;

                    case 0xC3:
                        tmp = new byte[size - 2];
                        rawPacket.Read(tmp, 0, tmp.Length);

                        if (_packetRijndael)
                        {
                            dec = PacketEncrypt.Decrypt(tmp, client);
                            if (dec.Length == 0)
                            {
                                return(size);
                            }

                            decPacket.WriteByte(0xC1);
                            decPacket.WriteByte((byte)(dec.Length + 2));
                            decPacket.Write(dec, 0, dec.Length);
                        }
                        else
                        {
                            dec    = SimpleModulus.Decoder(tmp);
                            serial = dec[0];
                            decPacket.WriteByte(0xC1);
                            decPacket.WriteByte((byte)(dec.Length + 1));
                            decPacket.Write(dec, 1, dec.Length - 1);
                        }
                        break;

                    case 0xC4:
                        tmp = new byte[size - 3];
                        rawPacket.Read(tmp, 0, tmp.Length);

                        if (_packetRijndael)
                        {
                            dec = PacketEncrypt.Decrypt(tmp, client);
                            if (dec.Length == 0)
                            {
                                return(size);
                            }

                            decPacket.WriteByte(0xC2);
                            decPacket.WriteByte((byte)((dec.Length + 3) >> 8));
                            decPacket.WriteByte((byte)((dec.Length + 3) & 255));
                            decPacket.Write(dec, 0, dec.Length);
                        }
                        else
                        {
                            dec    = SimpleModulus.Decoder(tmp);
                            serial = dec[0];
                            decPacket.WriteByte(0xC2);
                            decPacket.WriteByte((byte)((dec.Length + 2) >> 8));
                            decPacket.WriteByte((byte)((dec.Length + 2) & 255));
                            decPacket.Write(dec, 1, dec.Length - 1);
                        }
                        break;
                    }

                    using (var spe = new StreamPacketEngine(_packetRijndael))
                    {
                        spe.AddData(decPacket.ToArray());
                        var posProcess = spe.ExtractPacket();
                        posPacket.Write(posProcess, 0, posProcess.Length);
                    }

                    posPacket.Seek(0, SeekOrigin.Begin);

                    ushort opCode;
                    ushort pkSize;

                    if (type == 0xC1 || type == 0xC3)
                    {
                        if (posPacket.Length == 3)
                        {
                            posPacket.Seek(0, SeekOrigin.End);
                            posPacket.WriteByte(0);
                            posPacket.Seek(0, SeekOrigin.Begin);
                        }
                        else if (posPacket.Length < 3)
                        {
                            throw new Exception("Invalid Packet " + type.ToString("X2") + " size " + posPacket.Length + " -");
                        }

                        var tmph = Serializer.Deserialize <WZBPacket>(posPacket);
                        opCode = tmph.Operation;
                        pkSize = tmph.Size;
                    }
                    else
                    {
                        if (posPacket.Length == 4)
                        {
                            posPacket.Seek(0, SeekOrigin.End);
                            posPacket.WriteByte(0);
                            posPacket.Seek(0, SeekOrigin.Begin);
                        }
                        else if (posPacket.Length < 4)
                        {
                            throw new Exception("Invalid Packet " + type.ToString("X2") + " size " + posPacket.Length + " -");
                        }

                        var tmph = Serializer.Deserialize <WZWPacket>(posPacket);
                        opCode = tmph.Operation;
                        pkSize = tmph.Size;
                    }

                    //posPacket.Seek(0, SeekOrigin.Begin);

                    var factory = _factories.FirstOrDefault(f => f.ContainsOpCode(opCode));
                    try
                    {
                        if (factory != null)
                        {
                            messages.Add(factory.GetMessage(opCode, posPacket));
                        }
                        else
                        {
                            var orgOpCode = opCode;
                            opCode |= 0xFF00;
                            factory = _factories.FirstOrDefault(f => f.ContainsOpCode(opCode));
                            if (factory != null)
                            {
                                posPacket.Position--;
                                messages.Add(factory.GetMessage(opCode, posPacket));
                            }
                            else
                            {
                                Logger.Error("Invalid OpCoder {opCodea:X4}|{opCode:X2} Size:{pkSize}", orgOpCode, opCode & 0xff, pkSize);
                                using (var fs = File.OpenWrite("unknowPacket_" + orgOpCode + ".bin"))
                                {
                                    fs.Write(posPacket.GetBuffer(), 0, pkSize);
                                }
                            }
                        }
                    }catch (Exception ex)
                    {
                        throw new Exception("Factory: " + factory, ex);
                    }

                    return(size);
                }
        }