예제 #1
0
 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)
예제 #2
0
 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))
예제 #3
0
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
예제 #4
0
 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
예제 #5
0
 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)
예제 #6
0
    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
예제 #7
0
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
예제 #8
0
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
예제 #9
0
    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))
예제 #10
0
    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")
예제 #11
0
    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)
예제 #12
0
 def body(self):
     data = ByteArray(b"")
     for arg in self.arg_order:
         data.extend(getattr(self, arg).encode())
     return data
예제 #13
0
 def encode(self, client):
     arr = ByteArray(self.type.encode())
     arr.append(Int32(len(self.characters)))
     for character in self.characters:
         pass
     return arr
예제 #14
0
 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
예제 #15
0
 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)
예제 #16
0
    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))
예제 #17
0
 def encode(self):
     from common.helpers.bytearray import ByteArray
     return ByteArray(self.value.to_bytes(self.length, "little", signed=self.signed))
예제 #18
0
 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
예제 #19
0
 def decrypt(self, data):
     return ByteArray(b"".join(self.encoder.decrypt_ecb(bytes(data))))
예제 #20
0
    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