Пример #1
0
        private void OnInitPacketRecv(IAsyncResult ar)
        {
            if (!Connected)
            {
                return;
            }
            byte[] data = (byte[])ar.AsyncState;
            int    len  = _socket.EndReceive(ar);

            if (len < 15)
            {
                if (OnClientDisconnected != null)
                {
                    OnClientDisconnected(this);
                }
                Connected = false;
                return;
            }

            PacketReader reader = new PacketReader(data);

            reader.ReadShort();
            short  version  = reader.ReadShort();
            string patchVer = reader.ReadMapleString();

            _SIV = new MapleCrypto(reader.ReadBytes(4), version);
            _RIV = new MapleCrypto(reader.ReadBytes(4), version);
            byte locale = reader.ReadByte();

            if (_type == SessionType.CLIENT_TO_SERVER)
            {
                OnInitPacketReceived(version, patchVer, locale);
            }
            WaitForData();
        }
Пример #2
0
        public static byte[] GenerateWzKey(byte[] pWzIv, byte[] pAesKey)
        {
            if (BitConverter.ToInt32(pWzIv, 0) == 0)
            {
                return(new byte[ushort.MaxValue]);
            }
            AesManaged crypto = new AesManaged {
                KeySize = 256, Key = pAesKey, Mode = CipherMode.ECB
            };

            MemoryStream memStream    = new MemoryStream();
            CryptoStream cryptoStream = new CryptoStream(memStream, crypto.CreateEncryptor(), CryptoStreamMode.Write);

            byte[] input = MapleCrypto.multiplyBytes(pWzIv, 4, 4);
            byte[] wzKey = new byte[ushort.MaxValue];
            for (int i = 0; i < (wzKey.Length / 16); i++)
            {
                cryptoStream.Write(input, 0, 16);
                input = memStream.ToArray();
                Array.Copy(memStream.ToArray(), 0, wzKey, (i * 16), 16);
                memStream.Position = 0;
            }

            try {
                cryptoStream.Dispose();
                memStream.Dispose();
            } catch (Exception e) {
                Console.WriteLine("Error disposing AES streams" + e);
            }

            return(wzKey);
        }
Пример #3
0
 /// <summary>
 ///   Creates a new instance of a Session
 /// </summary>
 /// <param name="socket"> Socket connection of the session </param>
 /// <param name="recv"> Recive crypto of the session </param>
 /// <param name="send"> Send crypto of the session </param>
 public Session(Socket socket, MapleCrypto recv, MapleCrypto send)
 {
     this.Socket        = socket;
     this.ReceiveCrypto = recv;
     this.SendCrypto    = send;
     this.Client        = new MapleClient(this);
 }
Пример #4
0
 private void EndReceive(IAsyncResult ar)
 {
     if (this.Connected)
     {
         int pLength = 0;
         try
         {
             pLength = this._socket.EndReceive(ar);
         }
         catch
         {
             this.ForceDisconnect();
             return;
         }
         if (pLength <= 0)
         {
             this.ForceDisconnect();
         }
         else
         {
             this.Append(this.mSharedBuffer, 0, pLength);
             while (true)
             {
                 if (this.mCursor < 4)
                 {
                     break;
                 }
                 ushort count = MapleCrypto.getPacketLength(this.mBuffer, 0);
                 if (this.mCursor < (count + 4))
                 {
                     break;
                 }
                 byte[] dst = new byte[count];
                 Buffer.BlockCopy(this.mBuffer, 4, dst, 0, count);
                 this.RIV.Decrypt(dst);
                 this.mCursor -= count + 4;
                 if (this.mCursor > 0)
                 {
                     Buffer.BlockCopy(this.mBuffer, count + 4, this.mBuffer, 0, this.mCursor);
                 }
                 if (this.OnPacketReceived != null)
                 {
                     if (!this.Connected)
                     {
                         return;
                     }
                     this.OnPacketReceived(dst);
                 }
             }
             this.BeginReceive();
         }
     }
 }
