Example #1
0
        private static void PackHeader(CryptoClient client, Span <byte> packet)
        {
            var key = client.ServerKey;

            var randKey = _random.Next(0, 255);

            packet[6] = (byte)randKey;                          // Set RandKey field
            packet[7] = 0x06;                                   // Set Packing field to 0x06 (don't change key)
            packet[8] = CryptoCommon.MakeChecksum(packet, key); // Update the checkflag

            // Encrypt packing
            packet[7] = KeyTable.Table[(ushort)((randKey << 8) + packet[7])];

            // Encrypt length
            var length = (ushort)((KeyTable.Table[(ushort)(((packet[6] ^ packet[7]) << 8) + packet[1])] << 8)
                                  + KeyTable.Table[(ushort)(((packet[7] ^ key) << 8) + packet[0])]);

            ByteUtil.CopyTo(packet, 0, length);

            // Encrypt opcode
            var opcode = (ushort)((KeyTable.Table[(ushort)(((packet[1] ^ key) << 8) + packet[3])] << 8)
                                  + KeyTable.Table[(ushort)(((packet[6] ^ packet[0]) << 8) + packet[2])]);

            ByteUtil.CopyTo(packet, 2, opcode);

            // Encrypt sequence
            var sequence = (ushort)((KeyTable.Table[(ushort)(((packet[3] ^ packet[7]) << 8) + packet[5])] << 8)
                                    + KeyTable.Table[(ushort)(((packet[2] ^ key) << 8) + packet[4])]);

            ByteUtil.CopyTo(packet, 4, sequence);
        }
Example #2
0
        /// <summary>
        /// This method is copied directly from the Trickster server.
        ///
        /// My theory on what this method does is that it makes sure the first packet sent is valid.
        /// If it's not valid, we can exit early as the server will know that it's an invalid client.
        /// Perhaps someone's trying to send some trash data or connect with a non-client.
        ///
        /// The Header object (at the time of a call to this function) is essentially a bunch
        /// of fields within the raw packet.
        /// </summary>
        /// <param name="header">The Header object before decrypting the packet header.</param>
        /// <param name="client">The current client session.</param>
        /// <returns>Primitive packet validity flag</returns>
        private static bool CheckHeader(Header header, CryptoClient client)
        {
            if (!client.IsFirstPacket)
            {
                return(true);
            }

            byte packing = header.Packing;

            if (packing > 0xFu && (KeyTable.Table[(ushort)((header.RandKey << 8) + packing)] & 0xF) == 15)
            {
                // If that magic value is 15, we know this is a primitively "valid packet".
                // We can update the session since we know the next packet is no longer the first packet.
                client.IsFirstPacket = false;
                return(true);
            }

            return(false);
        }
Example #3
0
        public static void UpdateKey(CryptoClient client, int tail)
        {
            byte key = client.Key;

            client.Key = (byte)(KeyTable.Table[((tail & 0xff) << 8) + key] + key);
        }
Example #4
0
 private static void PackStream(CryptoClient client, ushort opcode, Span <byte> packet)
 {
     // Get the packet data only, from offset 9 to (len - 2)
     var data = packet[9..^ 2];