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); }
/// <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); }
public static void UpdateKey(CryptoClient client, int tail) { byte key = client.Key; client.Key = (byte)(KeyTable.Table[((tail & 0xff) << 8) + key] + key); }
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];