/*
EUDEMON PACKET ENCRYPTION/DECRYPTION, MARCH 30th, 2012
Copyright (C) 2012 InfamousNoone (of http://elitepvpers.com) and http://conquerai.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
GNU General Public License: http://www.gnu.org/licenses/
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using ICSPublicLibrary;
namespace EudemonAI.Network
{
public unsafe class EudemonCryptographer : INetworkEncryption
{
//
//
// REVERSED BY InfamousNoone @ E*PVP (http://www.elitepvpers.com)
// OF CONQUERAI (http://conquerai.com) -- 2012, March 28th
//
// Special thanks for contributions (from elitepvpers.com):
// hio77
// funhacker
//
//
[StructLayout(LayoutKind.Explicit)]
private struct Counter
{
[FieldOffset(0)]
public ushort Value;
[FieldOffset(0)]
public byte Low;
[FieldOffset(1)]
public byte High;
}
private static byte[] skey1 =
{
0x9A,0x71,0x9E,0x65,0xB2,0xE9,0x96,0xBD,0x0A,0xA1,0xCE,0x55,0xA2,0x99,0x46,0x2D
,0x7A,0xD1,0xFE,0x45,0x92,0x49,0xF6,0x9D,0xEA,0x01,0x2E,0x35,0x82,0xF9,0xA6,0x0D
,0x5A,0x31,0x5E,0x25,0x72,0xA9,0x56,0x7D,0xCA,0x61,0x8E,0x15,0x62,0x59,0x06,0xED
,0x3A,0x91,0xBE,0x05,0x52,0x09,0xB6,0x5D,0xAA,0xC1,0xEE,0xF5,0x42,0xB9,0x66,0xCD
,0x1A,0xF1,0x1E,0xE5,0x32,0x69,0x16,0x3D,0x8A,0x21,0x4E,0xD5,0x22,0x19,0xC6,0xAD
,0xFA,0x51,0x7E,0xC5,0x12,0xC9,0x76,0x1D,0x6A,0x81,0xAE,0xB5,0x02,0x79,0x26,0x8D
,0xDA,0xB1,0xDE,0xA5,0xF2,0x29,0xD6,0xFD,0x4A,0xE1,0x0E,0x95,0xE2,0xD9,0x86,0x6D
,0xBA,0x11,0x3E,0x85,0xD2,0x89,0x36,0xDD,0x2A,0x41,0x6E,0x75,0xC2,0x39,0xE6,0x4D
};
private static byte[] skey2 = { 0x7E, 0xDE, 0xFE, 0x5E };
private static byte[] skey3 =
{
0xE4,0xAF,0x60,0x3B,0xCC,0x37,0x68,0xE3,0x74,0x7F,0x30,0x0B,0xDC,0x47,0xB8,0x73
,0x04,0x0F,0x00,0x1B,0xEC,0x97,0x08,0xC3,0x94,0xDF,0xD0,0x6B,0xFC,0x27,0x58,0x53
,0x24,0xEF,0xA0,0x7B,0x0C,0x77,0xA8,0x23,0xB4,0xBF,0x70,0x4B,0x1C,0x87,0xF8,0xB3
,0x44,0x4F,0x40,0x5B,0x2C,0xD7,0x48,0x03,0xD4,0x1F,0x10,0xAB,0x3C,0x67,0x98,0x93
,0x64,0x2F,0xE0,0xBB,0x4C,0xB7,0xE8,0x63,0xF4,0xFF,0xB0,0x8B,0x5C,0xC7,0x38,0xF3
,0x84,0x8F,0x80,0x9B,0x6C,0x17,0x88,0x43,0x14,0x5F,0x50,0xEB,0x7C,0xA7,0xD8,0xD3
,0xA4,0x6F,0x20,0xFB,0x8C,0xF7,0x28,0xA3,0x34,0x3F,0xF0,0xCB,0x9C,0x07,0x78,0x33
,0xC4,0xCF,0xC0,0xDB,0xAC,0x57,0xC8,0x83,0x54,0x9F,0x90,0x2B,0xBC,0xE7,0x18,0x13
};
private static byte[] skey4 =
{
0x1A,0x50,0x9E,0x44,0x32,0xC8,0x96,0x1C,0x0A,0x80,0xCE,0x54,0x22,0x98,0x46,0x0C
,0x7A,0xD0,0xFE,0x44,0x12,0x48,0xF6,0x1C,0x6A,0x00,0x2E,0x14,0x02,0xD8,0xA6,0x0C
,0x5A,0x10,0x5E,0x04,0x72,0x88,0x56,0x5C,0x4A,0x40,0x8E,0x14,0x62,0x58,0x06,0x4C
,0x3A,0x90,0xBE,0x04,0x52,0x08,0xB6,0x5C,0x2A,0xC0,0xEE,0x54,0x42,0x98,0x66,0x4C
};
private byte[] key1, key2, key3, key4;
private Counter inCounter;
private Counter outCounter;
public bool IsServer { get; set; }
public uint CryptoKey { get; private set; }
public EudemonCryptographer()
{
IsServer = false;
inCounter = new Counter();
outCounter = new Counter();
key1 = Inflate(skey1, 256);
key2 = Inflate(skey2, 256);
key3 = Inflate(skey3, 256);
key4 = Inflate(skey4, 256);
}
private byte[] Inflate(byte[] key, int size)
{
if (size % key.Length != 0)
throw new ArgumentException("Cannot inflate, size modulated by the key length must be zero.");
byte[] inflation = new byte[size];
for (int i = 0; i < size; i += key.Length)
Array.Copy(key, 0, inflation, i, key.Length);
return inflation;
}
private byte Nibble(byte arg)
{
return (byte)((arg >> 4) | (arg << 4));
}
private uint ExchangeLongBits(uint nData, int nBits)
{
return (nData>>nBits) | (nData<<(32-nBits));
}
public void SetKey(uint accountId, uint cryptoId)
{
uint key = ExchangeLongBits(accountId, 7) + ExchangeLongBits(cryptoId, 0xb);
key ^= 0x6279;
key ^= cryptoId;
uint num2 = (key & 0xFFFF); // edx
uint num1 = ((key >> 16) & 0xFFFF); // eax
num1 *= num1;
num2 *= num2;
fixed (void* ptr1 = key1, ptr2 = key2, ptr3 = key3, ptr4 = key4)
{
uint* k1 = (uint*)ptr1;
uint* k2 = (uint*)ptr2;
uint* k3 = (uint*)ptr3;
uint* k4 = (uint*)ptr4;
for (int i = 0; i < 64; i++)
{
k1[i] = k1[i] ^ num2;
k2[i] = k2[i] ^ num1;
k3[i] = k1[i] ^ k2[i];
k4[i] = k1[i] & k2[i];
}
}
}
public void Decrypt(byte[] @in, int inOffset, byte[] @out, int outOffset, int length)
{
if (!IsServer) // Server->Client
{
for (int i = 0; i < length; i++)
{
byte al = @in[inOffset + i];
al = Nibble(al);
al -= skey4[inCounter.High % skey4.Length];
al ^= skey2[inCounter.High % skey2.Length];
al -= skey3[inCounter.Low % skey3.Length];
al ^= skey1[inCounter.Low % skey1.Length];
@out[outOffset + i] = al;
inCounter.Value++;
}
}
else // Client -> Server
{
for (int i = 0; i < length; i++)
{
byte al = @in[inOffset + i];
al = Nibble(al);
al -= key4[inCounter.High];
al ^= key2[inCounter.High];
al -= key3[inCounter.Low];
al ^= key1[inCounter.Low];
@out[outOffset + i] = al;
inCounter.Value++;
}
}
//fixed (byte* bf = @out)
// App.Log("Decrypt After -- \n" + Packet.CreatePacketStringWithNumbers(bf + outOffset, length));
}
public unsafe void Encrypt(byte* @in, byte[] @out, int length)
{
//App.Log("Encrypt Before -- \n" + Packet.CreatePacketStringWithNumbers(@in, length));
if (!IsServer) // Client->Server
{
for (int i = 0; i < length; i++)
{
byte al = @in[i];
al ^= key1[outCounter.Low];
al += key3[outCounter.Low];
al ^= key2[outCounter.High];
al += key4[outCounter.High];
al = Nibble(al);
@out[i] = al;
outCounter.Value++;
}
}
else // Server -> Client
{
for (int i = 0; i < length; i++)
{
byte al = @in[i];
al ^= skey1[outCounter.Low % skey1.Length];
al += skey3[outCounter.Low % skey3.Length];
al ^= skey2[outCounter.High % skey2.Length];
al += skey4[outCounter.High % skey4.Length];
al = Nibble(al);
@out[i] = al;
outCounter.Value++;
}
}
}
}
}
AccountID and CryptoID are sent in the 41F Packet (Server->Client), which is structured:
Code:
AccountID = msg.ReadInt32();
CryptoID = msg.ReadInt32();
int port = msg.ReadInt32();
int unknown = msg.ReadInt32();
string host = msg.ReadCString(32);
When the client sends the 41C packet on the game server, it then switches to these new keys. Therefore, packets decrypted from the client must now be decrypted using the new keys generated by SetKey().
Sorry I couldn't be of much help, sadly I've no real experience in encryption/decryption or even packets for that matter.
However you may want to put in the main post that this is done on client version 1581, may help further down the track if ever abandoned and TQ changes encryption
BOI Packet Encryption 09/28/2011 - Battle of the Immortals - 13 Replies I've made some research about the packet encryption used in this game and I thought I'd share them.
BOI uses a simple XOR-Algorithm. Each byte of a packet is being XORed with the value of the previous byte. The first byte of every packet indicates its length. Furthermore the first byte of the very first packet sent after the connection was established is being XORed with the value 0xCD.
Example:
Let's say the client sends this packet right after connecting to the server.
0x06 0xA7 0x57...
Packet encryption. 06/22/2009 - Shaiya - 2 Replies Not sure if anyone has tried making a proxy yet, other than the one that is stickied (which is injected and I imagine directly hooks the games send function bypassing the need for encryption?).
Anyway, just curious if anyone knows what sort of encryption is being used on packets?
US server for the record.
Help with Packet Encryption? 04/16/2009 - General Coding - 9 Replies can someone help with these packets? im completely lost lol.i typed in A,B,ABC aand recorded the 3 packets
A
2C 35 52 66 BF 66 15 E1 2C 3A D6 AD E3 29 82 A9 BC C5 EE F5 90 A9 1A 71 0C CD 06 3D FC 3A F6 5C A7 A1 4C 30 63 CD 03 AE 12 A6 20 88 1E C0 E8 95 19 F3 3D A7 42 3A 09 22
B
A7 9E F9 6D D4 5D 9E 6A F7 81 0D D6 B8 22 D9 52 57 8E E5 9E 9B 92 31 9A 97 F6 DD 46 A7 11 ED A7 6C 8A E7 7B 08 F6 48 65 09 EE C8 80 76 78 00 1D 81 8B 85 BF 79 F2 D1 BA
Packet Encryption 02/22/2007 - General Coding - 4 Replies so heute mal nichts zu tun also hab ich mal nach einem opfer ausschau gehalten und stieß dabei auf steam
steam ist wie vermutlich jeder weiß eine online platform zum kaufen und spielen von spielen
einige dinge die ich mir ueberlegt hab:
steam bruter
no-recoil hack fuer cs
ein steam bruter gab es soweit ich weiß noch nicht und koennte sich als sehr nuetzlich erweisen natuerlich sollte er interface unabhaengig sein und rein auf packet basis arbeiten
keke wireshark angeschmissen...
Packet encryption 09/19/2005 - Lineage 2 - 1 Replies Hi,I'm trying to make a simple L2 bot, but i got stuck in begginning - in the packet encryption. I rewrote the l2j login thread sources (those about encryption) but it doesn't work. Has anyone any description of L2 packet encryption. And second question - what Init packet (server packet,nr. 0) means? I guess that it something related with encryption, but in l2j sources that packet content is hardcoded.
Thanks for replies (if any ;) )