Packet Decryption help

01/19/2008 16:55 Kendoo#1
Hi!

I'm working on a little prog. that decrypts the L2 packages.

The decryption algorithm is (I think) good, because the first packet seems to be decrypted successfully, the problem is probably in the key update, which is made after every packet.

[Only registered and activated users can see links. Click Here To Register...]
You can see on this image that the decryption is good, and it doesn't screws up long strings (will be described below).

I noticed the error when I tried to decrypt Message packets.

[Only registered and activated users can see links. Click Here To Register...]
You can see on this image, that every 9. byte is wrong if you split the packets into 16 byte parts, which is the key length (and the error is the same in each packet). On the image, the opcode is separated in the first line, and the others is the data splitted 8 byte/row.

I use this algorithm to decrypt packets (c#):
Code:
public void Decrypt(byte[] buf)
        {
            int temp = 0;
            for (int i = 0; i < buf.Length; i++)
            {
                int temp2 = buf[i];
                buf[i] = ((byte)(temp2 ^ (this._key[i & 0x0F]) ^ temp));
                temp = temp2;
            }

            long old = ((uint)this._key[8] & 0x000000ff)
                | (((uint)this._key[9] << 8) & 0x0000ff00)
                | (((uint)this._key[10] << 16) & 0x00ff0000)
                | (((uint)this._key[11] << 24) & 0xff000000);

            old += buf.Length;

            this._key[8] = (byte)(old & 0xff);
            this._key[9] = (byte)(old >> 8 & 0xff);
            this._key[10] = (byte)(old >> 16 & 0xff);
            this._key[11] = (byte)(old >> 24 & 0xff);
        }
As you see, the algorithm updates the bytes 9, 10, 11 and 12 (8...11 if zero based), exactly the ones, that is wrong in the decryption, and you can see, that if you decrypt the 9. byte of the packet, it's decrypted using the 9. byte of the key (buf[i] = ((byte)(temp2 ^ (this._key[i & 0x0F]) ^ temp));)

I made this algorithm based on the L2J source (gameserver/Crypt.java and gameserver/network/GameCrypt.java) and the LineAge Utils ([Only registered and activated users can see links. Click Here To Register...] it works on C4 and written in c#.

I try to decrypt Interlude packages, but the problem is the same on the locally installed L2J server and on an offmod server too.
01/19/2008 22:28 pengpong#2
a friend had the same problem, but i can't really remember how we solved the problem *hm*

try
old += buf.Length -2;
instead of
old += buf.Length;

---->
I use a slightly different code for decrypting (beside the fact that i'm using c++), i have 2 arguments (the buffer, and the size..)

I'm not sure how you do the packet handling, but remember:
the thing that you add to "old" is not the tcp packet size but the packet size...

packet size is in the first 2 bytes of a packet, so normally your "correct size" should be buf.Length-2 .....
do you have implented a packet queue? don't forget that the tcp packet might be fragmented... so normally you should do s.th like:

1* get packet
* if(oldPacket!=null) packet=oldPacket+packet; oldPacket=null;
* size=packet[1+2];
* if packet.size < (size+2) oldPacket=packet; goto 1;

blablub... i think you know what i mean :)
01/22/2008 21:10 Kendoo#3
The algorithm is perfect, the data, that the decrypter gets is the game packet data only, the size has been splitted, so the old is right.
I didn't made a packet queue and a TCP sorter.

Now it works, thanks.
01/27/2008 22:49 dinesat4#4
Good code
i have about 1 month trying to decrypt l2 packets

this is my code (it the same, i taked from Crypt.java)

Code:
    public class LA2Crypt
    {
        private byte[] decode_key = new byte[16];
        public byte[] inKey = new byte[16];
        public byte[] outKey = new byte[16];

        public LA2Crypt(byte[] decode_key, bool blowfish)
        {
            decode_key.CopyTo(inKey, 1);
            decode_key.CopyTo(outKey, 1);
        }

        public void Decrypt(byte[] buf)
        {
            int tmp = 0;
            for (int k = 0; k < buf.Length; k++)
            {
                int tmp2 = buf[k] & 0xFF;
                buf[k] = (byte)(tmp2 ^ (inKey[k & 0x0F]) ^ tmp);
                tmp = tmp2;
            }

            long old = ((uint)this.inKey[8] & 0x000000ff)
                | (((uint)this.inKey[9] << 0x08) & 0x0000ff00)
                | (((uint)this.inKey[10] << 0x10) & 0x00ff0000)
                | (((uint)this.inKey[11] << 0x18) & 0xff000000);

            old += buf.Length;

            inKey[8] = (byte)(old & 0xff);
            inKey[9] = (byte)(old >> 0x08 & 0xff);
            inKey[10] = (byte)(old >> 0x10 & 0xff);
            inKey[11] = (byte)(old >> 0x18 & 0xff);
        }
    }
04/07/2009 08:17 nobleman80#5
any one have a decryption tool? or any1 play 2moon here? any idea to make the 2moon exe read only real time? help pls.