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(); }
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); }
/// <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); }
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(); } } }
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(); }
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(); }
/// <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); } }
/// <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; } }
/// <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."); } }
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(); } } }
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); }
/// <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); } }
/// <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); } }