=============================================
========= FANTASY TENNIS PACKET SYSTEM ========
============== by AnotherCoder ==============
=============================================
1. ENCRYPTION
2. PACKET STRUCTURE
Code:
[COLOR="Navy"]for(int i = 0; i < packet_size; i++)
{
decrypted_packet[i] = encrypted_packet[i] ^ XOR_Table[(i&3)];
}
1. ENCRYPTION
The packet encryption of Fantasy Tennis is very simple, it is just a normal XOR encryption.
If you do not know what a XOR encryption is, or how to use it in your programming language,
look it up.
Here are some nice explanations:
Exclusive or - Wikipedia, the free encyclopedia
Bitwise operation - Wikipedia, the free encyclopedia
I will not go any further into explaining what XOR is because most programmers have already used it,
and if you do not know what it is then I am sure that you will not understand anything of this thread anyway.
Okay so let us continue.
Fantasy Tennis uses a 4-byte XOR-table to encrypt their packets here is an example of how it works:
So let us say this is our encrypted packet buffer:
{c6 89 7c 39 d3 9d 78}
and this is our XOR-table:
{a3, f1, 1d, 54}
then you have to decrypt the buffer like this:
c6 XOR a3 = 65
89 XOR f1 = 78
7c XOR 1d = 61
39 XOR 54 = 6d
d3 XOR a3 = 70
9d XOR f1 = 6c
78 XOR 1d = 65
the decrypted packet would be:
HEX: {65 78 61 6d 70 6c 65}
ASCII: example
packet[0] XOR table[0], packet[1] XOR table[1], packet[2] XOR table[2],
packet[3] XOR table[3], packet[4] XOR table[0], packet[5] XOR table[1] ...
I hope you get what I mean ;) you use the first byte of the table to decrypt the first byte of the packet, then the second byte of the table to decrypt the second byte of the packet...and the fourth byte of the table to decrypt the fourth byte of the packet AND THEN the first byte of the table again, to decrypt the fifth byte of the packet and so on.
a C/C++ implementation would be:
So you might be wondering, uhh? Where do I get the XOR-table from? Well good question.
Once you connect to a Fantasy Tennis server, regardless of whether it is a login or a gameserver, the server sends you an unencrypted packet which contains the XOR-tables. Tables? Yes 1 table for send and 1 table for recv ;)
I will give you an example, so well give me a few seconds to start FantasyTennis...
Ok this is the packet that I received:
00 00 00 00 9A FF 10 00 B8 35 14 9F F6 BA 09 78 04 00 00 00 00 00 00 00
B8 35 14 9F <- send XOR-table
F6 BA 09 78 <- recv XOR-table
after I received this packet from the server, the client sent this packet:
AA 67 5F 98 19 3A 03 9F D9 35 75 9F D9 35 75 9F D9 35 14 9F D9 54 75 FE D9 35 82 3F C9 37 14
So let us try to decrypt it with the XOR-table we have got:
Code:
[COLOR="Navy"] unsigned char packet[] = {[COLOR="DarkRed"]0xAA, 0x67, 0x5F, 0x98, 0x19, 0x3A, 0x03, 0x9F, 0xD9, 0x35, 0x75, 0x9F, 0xD9, 0x35, 0x75, 0x9F, 0xD9, 0x35, 0x14, 0x9F, 0xD9, 0x54, 0x75, 0xFE, 0xD9, 0x35, 0x82, 0x3F, 0xC9, 0x37, 0x14[/COLOR]};
unsigned char xor[] = {[COLOR="RoyalBlue"]0xB8, 0x35, 0x14, 0x9F[/COLOR]};
for(int i = 0; i < 31; i++)
{
printf("%02x ", packet[i]^xor[(i&3)]);
}[/COLOR]
ASCII : ↕ R K í ☼ ↨ a a a a a a a a a a û á q ☻
I logged in with aaaaa aaaaa, so yeah it worked :) the packet is decrypted, nice done.
2. PACKET STRUCTURE
2bytes [header1]
2bytes [header2]
2bytes [packetId]
2bytes [data_size]
x bytes [data] x = data_size
Example: Let us use the login packet from above
12 52 4b 07 a1 0f 17 00 61 00 61 00 61 00 61 00 61 00 00 00 61 61 61 61 61 00 96 a0 71 02 00
That is all :) you can now decrypt and encrypt the packets from send / recv and should be able to unterstand their structure.
You cannot edit or send your own packets yet because header1 and header2 differ between each packet and has to be built by yourself.
I will show you how to do that if this thread attracts enough skilled programmers who know what they do ;)
and do not forget to press the thanks button ;)
[/COLOR]
ZeroTen / AnotherCoder