Пример #5
0
        private void EndReceive(IAsyncResult ar)
        {
            if (!Connected)
            {
                return;
            }
            int recvLen = 0;

            try {
                recvLen = _socket.EndReceive(ar);
            } catch {
                ForceDisconnect();
                return;
            }
            if (recvLen <= 0)
            {
                ForceDisconnect();
                return;
            }
            Append(mSharedBuffer, 0, recvLen);

            while (true)
            {
                if (mCursor < 4)
                {
                    break;
                }

                ushort packetSize = MapleCrypto.getPacketLength(mBuffer, 0);
                if (mCursor < (packetSize + 4))
                {
                    break;
                }
                byte[] packetBuffer = new byte[packetSize];
                Buffer.BlockCopy(mBuffer, 4, packetBuffer, 0, packetSize);
                RIV.Decrypt(packetBuffer);
                mCursor -= (packetSize + 4);
                if (mCursor > 0)
                {
                    Buffer.BlockCopy(mBuffer, packetSize + 4, mBuffer, 0, mCursor);
                }
                if (OnPacketReceived != null)
                {
                    if (!Connected)
                    {
                        return;
                    }
                    OnPacketReceived(packetBuffer);
                }
            }
            BeginReceive();
        }
Пример #6
0
        private void OnInitPacketRecv(IAsyncResult ar)
        {
            if (!Connected)
            {
                return;
            }
            byte[] data = (byte[])ar.AsyncState;
            int    len  = _socket.EndReceive(ar);

            if (len < 15)
            {
                if (OnClientDisconnected != null)
                {
                    OnClientDisconnected(this);
                }
                Connected = false;
                return;
            }
            if (_type == SessionType.CLIENT_TO_SERVER)
            {
                for (int i = 0; i < len; i++)
                {
                    byte[] expr_42_cp_0 = data;
                    int    expr_42_cp_1 = i;
                    //Console.WriteLine("data init: " + data[i]);
                    expr_42_cp_0[expr_42_cp_1] ^= 12;
                    //Console.WriteLine("data after:  " + data[i]);
                    data[i] = (byte)(((int)data[i] << 4 & 240) | (data[i] >> 4 & 15));
                    //Console.WriteLine("data before:  " + data[i]);
                }
            }
            PacketReader reader = new PacketReader(data);

            Console.WriteLine(reader.ReadShort());
            short version = reader.ReadShort();

            reader.Skip(3);
            _SIV = new MapleCrypto(reader.ReadBytes(4), version);
            _RIV = new MapleCrypto(reader.ReadBytes(4), version);
            byte serverType = reader.ReadByte();

            if (_type == SessionType.CLIENT_TO_SERVER)
            {
                Console.WriteLine("OnInitPacketReceived .");
                OnInitPacketReceived(version, serverType);
            }
            WaitForData();
        }
Пример #7
0
 /// <summary>
 ///   Client connected handler
 /// </summary>
 /// <param name="iar"> The IAsyncResult </param>
 private void OnClientConnect(IAsyncResult iar)
 {
     try
     {
         Socket      socket     = Listener.EndAccept(iar);
         byte[]      ivRecv     = { 70, 114, 122, 82 };
         byte[]      ivSend     = { 82, 48, 120, 115 };
         MapleCrypto recvCrypto = new MapleCrypto(ivRecv);
         MapleCrypto sendCrypto = new MapleCrypto(ivSend);
         Session     session    = new Session(socket, recvCrypto, sendCrypto);
         session.Begin(ivRecv, ivSend);
         Listener.BeginAccept(OnClientConnect, null);
     }
     catch (Exception e)
     {
         Console.WriteLine(e.Message);
         Console.WriteLine(e.StackTrace);
     }
 }
