And also a way to check out whats in the packets hex and do simple operations like XOR. I suggest 010 Hex Editor its amazing.
Packets are the things that hold data to be communicated between the server and client, or client too client(s).
Since it is a communication each packet can be thought of as a message.
The message has information, but the information is only useful if the other end knows what the message is about. So that the receiver knows what the context of the message is there is usually a PacketID.
In binary based protocols there is usually 1 byte or 2 byte sometimes even 4 that are prefixed to the data of the message. This says what the packet is for. In text based protocols there is usually just a command. For example in HTTP there is the action command of GET or POST or whatever.
If the data is sent over UDP then the packet when/if it is received will always be the exact size it was when sent. With TCP since it is a stream not all data may be at the endpoint after a RECV similarly more data might be there.
So it is common when using TCP to use fixed sized packets or to have a unsigned short or unsigned int that is in the first spot of the packet that says how much data the other end should read for the message. In this case its often before any packet id and the other end makes sure it receives >= that amount of data before it can be processing the message.
So we now know that there is usually an ID or a Size and ID.
Both ends of the communication agree on packet id's there is usually an order to them.
Either its one end sends 01 and other end sends 01+1 for the reply
Or one end sends 01 and the other end replys with 01.
But it might also be possible for them to reply with something else depending on the type of command. Or even replying with nothing. No reply is still communicating :) Just like in real life if someone says Hey and you don't like them or are mad at them and ignore them. Thats still communicating a message of I don't wanna talk to you.
What about the message that the packet has the data after these?.
Well not all packets require data some might be an instruction for example a Keep Alive packet that most games send might be the client sends a 04 and the server sends a 05 in reply. Keep Alive's are an important feature in UDP where packets are not reliable. or Reliable UDP even. But in TCP I think its rather useless as its a stream it sends underlying packets that the OS handles to let you know the state of the connection. UDP is connectionless you just send the data and hope it makes it.
However in some things it might be handy to send a keep alive on TCP for example you might want to detect speed hacking. If the game client sends a packet every 10 seconds and all of a sudden you are getting them quicker than expected the user is probably speed hacking or spamming the packet. You have to take latency into account of course.
Oh and before I forget. TCP the packets end up at the other end in the order you sent them. In UDP your packets can end up in a mixed order. So it may be a good idea to have a sequence or a CommandNumber which is just the packet count or command count respectfully. The sequence number can be used to reorder the packets or perhaps ignore older ones. And a CommandNumber can be used when you send a command packet but don't expect it to be processed by the server sequentially. For example when you login to a server it would probably be sequential *We send packet server replys we send another etc* but when in game you would want to be able to send packets asyncronously that means in any order. With a CommandNumber you can send a command to the server and when it replys you can note that the reply has happened for that action. For example file transfer or a request for cam in a chat client would use this method. Similarly it might just ask the server for permission to create a request ID which you would get back and then the server sends you the reply for that ID and all communications might have that ID in it. MSNP for exmaple uses that for their switchboard sessions.
So onto the data and of course Cryptography.
If the data is not encrypted you will see the same data each time. An easy test is to get the game or software to send a packet for something you know like a username or a chat message. If you see the text in your sniffed packet you know its plain text there for no encryption.
If you cannot see the message at all in plain text or unicode plain text then the data is most likely encrypted.
If you send the same message twice and see the same data in the sniffed packets apart from perhaps a sequence number or command number then you can be sure the data is encrypted with something that is symmetric. That means the same every time.
If the data is different then it might just be a different key or perhaps a slightly trickyer crypt.
Another test I like to do is send my message with all 1 character apart from the last.
For example I might send a message like this.
In this example its plain text. You can see the packet id is 0C and that its a dynamic message. The size of the chat message is next as a unsigned short. 25 characters. And then there is the chat message with null terminator. *The prefix of message size is for speed knowing it rather than looking increases speed of the operation to copy/use it for something.
If the data were encrypted like this and its the same each time
Then I can be sure that the encryption is most likely 1 operation in a for loop for the size. Possibly XOR
If it is XOR then 00^EA would == EA so we would know that the key is EA. We can see it twice in this packet where the 00 would be.
You see the pattern of 83's were the i's would be.
If they are not like that and it was 83 84 85 86 83 84 85 86 then it would be xor but it would add 1 each time to the key to a point then reset it to the start.
If it is something like 83 91 23 14 83 91 23 14 then its a pattern still. Either its - or + the base key of EA or its another key altogether. It is also possible for a block cipher to be used. This changes a block. Blowfish is quite a common one. I won't show the data here but basically all the data in blocks of 4 is encrypted. if theres any remaining its not encrypted thats an easy way to tell if you send a plain text message of uneven size.
In a block cipher the data may even look something like this
83 83 83 83 85 85 85 85 81 81 81 81 82 82 82 82
There are also obfuscating techniques that can be done to the data like rearranging it. I won't go into detail on these but if you step through the ASM code for the encrypt/decrypt you can most likely reverse it.
If they use XOR then its budget and cheap and basically not even worth it. It only prevents noobs wanting to make packet hacks, server side emulators or bots. If you are a noob and couldn't get around this before well you have information right here to get past it.
for (int i=0;i<buffersize;i++)
XOR encrypt and decrypt are the same.
Next in the series will probably be using OllyDBG to find the GameSend GameRecv Encrypt and Decrypt functions. As well as identifying what encryption a game uses. And maybe even how to call the functions from a DLL.
I might write more here later for other things to do with packets.