0

I made a DLL that hooks the send function of an MMORPG game. When the send() function is called, it will send the packet in a loop until I stop it instead of just sending the packet one time.

My problem is the packets are encrypted. And, the server checks every packet sent from the client. If the packet that the server expect does not match from what the client sent, the server will disconnect you. So, even if you disable the encryption code in the client, it will still get verified on the server side.

I manage to disable the encryption of the packet by modifying the binary but I still get disconnected because of the above statement. And, I can't send it in an infinite loop because each packet should be different.

Info:

  • Only the packets sent from client to server are encrypted. The packets from server to client are not encrypted.
  • Only the first 2 bytes of the packet is encrypted. The remaining 8 bytes are not. The size of the packet is 10 bytes.
  • I found the function (written in assembly) where it generates the dynamic key used to encrypt the first 2 bytes. I wanted to use that codes but I don't know how to translate them into a higher level language like c++.

Decryption Function

unsigned short clif_decrypt_cmd( int cmd, struct map_session_data *sd ) {
  if (sd) {
    return (cmd ^ ((sd->cryptKey >> 16) & 0x7FFF));
  }
  return (cmd ^ ((((clif->cryptKey[0] * clif->cryptKey[1]) + clif->cryptKey[2]) >> 16) & 0x7FFF));
}

Question:

  • How can I achieve my goal to send the packet in an infinite loop if each packet is checked by the server?
  • Should I use the function that encrypts the first two bytes before sending each time I send it?
4
  • 1
    why do you need to send the same packet in a loop? are you trying to DDoS the server?
    – Igor Skochinsky
    Aug 8, 2017 at 8:59
  • 1
    add the disassembly of the function which "generates the dynamic key used to encrypt the first 2 bytes"
    – Igor Skochinsky
    Aug 9, 2017 at 13:13
  • so you want to cheat yourself but not let others cheat? I'm not sure I want to go along with that...
    – Igor Skochinsky
    Aug 9, 2017 at 15:11
  • @NoobProgrammer I guess anyone who is able to write game cheats isn't dependent on your asm snippet. Aug 11, 2017 at 15:12

1 Answer 1

3

First of all the statement

If the packet that the server expect does not match from what the client sent, the server will disconnect you.

makes no sense.

How would the server know what you are going to send to him?
Maybe you ment that the server disconnects you if you malform the packet (change the structure of the packet - or, for example, by disabling the packet encryption - in this case the server would try to decrypt it and would get non interpretable results).

So to answer your question:

IMO you have two possible ways to achieve your goal:

  1. Find the function that creates the packet before it is encrypted and use it to send your own data.
  2. Understand how the network protocol and cryptography of your game works and rebuild it in your own program.

I'd suggest you use the first option since it's the simpler one. While the second option provides you more flexibility I don't think it's feasable for you since you said but I don't know how to translate them into a higher level language like c++..

I can only provide you with general instructions since you didn't post much information about your target (name, some assembly snippets, if it uses TCP or UDP, ..):

  1. Use a dynamic debugger to find the function mentioned in #1. I prefer x64dbg since it works for both, x86 and x64 bit applications.
  2. Set a breakpoint on the socket send function. Which send function is used depends on your game but possible candidates are send, sendto, WSASend and WSASendTo.
  3. Find the used send function by placing a breakpoint on all of them and watch which bp triggers. Now you know which function is used to send the data to the game server. I'll use WSASendTo in this example since it's very common in modern udp applications (I assume your game uses UDP - I could be wrong tho).
  4. As you know by the documentation of WSASendTo the function takes a pointer to one or more WSABUF structures as second argument. Usually it's just one WSABUF.
  5. Since almost every windows api function is a __stdcall the second argument will be at [esp+0x8] when your breakpoint triggers ([esp] is the return address, [esp+0x4] is the first argument _In_ Socket s).
  6. If you use x64dbg you can now follow the pointer to the WSABUF structure "in dump" to see the contents of it. You can also follow the return address at [esp] to find the function which called WSASendTo.
  7. You will probably need to restart the game a few times and set new breakpoints on the function which called the windows send function.
  8. At some point you will see that the contents of the buffer change - you said that only the first two bytes are encrypted, so you already know at what to put your eyes at.
  9. At this point you should know which function is responsible for encrypting your data. Maybe this is already all you need - maybe you need to go a bit higher in the calling hierarchy to find the function which actually starts the whole packet create-encrypt-send process.

Hope that helps!

2
  • Well, as Mr. Skochinsky already said, it's very hard to help you without any asm snippets. Please consider adding some more information to you question so I can update my answer. BTW if you use x64dbg, why is the question tagged with ollydbg? Aug 14, 2017 at 10:30
  • Sorry, but I can't find the x64dbg tag. So I tagged it with ollydbg and IDA. I edited the question and added the decryption code on the server side. BTW, thank you for the time give an answer to my question. Aug 14, 2017 at 15:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.