Пример #8
0
        /// <summary>
        /// A loop to check for received packets
        /// </summary>
        private void ReceiveLoop()
        {
            if (this.TcpConnection.Connected)
            {
                while (this.TcpConnection.Available < 0x10)
                {
                    Thread.Sleep(50);
                }
                byte[] buffer = new byte[0x10];
                this.TcpConnection.GetStream().Read(buffer, 0, 0x10);

                PacketReader Reader = new PacketReader(buffer);
                Reader.ReadShort();
                this.MapleVersion = Reader.ReadShort();
                Reader.ReadMapleString();
                this.SendCrypto    = new MapleCrypto(Reader.ReadBytes(4), (short)this.MapleVersion);
                this.ReceiveCrypto = new MapleCrypto(Reader.ReadBytes(4), (short)this.MapleVersion);

                this.Ready = true;
                while (this.TcpConnection.Connected)
                {
                    if (this.TcpConnection.Available >= 4)
                    {
                        byte[] buffer2 = new byte[4];
                        this.TcpConnection.GetStream().Read(buffer2, 0, 4);
                        int packetLength = MapleCrypto.GetPacketLength(buffer2);
                        while (this.TcpConnection.Available < packetLength)
                        {
                            Thread.Sleep(20);
                        }
                        byte[] buffer3 = new byte[packetLength];
                        this.TcpConnection.GetStream().Read(buffer3, 0, packetLength);
                        this.ReceiveCrypto.Crypt(buffer3);
                        MapleCustomEncryption.Decrypt(buffer3);
                        Client.HandlePacket(buffer3);
                    }
                    Thread.Sleep(5);
                }
                this.Ready = false;
            }
        }
