Welcome!

Join our community of MMO enthusiasts and game developers! By registering, you'll gain access to discussions on the latest developments in MMO server files and collaborate with like-minded individuals. Join us today and unlock the potential of MMO server development!

Join Today!

Packets to server (Ostara Project)

Initiate Mage
Joined
Mar 15, 2015
Messages
1
Reaction score
0
Hi
I first met the Ostara project yesterday and i'm very intersted. For a long time I've been studied about Cabal packets with the intention of create a simple loot filter.

Ostara already give me decrypted packets (I studied the source, some parts I could understand).

I know it needs to use a proxy server to intercept packets. I read somewhere that the connection is like this:

Client packet > Proxy > Server <=> Server packet > Proxy > Client

I can't send packets to server directly from other software like wpe. I think is't because the server isn't recognize the IP/Port.

So, I need send packets through the proxy that Ostara use?

In that source have a decryption code, used to decrypt Server>Client. I need a way to use that decryption to send back my undecripted packs catched by Ostara.

How can I send my packets through the proxy to server?

After understanding this, i wanna develop a loot filter. I have some notes about the server packets received for mobs drops and I can identify then.

Fell free for give any help, indicate posts/thread or other (I not find another topic about my doubt. But I read many related that helped me)

Thanks all!
 
Skilled Illusionist
Joined
Jan 5, 2009
Messages
343
Reaction score
391
if ya really wanna send packets to the sv ya better include the checksum (not included in ostara yet) :D here's a snippet that may help :p this is how the sv expects packets to be ;)
Code:
            ACE_UINT32 dwR = 0;
            size_t remainLen = packetLen % 4;

            std::memcpy(&dwR, pPayload, remainLen);

            const ACE_UINT32 mask[] 
                        = { 0xFFFFFFFF, 0xFFFFFF00, 0xFFFF0000, 0xFF000000 };
            const ACE_UINT32 m = mask[remainLen];
            XorNum = dwR;
            dwR = (XorNum ^ XorKey) ^ (XorKey & m);

            std::memcpy(pPayload, &dwR, remainLen);

            // CheckSum
            const ACE_UINT32 calcChecksum = 
                (XorKeyTable[(XorKey & RECV_XORKEYNUMMASK) * xorKeyTableBaseMultiple_] ^ (XorNum & ~m));            
            if(*pChecksum != calcChecksum) {
                LOG_TRACE(1, ("sock %d=> wrong checksum (%X, %X)", 
                            get_handle(), *pChecksum, calcChecksum));
                return false;
            }
 
Newbie Spellweaver
Joined
Mar 28, 2010
Messages
26
Reaction score
9
Is the checksum part of the packet header?

if ya really wanna send packets to the sv ya better include the checksum (not included in ostara yet) :D here's a snippet that may help :p this is how the sv expects packets to be ;)
Code:
            ACE_UINT32 dwR = 0;
            size_t remainLen = packetLen % 4;

            std::memcpy(&dwR, pPayload, remainLen);

            const ACE_UINT32 mask[] 
                        = { 0xFFFFFFFF, 0xFFFFFF00, 0xFFFF0000, 0xFF000000 };
            const ACE_UINT32 m = mask[remainLen];
            XorNum = dwR;
            dwR = (XorNum ^ XorKey) ^ (XorKey & m);

            std::memcpy(pPayload, &dwR, remainLen);

            // CheckSum
            const ACE_UINT32 calcChecksum = 
                (XorKeyTable[(XorKey & RECV_XORKEYNUMMASK) * xorKeyTableBaseMultiple_] ^ (XorNum & ~m));            
            if(*pChecksum != calcChecksum) {
                LOG_TRACE(1, ("sock %d=> wrong checksum (%X, %X)", 
                            get_handle(), *pChecksum, calcChecksum));
                return false;
            }

This is how the encryption is happening client side but the server doesn't respond to it.
Is this algorithm calculating the checksum wrong? I compared the code but cannot see the difference only the remainLen is like hardcoded don't get why.

Code:
public void Encrypt(ref byte[] packet)
		{
			uint size = (uint)packet.Length;
			Array.Resize(ref packet, packet.Length + 4);
			if (size < 0x0A)
				return;

			BitConverter.GetBytes(BitConverter.ToInt32(packet, 0) ^ HeaderXor).CopyTo(packet, 0);

			uint Key = (BitConverter.ToUInt32(packet, 0) & 0x3FFF) * (uint)Mul;
			Key = BitConverter.ToUInt32(Keychain, (int)(Key * 4));

			uint t = (size - 8) >> 2; //Shift right 2 = divide by 4
			uint t1;
			uint i = 8;
			while (t > 0)
			{
				t1 = BitConverter.ToUInt32(packet, (int)i);
				t1 = t1 ^ Key;
				BitConverter.GetBytes(t1).CopyTo(packet, i);
				t1 = (t1 & 0x3FFF) * (uint)Mul;
				Key = BitConverter.ToUInt32(Keychain, (int)(t1 * 4));
				i += 4;
				t--;
			}
			t1 = masks[((size - 8) & 3)];
			t1 = ~t1;
			uint t2 = (t1 & Key) ^ BitConverter.ToUInt32(packet, (int)i);
			BitConverter.GetBytes((t1 & Key) ^ BitConverter.ToUInt32(packet, (int)i)).CopyTo(packet, i);
			Array.Resize(ref packet, packet.Length - 4);
			t1 = (Key & 0x3FFF) * (uint)Mul;
			t1 = t2 ^ BitConverter.ToUInt32(Keychain, (int)(t1 * 4));
			BitConverter.GetBytes(t1).CopyTo(packet, 4);
			Step = ((Step + 1) & 0x3FFF);
			HeaderXor = BitConverter.ToUInt32(Keychain, (int)((Step * Mul) * 4));
		}
 
Last edited by a moderator:
Back
Top