async def wrap(protocol, data): data = ByteArray(data) packet_len = Int16.decode(data[:2]) - 2 data = ByteArray(data[2:]) if not packet_len == len(data): log.error("Data len byte doesnt match data length.") return await func(protocol, data)
def parse(cls, data: ByteArray, client: "LoginClient"): data = ByteArray(data[1:]) encrypted = ByteArray(data[0:128]) key = client.rsa_key.m2crypto_key decrypt = key.private_decrypt(bytes(encrypted), RSA.no_padding) login = decrypt[94:107] password = decrypt[108:124] return cls(String.decode(login), String.decode(password))
def test_add_checksum(data, result): data = ByteArray(bytes.fromhex(data)) result = ByteArray(bytes.fromhex(result)) @add_checksum def _add_checksum(_data): return _data assert _add_checksum(data) == result
def generate_game_key(cls): key = ByteArray(os.urandom(8)) key.append(Int8(0xc8)) key.append(Int8(0x27)) key.append(Int8(0x93)) key.append(Int8(0x01)) key.append(Int8(0xa1)) key.append(Int8(0x6c)) key.append(Int8(0x31)) key.append(Int8(0x97)) return key
def parse(cls, data, client): client.xor_key = LoginXorKey(Int32.decode(data[-8:-4])) data = xor_decrypt_login(lambda packet_cls, data, client: data)(cls, data, client) data = data[1:] client.session_id = Int32.decode(data[0:4]) client.protocol_version = Int32.decode(data[4:8]) client.rsa_key = L2RsaKey.from_scrambled(bytes(ByteArray(data[8:136]))) client.blowfish_key = BlowfishKey(bytes(ByteArray(data[152:168]))) return cls(client)
def read(cls, data, start): from common.helpers.bytearray import ByteArray from common.datatypes.integer import UInt16 pos = start string = ByteArray(b"") while pos < len(data): if UInt16(data[pos:pos + 2]) != 0: string += ByteArray(data[pos:pos + 2]) pos += 2 else: pos += 2 break return cls(bytes(string).decode("utf-16")), pos
def test_verify_checksum(data): data = ByteArray(bytes.fromhex(data)) @verify_checksum def _verify_checksum(packet, _data, *args): return _data assert _verify_checksum(None, data) is not None
def test_Init_encrypt_decrypt(client): out = Init(client).encode(client) session_id = client.session_id blowfish_key = client.blowfish_key.key client.blowfish_key.key = client.blowfish_key.static LoginServerPacket.decode(ByteArray(out[2:]), client) assert client.blowfish_key.key == blowfish_key assert client.session_id == session_id
def __init__(self, value): from common.helpers.bytearray import ByteArray if isinstance(value, Int): super(self.ctype, self).__init__(value.value) elif isinstance(value, DataType): super(self.ctype, self).__init__(value.data) elif isinstance(value, list): super(self.ctype, self).__init__(int.from_bytes(bytes(ByteArray(value)), "little")) else: super(self.ctype, self).__init__(int(value))
def unscramble_mod(cls, n: bytes) -> int: n = ByteArray(n) for i in range(0x40): n[0x40 + i] = n[0x40 + i] ^ n[i] for i in range(4): n[0x0d + i] = n[0x0d + i] ^ n[0x34 + i] for i in range(0x40): n[i] = n[i] ^ n[0x40 + i] for i in range(4): temp = n[0x00 + i] n[0x00 + i] = n[0x4d + i] n[0x4d + i] = temp return int.from_bytes(bytes(n), "big")
def scramble_mod(self) -> bytes: n = ByteArray(self.n_bytes) # step 1: 0x4d - 0x50 <-> 0x00 - 0x04 for i in range(4): n[i], n[0x4d + i] = n[0x4d + i], n[i] # step 2 : xor first 0x40 bytes with last 0x40 bytes for i in range(0x40): n[i] = n[i] ^ n[0x40 + i] # step 3 : xor bytes 0x0d-0x10 with bytes 0x34-0x38 for i in range(4): n[0x0d + i] = n[0x0d + i] ^ n[0x34 + i] # step 4 : xor last 0x40 bytes with first 0x40 bytes for i in range(0x40): n[0x40 + i] = n[0x40 + i] ^ n[i] return bytes(n)
def body(self): data = ByteArray(b"") for arg in self.arg_order: data.extend(getattr(self, arg).encode()) return data
def encode(self, client): arr = ByteArray(self.type.encode()) arr.append(Int32(len(self.characters))) for character in self.characters: pass return arr
def encode(self, client): arr = ByteArray(self.type.encode()) arr.append(Int8(len(self.servers))) arr.append(Int8(client.account.latest_server)) for server in self.servers: arr.extend(Int8(server.id)) arr.append(Int8(server.ip[0])) arr.append(Int8(server.ip[1])) arr.append(Int8(server.ip[2])) arr.append(Int8(server.ip[3])) arr.append(Int32(server.port)) arr.append(Int8(server.age_limit)) arr.append(Int8(server.is_pvp)) arr.append(Int16(server.online)) arr.append(Int16(server.max_online)) arr.append(Int8(server.is_online)) arr.append(Int32(server.server_type)) arr.append(Int8(server.brackets)) arr.append(Int8(0)) return arr
def parse(cls, data, client): data = ByteArray(data[1:]) login_ok1 = data[0:4] login_ok2 = data[4:8] server_id = data[8] return cls(login_ok1, login_ok2, server_id)
def decode(cls, data): from common.helpers.bytearray import ByteArray if isinstance(data, list): data = bytes(ByteArray(data)) return cls(int.from_bytes(data, "little", signed=cls.signed))
def encode(self): from common.helpers.bytearray import ByteArray return ByteArray(self.value.to_bytes(self.length, "little", signed=self.signed))
def encrypt(self, packet: ByteArray, init=False): if init: encrypted = ByteArray(b"".join(self.static_encoder.encrypt_ecb(bytes(packet)))) else: encrypted = ByteArray(b"".join(self.encoder.encrypt_ecb(bytes(packet)))) return encrypted
def decrypt(self, data): return ByteArray(b"".join(self.encoder.decrypt_ecb(bytes(data))))
def encode(self, client): arr = ByteArray(self.type.encode()) encrypt_arr = ByteArray(b"") encrypt_arr.pad(128) encrypt_arr[0x5b] = 0x24 enc_login = self.login.encode() enc_password = self.password.encode() encrypt_arr[0x5e:0x5e + len(enc_login)] = enc_login encrypt_arr[0x6c:0x6c + len(enc_password)] = enc_password key = client.rsa_key.m2crypto_key encrypted_login_info = key.public_encrypt(bytes(encrypt_arr), RSA.no_padding) arr += ByteArray(encrypted_login_info) arr.append(client.session_id) arr += ByteArray([ 0x23, 0x01, 0x00, 0x00, 0x67, 0x45, 0x00, 0x00, 0xab, 0x89, 0x00, 0x00, 0xef, 0xcd, 0x00, 0x00 ]) arr += ByteArray( [0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]) footer = ByteArray(b"") footer.pad(16) arr += footer return arr