Пример #9
0
        /// <summary>
        ///   Data received event handler
        /// </summary>
        /// <param name="iar"> IAsyncResult of the data received event </param>
        private void DataReceived(IAsyncResult iar)
        {
            ReceiveManager manager = (ReceiveManager)iar.AsyncState;

            try
            {
                int received = Socket.EndReceive(iar);
                manager.Index += received;
                if (manager.Index == manager.Buffer.Length)
                {
                    byte[] data = manager.Buffer;
                    switch (manager.State)
                    {
                    case ReceiveState.Header:
                        int packetLength = MapleCrypto.GetPacketLength(data);
                        manager.State  = ReceiveState.Content;
                        manager.Buffer = new byte[packetLength];
                        manager.Index  = 0;
                        WaitForData(manager);
                        break;

                    case ReceiveState.Content:
                        ReceiveCrypto.Crypt(data);
                        MapleCustomEncryption.Decrypt(data);
                        PacketReceived(new MaplePacketReader(data));
                        WaitForData(new ReceiveManager());
                        break;
                    }
                }
                else
                {
                    Console.WriteLine("[Warning] Not enough data");
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
                Console.WriteLine(e.StackTrace);
                Close("Exception while receiving data.");
            }
        }
Пример #10
0
        private void OnInitPacketRecv(IAsyncResult ar)
        {
            if (this.Connected)
            {
                byte[] asyncState = (byte[])ar.AsyncState;
                if (this._socket.EndReceive(ar) < 15)
                {
                    if (this.OnClientDisconnected != null)
                    {
                        this.OnClientDisconnected(this);
                    }
                    this.Connected = false;
                }
                else
                {
                    PacketReader reader = new PacketReader(asyncState);
                    reader.ReadShort();
                    short  mapleVersion     = reader.ReadShort();
                    string str              = reader.ReadMapleString();
                    byte[] serverRecv       = reader.ReadBytes(4);
                    byte[] serverSend       = reader.ReadBytes(4);
                    byte   serverIdentifier = (byte)7;
                    if (reader.ReadByte() == (byte)7)
                    {
                        serverRecv = new byte[] { 0x74, 0x65, 0x74, 0x72 };
                        serverSend = new byte[] { 0x61, 0x53, 0x45, 0x41 };
                    }

                    this._SIV = new MapleCrypto(serverRecv, mapleVersion);
                    this._RIV = new MapleCrypto(serverSend, mapleVersion);
                    if (this._type == SessionType.CLIENT_TO_SERVER)
                    {
                        this.OnInitPacketReceived(mapleVersion, serverIdentifier, str);
                    }
                    this.WaitForData();
                }
            }
        }
Пример #11
0
        public static byte[] GenerateWzKey(byte[] WzIv, byte[] AesKey)
        {
            if (BitConverter.ToInt32(WzIv, 0) == 0)
            {
                return(new byte[ushort.MaxValue]);
            }
            AesManaged crypto = new AesManaged();

            crypto.KeySize = 256;
            crypto.Key     = AesKey;
            crypto.Mode    = CipherMode.ECB;

            MemoryStream memStream    = new MemoryStream();
            CryptoStream cryptoStream = new CryptoStream(memStream, crypto.CreateEncryptor(), CryptoStreamMode.Write);

            byte[] input = MapleCrypto.multiplyBytes(WzIv, 4, 4);
            byte[] wzKey = new byte[ushort.MaxValue];
            for (int i = 0; i < (wzKey.Length / 16); i++)
            {
                cryptoStream.Write(input, 0, 16);
                input = memStream.ToArray();
                Array.Copy(input, 0, wzKey, (i * 16), 16);
                memStream.Position = 0;
            }
            cryptoStream.Write(input, 0, 16);
            Array.Copy(memStream.ToArray(), 0, wzKey, (wzKey.Length - 15), 15);
            try
            {
                cryptoStream.Dispose();
                memStream.Dispose();
            }
            catch (Exception e)
            {
                Helpers.ErrorLogger.Log(Helpers.ErrorLevel.Critical, "Error disposing AES streams" + e);
            }

            return(wzKey);
        }
Пример #12
0
        /// <summary>
        /// Data received event handler
        /// </summary>
        /// <param name="iar">IAsyncResult of the data received event</param>
        private void OnDataReceived(IAsyncResult iar)
        {
            SocketInfo socketInfo = (SocketInfo)iar.AsyncState;

            try
            {
                int received = socketInfo.Socket.EndReceive(iar);
                if (received == 0)
                {
                    if (OnClientDisconnected != null)
                    {
                        OnClientDisconnected(this);
                    }
                    return;
                }

                socketInfo.Index += received;

                if (socketInfo.Index == socketInfo.DataBuffer.Length)
                {
                    switch (socketInfo.State)
                    {
                    case SocketInfo.StateEnum.Header:
                        if (socketInfo.NoEncryption)
                        {
                            PacketReader headerReader = new PacketReader(socketInfo.DataBuffer);
                            short        packetHeader = headerReader.ReadShort();
                            socketInfo.State      = SocketInfo.StateEnum.Content;
                            socketInfo.DataBuffer = new byte[packetHeader];
                            socketInfo.Index      = 0;
                            WaitForData(socketInfo);
                        }
                        else
                        {
                            PacketReader headerReader  = new PacketReader(socketInfo.DataBuffer);
                            byte[]       packetHeaderB = headerReader.ToArray();
                            int          packetHeader  = headerReader.ReadInt();
                            short        packetLength  = (short)MapleCrypto.getPacketLength(packetHeader);
                            if (_type == SessionType.SERVER_TO_CLIENT && !_RIV.checkPacketToServer(BitConverter.GetBytes(packetHeader)))
                            {
                                Helpers.ErrorLogger.Log(Helpers.ErrorLevel.Critical, "[Error] Packet check failed. Disconnecting client.");
                                //this.Socket.Close();
                            }
                            socketInfo.State      = SocketInfo.StateEnum.Content;
                            socketInfo.DataBuffer = new byte[packetLength];
                            socketInfo.Index      = 0;
                            WaitForData(socketInfo);
                        }
                        break;

                    case SocketInfo.StateEnum.Content:
                        byte[] data = socketInfo.DataBuffer;
                        if (socketInfo.NoEncryption)
                        {
                            socketInfo.NoEncryption = false;
                            PacketReader reader  = new PacketReader(data);
                            short        version = reader.ReadShort();
                            string       unknown = reader.ReadMapleString();
                            _SIV = new MapleCrypto(reader.ReadBytes(4), version);
                            _RIV = new MapleCrypto(reader.ReadBytes(4), version);
                            byte serverType = reader.ReadByte();
                            if (_type == SessionType.CLIENT_TO_SERVER)
                            {
                                OnInitPacketReceived(version, serverType);
                            }
                            OnPacketReceived(new PacketReader(data), true);
                            WaitForData();
                        }
                        else
                        {
                            _RIV.crypt(data);
                            MapleCustomEncryption.Decrypt(data);
                            if (data.Length != 0 && OnPacketReceived != null)
                            {
                                OnPacketReceived(new PacketReader(data), false);
                            }
                            WaitForData();
                        }
                        break;
                    }
                }
                else
                {
                    Helpers.ErrorLogger.Log(Helpers.ErrorLevel.Critical, "[Warning] Not enough data");
                    WaitForData(socketInfo);
                }
            }
            catch (ObjectDisposedException)
            {
                Helpers.ErrorLogger.Log(Helpers.ErrorLevel.Critical, "[Error] Session.OnDataReceived: Socket has been closed");
            }
            catch (SocketException se)
            {
                if (se.ErrorCode != 10054)
                {
                    Helpers.ErrorLogger.Log(Helpers.ErrorLevel.Critical, "[Error] Session.OnDataReceived: " + se);
                }
            }
            catch (Exception e)
            {
                Helpers.ErrorLogger.Log(Helpers.ErrorLevel.Critical, "[Error] Session.OnDataReceived: " + e);
            }
        }
Пример #13
0
        /// <summary>
        /// Data received event handler
        /// </summary>
        /// <param name="iar">IAsyncResult of the data received event</param>
        private void OnDataReceived(IAsyncResult iar)
        {
            var socketInfo = (SocketInfo)iar.AsyncState;

            try
            {
                var received = socketInfo.Socket.EndReceive(iar);
                if (received == 0)
                {
                    OnClientDisconnected?.Invoke(this);
                    return;
                }

                socketInfo.Index += received;

                if (socketInfo.Index == socketInfo.DataBuffer.Length)
                {
                    switch (socketInfo.State)
                    {
                    case SocketInfo.StateEnum.Header:
                        if (socketInfo.IsNoEncryption)
                        {
                            var headerReader = new PacketReader(socketInfo.DataBuffer);
                            var packetHeader = headerReader.ReadShort();
                            socketInfo.State      = SocketInfo.StateEnum.Content;
                            socketInfo.DataBuffer = new byte[packetHeader];
                            socketInfo.Index      = 0;
                            WaitForData(socketInfo);
                        }
                        else
                        {
                            var headerReader  = new PacketReader(socketInfo.DataBuffer);
                            var packetHeaderB = headerReader.ToArray();
                            var packetHeader  = headerReader.ReadInt();
                            var packetLength  = (short)MapleCrypto.GetPacketLength(packetHeader);
                            if (Type == SessionType.SERVER_TO_CLIENT &&
                                !RIV.CheckPacketToServer(BitConverter.GetBytes(packetHeader)))
                            {
                                Log.LogError("Packet check failed. Disconnecting client");
                                Socket.Close();
                            }

                            socketInfo.State      = SocketInfo.StateEnum.Content;
                            socketInfo.DataBuffer = new byte[packetLength];
                            socketInfo.Index      = 0;
                            WaitForData(socketInfo);
                        }

                        break;

                    case SocketInfo.StateEnum.Content:
                        var data = socketInfo.DataBuffer;

                        if (socketInfo.IsNoEncryption)
                        {
                            socketInfo.IsNoEncryption = false;
                            var reader  = new PacketReader(data);
                            var version = reader.ReadShort();
                            var unknown = reader.ReadMapleString();
                            SIV = new MapleCrypto(reader.ReadBytes(4), version);
                            RIV = new MapleCrypto(reader.ReadBytes(4), version);
                            var serverType = reader.ReadByte();

                            if (Type == SessionType.CLIENT_TO_SERVER)
                            {
                                OnInitPacketReceived(version, serverType);
                            }

                            OnPacketReceived(new PacketReader(data), true);
                            WaitForData();
                        }
                        else
                        {
                            RIV.Crypt(data);
                            MapleCustomEncryption.Decrypt(data);

                            if (data.Length != 0)
                            {
                                OnPacketReceived?.Invoke(new PacketReader(data), false);
                            }

                            WaitForData();
                        }

                        break;
                    }
                }
                else
                {
                    Log.LogWarning("Not enough data");
                    WaitForData(socketInfo);
                }
            }
            catch (ObjectDisposedException e)
            {
                Log.LogError("Socket has been closed", e);
            }
            catch (SocketException se)
            {
                if (se.ErrorCode != 10054)
                {
                    Log.LogError("Session.OnDataReceived", se);
                }
            }
            catch (Exception e)
            {
                Log.LogError("Session.OnDataReceived", e);
            }
        }