Recently, I have nothing to worry about. I have studied how to send and receive packets for a magic domain game. Next I will share some of the packet sending content with you.
I believe that people who have performed Reverse Analysis on the game know that sending packets can accomplish many unexpected functions. If these functions call the call of the game itself, the operation is very complicated. Therefore, sending packets simplifies the reverse gaming process. Sending subcontracting is the omnipotent key to control the game.
It is not complicated to look for the function of sending a magic domain package. What's complicated is how to find the plaintext of the package data, that is, to find the encryption function of the package data. In fact, this is not difficult. As long as you follow the regular method and patiently look for it, in the end, the game will be displayed to you like a girl whose clothes are stripped by you. Don't talk nonsense. The procedure is as follows:
- Breakpoint at the sending of the packet sending function. Make an action, such as selling items. This means that the game will be disconnected from the place where packets are sent. If you look at the sending data buffer, you will find that all the data in the buffer is ciphertext, with the same action, and the packet data is completely different. Therefore, we must find the function of packet encryption.
- The hardware write breakpoint in the ciphertext package. This is another item, and you will find that the game is disconnected from another place. Cancel a hardware breakpoint. Returns the upper-level function. You will find that a parameter of the function is the packet sending buffer of the send function. Obviously, this function is the packet encryption function. The compilation code is as follows:
Encryption:
00dc0630 55 push EBP
00dc0631 8b6c24 0C mov EBP, dword ptr [esp + C]
00dc0635 56 push ESI
00dc0636 33f6 xor esi, ESI
00dc0638 85ed test EBP, EBP
00dc063a 7E 6e jle short 00dc06aa
00dc063c 57 push EDI
00dc063d 8b7c24 10 mov EDI, dword ptr [esp + 10]
00dc0641 33c0 XOR eax, eax
00dc0643 8a81 04040000 mov Al, byte PTR [ECx + 404]
00dc0649 8a5408 04 mov DL, byte PTR [eax + ECx + 4]
00dc064d 8a043e mov Al, byte PTR [ESI + EDI]
00dc0650 32c2 XOR Al, DL
00dc0652 88043e mov byte PTR [ESI + EDI], Al
00dc0655 8ad0 mov DL, Al
00dc0657 33c0 XOR eax, eax
00dc0659 8a81 04040000 mov Al, byte PTR [ECx + 404]
00dc065f 8a8408 04020000 mov Al, byte PTR [eax + ECx + 204]
00dc0666 02c2 add Al, DL
00dc0668 33d2 XOR edX, EDX
00dc066a 88043e mov byte PTR [ESI + EDI], Al
00dc066d 8a91 05040000 mov DL, byte PTR [ECx + 405]
00dc0673 8a940a 04010000 mov DL, byte PTR [edX + ECx + 104]
00dc067a 32d0 xor dl, Al
00dc067c 33c0 XOR eax, eax
00dc067e 88143e mov byte PTR [ESI + EDI], DL
00dc0681 8a81 05040000 mov Al, byte PTR [ECx + 405]
00dc0687 8a8408 04030000 mov Al, byte PTR [eax + ECx + 304]
00dc068e 02c2 add Al, DL
00dc0690 8ad0 mov DL, Al
00dc0692 c0ea 04 shr dl, 4
00dc0695 c0e0 04 SHL Al, 4
00dc0698 0ad0 or DL, Al
00dc069a 88143e mov byte PTR [ESI + EDI], DL
00dc069d 66: ff81 0404000> Inc word PTR [ECx + 404]
00dc06a4 46 Inc ESI
00dc06a5 3bf5 cmp esi, EBP
00dc06a7 ^ 7C 98 JL short 00dc0641
00dc06a9 5f pop EDI
00dc06aa 5E pop ESI
00dc06ab 5d pop EBP
00dc06ac C2 0800 retn 8
3. Find the socket of the send function. This step is relatively simple. As long as the API function is disconnected at send and the query is returned, socke is near the function header.
4. send packets. Because both socket and plain text have been found, you can directly call the send function to send packets with specific actions like the game server.
Int my_encfunc (INT gamekey, int data, int Len)
{
Int Len;
Int I;
Int data;
Int result;
Char value1;
Unsigned _ int8 value_data;
Char value2;
Unsigned _ int8 V10;
Len = Len;
I = 0;
If (LEN> 0)
{
Data = data;
Do
{
Value1 = * (byte *) (gamekey + 0x404) + gamekey + 4) ^ * (byte *) (I + data );
* (Byte *) (I + Data) ^ = * (byte *) (gamekey + 0x404) + gamekey + 4 );
Value_data = value1 + * (byte *) (gamekey + 0x404) + gamekey + 0x204 );
* (Byte *) (I + Data) = value_data;
Value2 = value_data ^ * (byte *) (gamekey + 0x405) + gamekey + 0x104 );
* (Byte *) (I + Data) = value2;
Result = * (byte *) (gamekey + 0x405 );
* (Byte *) (& result) = value2 + * (byte *) (result + gamekey + 0x304 );
V10 = (byte) Result> 4;
* (Byte *) (& result) = 16 * (byte) result;
* (Byte *) (I + Data) = (byte) Result | V10;
+ + * (Word *) (gamekey + 0x404 );
++ I;
}
While (I <Len );
}
Return result;
}
Int my_decfunc (INT gamekey, int data, int Len)
{
Int Len;
Int I;
Int data;
Int result;
Char value1;
Unsigned _ int8 value_data;
Char value2;
Int value3;
Len = Len;
I = 0;
If (LEN> 0)
{
Data = data;
Do
{
Value1 = (unsigned _ int8) (16 ** (byte *) (I + Data) | (unsigned _ int8) (* (byte *) (I + Data)> 4 );
* (Byte *) (I + Data) = (unsigned _ int8) (16 ** (byte *) (I + Data) | (unsigned _ int8) (* (byte *) (I + Data)> 4 );
Value_data = value1-* (byte *) (gamekey + 0x407) + gamekey + 0x304 );
* (Byte *) (I + Data) = value_data;
Value2 = value_data ^ * (byte *) (gamekey + 0x407) + gamekey + 0x104 );
* (Byte *) (I + Data) = value_data ^ * (byte *) (gamekey + 0x407) + gamekey + 0x104 );
Result = * (byte *) (gamekey + 0x406 );
Value3 = * (byte *) (gamekey + 0x406 );
* (Byte *) (& result) = value2-* (byte *) (value3 + gamekey + 0x204 );
* (Byte *) (I + Data) = value2-* (byte *) (value3 + gamekey + 0x204 );
* (Byte *) (I + Data) = (byte) Result ^ * (byte *) (gamekey + 0x406) + gamekey + 4 );
+ + * (Word *) (gamekey + 0x406 );
++ I;
}
While (I <Len );
}
Return result;
}
For example, selling things
Char sendstr [0x14] = {0 };
....
....
// Construct the sendstr Parameter
My_encfunc (gamekeythis, sendstr, 0x14 );
Send (sockthis, sendstr, 0x14,0 );