-
Member
Need help with packet decryption
I'm developing own core from scratch, using Python3. I'm using 2.4.3 client. I have HeaderCrypt class for encrypting and decrypting World packets. Currently I have the problem: only first packet decrypts successfully, another packets decrypts with wrong opcode. At the same time encrypting of packets processing without problems.
So, only the first packet (CMSG_CHAR_ENUM) decrypts successfully, but sometimes some packets like CMSG_PING also decrypts, but only one time (for example, from two CMSG_PING packets only first will be decrypted with correct opcode).
The HeaderCrypt initializes with session_key only one time, before SMSG_AUTH_RESPONSE sending. I need assistance with debugging the problem. The HeaderCrypt code below, if you need something else please tell me.
Code:
class HeaderCrypt(object):
ENCRYPT_HEADER_SIZE = 4
DECRYPT_HEADER_SIZE = 6
def __init__(self, session_key: bytes):
self.crypt_key = self._generate_key(session_key)
self.send_i = 0
self.send_j = 0
self.recv_i = 0
self.recv_j = 0
def encrypt(self, data: bytes):
assert len(data) >= self.ENCRYPT_HEADER_SIZE
encrypted_header = [0] * self.ENCRYPT_HEADER_SIZE
for index in range(self.ENCRYPT_HEADER_SIZE):
self.send_i %= len(self.crypt_key)
enc = (data[index] ^ self.crypt_key[self.send_i]) + self.send_j
enc %= 0x100
self.send_i += 1
encrypted_header[index] = self.send_j = enc
return bytes(encrypted_header) + data[self.ENCRYPT_HEADER_SIZE:]
def decrypt(self, data: bytes):
assert len(data) >= self.DECRYPT_HEADER_SIZE
decrypted_header = [0] * self.DECRYPT_HEADER_SIZE
for index in range(self.DECRYPT_HEADER_SIZE):
self.recv_i %= len(self.crypt_key)
dec = (data[index] - self.recv_j) ^ self.crypt_key[self.recv_i]
dec %= 0x100
self.recv_i += 1
self.recv_j = data[index]
decrypted_header[index] = dec
return bytes(decrypted_header) + data[self.DECRYPT_HEADER_SIZE:]
def _generate_key(self, session_key):
seed = b'8\xa7\x83\x15\xf8\x92%0q\x98g\xb1\x8c\x04\xe2\xaa'
hashed = hmac.new(seed, session_key, sha1)
return hashed.digest()
If somebody can explains the alg for packet decryption this will be very nice.
Last edited by /dev/not/null; 12-24-2018 at 03:28 PM.
-
Member
I think the reason in self.recv_i. I tried experimenting with it, for example, I added +3 to self.recv_i after for loop and this allow me to parse CMSG_PLAYER_LOGIN in 100%, if nothing was sended from client. I continuing...
-
The WoW memory editing forum section may be a better place to ask these questions, but be sure to read the rules.
https://www.ownedcore.com/forums/wor...emory-editing/
-
Post Thanks / Like - 1 Thanks
/dev/not/null (1 members gave Thanks to stoneharry for this useful post)
-
Elite User
I encountered the same problem in a different wow project I'm working on. Packet decryption breaks after entering world, and I was fortunate enough to find the workaround Sergio came up with to get around this weird issue, so I wanted to post it here for anyone who might struggle with this in the future.
idewave-core/WorldPacketManager.py at master . sergio-ivanuzzo/idewave-core . GitHub
Hack fix for packet decryption breaking after entering world. . ratkosrb/ReplayCore@857ffea . GitHub
Attempting to decrypt the packet a second time will fix it, but I still have no idea why this happens. I also notice it will break again after entering world if I do something that causes the client to send multiple packets rapidly, like spinning my character in random directions really fast, which spams the server with MSG_MOVE_SET_FACING.
Edit: I think I discovered the real cause of this issue shortly after posting this. I was receiving the packets from the network, processing them, and sending a reply all in the same thread. It appears this was causing a bottleneck, and some of the client packets were getting lost, which led to the counter inside the decryption code which increments with each packet to fall behind, thus it would no longer decrypt incoming packets properly. This would explain why trying to decrypt the packet a second time like Sergio was doing would fix it, as the counter would catch up through this looping. After moving the packet processing into a separate thread, this problem appears to have gone away completely.
Separate packet processing into a separate thread. . ratkosrb/ReplayCore@24c81ae . GitHub
Last edited by brotalnia; 04-17-2021 at 05:43 AM.
-
Post Thanks / Like - 1 Thanks
stoneharry (1 members gave Thanks to brotalnia for this useful post)