Decodage packet

Inscrit
5 Mai 2023
Messages
2
Reactions
0
#1
Bonjour,
Je suis actuellement en train de travailler sur la capture de paquets pour le jeu en ligne Dofus. J'ai réussi à récupérer plusieurs paquets et à identifier leur contenu et leur ID.
Cependant, je rencontre des difficultés lors du décodage du contenu du paquet. J'ai essayé plusieurs méthodes de décodage (UTF8, Latin1), mais je n'arrive pas à obtenir un texte lisible.
Si vous avez des connaissances ou des suggestions pour m'aider à décoder ces paquets, je vous serais reconnaissant de bien vouloir me les partager.
Merci d'avance pour votre aide.

Exemple :
45450364b9198805180006011f012c013a014701550171000042671aec2024a00016a4 => 4433 | BasicAckMessage
Mais pas si je décode le contenue => EESÿAw¥~¦~§~¨~
Merci d'avance
 
Inscrit
20 Octobre 2021
Messages
50
Reactions
42
#2
Salut,

Comment tu connais l'ID du paquet ? Déjà ça à l'air d'être du D2 (tu ne le précises pas) ensuite tu n'as pas l'air du tout de maîtriser la façon de lire les paquets ... Voir le tuto https://cadernis.com/index.php?threads/comprendre-le-protocole-de-dofus.115/

Sur D2 aucun texte brute n'est disponible il faut d'abord lire le header qui est sur 2 bytes. Ici tu as 4545 qui correspond à "10001010100101"

Il faut faire un >> 2 et un & 3 ce qui donne comme résultat:
"00100010101001" = ID 4433
"00000000000001" = Taille 1

Ton paquet à une taille lisible en 1 seul byte, le byte suivant est "03", ton paquet 4433 est : "45450364b919" le reste est un nouveau paquet.

Quand on regardes les sources de D2 fichier "com.ankamagames.dofus.network.messages.game.basic.BasicAckMessage"

Il contient ceci:

Code:
public function deserializeAs_BasicAckMessage(input:ICustomDataInput) : void {
    this._seqFunc(input);
    this._lastPacketIdFunc(input);
}
private function _seqFunc(input:ICustomDataInput) : void {
    this.seq = input.readVarUhInt();
    if(this.seq < 0) {
        throw new Error("Forbidden value (" + this.seq + ") on element of BasicAckMessage.seq.");
    }
}

private function _lastPacketIdFunc(input:ICustomDataInput) : void {
    this.lastPacketId = input.readVarUhShort();
    if(this.lastPacketId < 0) {
        throw new Error("Forbidden value (" + this.lastPacketId + ") on element of BasicAckMessage.lastPacketId.");
    }
}
Ton paquet contient alors 1 readVarUhInt et 1 readVarUhShort (les trucs chiants de D2 un Uh n'est pas fixe en nombre de bytes ..).
Donc déjà ton paquet 4433 contient que 3 bytes qui sont 2 chiffres.


À partir de là on peut vite voir les paquets sans même les traduire:

4545 03 64b919 (4433 BasicAckMessage)
8805 18 0006011f012c013a014701550171000042671aec2024a000 (8705 GameMapMovementMessage)
16a4 (1449 BasicNoOperationMessage)

Dans ton extrait il y à alors 3 messages. Le premier contient 3 bytes, le deuxième 24 et le dernier 0.

Pour le fun ton GameMapMovementMessage:

Code:
  public function deserializeAs_GameMapMovementMessage(input:ICustomDataInput) : void   {
     var _val1:* = 0;
     var _keyMovementsLen:uint = uint(input.readUnsignedShort());
     for(var _i1:Number = 0; _i1 < _keyMovementsLen; _i1++)      {
        _val1 = uint(input.readShort());
        this.keyMovements.push(_val1);
     }
     this.forcedDirection = input.readShort();
     this.actorId = input.readDouble();
  }
_keyMovementsLen = 00 06 (6)

il y à donc 6 cases entre le premier et derniers mouvement voici les cellId:

01 1f (287)
01 2c (300)
01 3a (314)
01 47 (327)
01 55 (341)
01 71 (369)

forcedDirection = 00 00 (0)
actorId = 42 67 1a ec 20 24 a0 00 (4784822730558317000)

Je penses sincèrement que tu n'as pas chercher avant d'écrire, je prends du temps pour te montrer tes erreurs, j'espères que cela te seras utiles.
 
Inscrit
5 Mai 2023
Messages
2
Reactions
0
#3
Bonjour,
Je suis ravi de recevoir votre message. Bien que je sois encore novice dans ce domaine, je suis disposé à étudier attentivement toutes les informations que vous avez fournies. Mon ami et moi-même cherchions simplement des orientations pour nous aider à avancer dans notre quête.
Je tiens à vous remercier sincèrement pour votre aide. Votre générosité et votre dévouement à notre égard sont très appréciés. Je suis impatient de suivre vos conseils et d'apprendre davantage sur ce sujet fascinant.
 
Inscrit
4 Avril 2020
Messages
6
Reactions
0
#4
Hello !

Il semblerait que l'actorId ne soit pas correct car il dépasse la valeur de sécurité (inscrit dans le code source) qui est de
9007199254740992

J'ai pas forcément de solution car il semblerait que la sérialization soit faite comme ça. Tu as une idée ?
 
Inscrit
20 Octobre 2021
Messages
50
Reactions
42
#5
Hello !

Il semblerait que l'actorId ne soit pas correct car il dépasse la valeur de sécurité (inscrit dans le code source) qui est de
9007199254740992

J'ai pas forcément de solution car il semblerait que la sérialization soit faite comme ça. Tu as une idée ?
J'ai vu ça aussi, aucune idée ! Je n'ai pas regarder comment il est utilisé
 
Inscrit
4 Avril 2020
Messages
6
Reactions
0
#6
En fait ce que je ne comprends pas c'est comment ils connaissent le nombre d'octet en entrée ? (je suis novice sur le traitement de packet mais ça m'interesse)
Par exemple pour les fonctions readDouble() ou readUTF(), comment ils savent le nombre d'octet à traiter ? Il est pas spécifier dans le code ...
Par exemple pour la class ChatAbstractServerMessage (qui est le parent de la classe ChatServerMessage) on a :
Code:
_channelFunc(input) {
    this.channel = input.readByte();
    if (this.channel < 0) {
      throw new Error(`Forbidden value (${this.channel}) on element of ChatAbstractServerMessage.channel.`);
    }
  }

  _contentFunc(input) {
    this.content = input.readUTF();
  }

  _timestampFunc(input) {
    this.timestamp = input.readInt();
    if (this.timestamp < 0) {
      throw new Error(`Forbidden value (${this.timestamp}) on element of ChatAbstractServerMessage.timestamp.`);
    }
  }

  _fingerprintFunc(input) {
    this.fingerprint = input.readUTF();
  }
ces 3 fonctions sont appelé à la suite :
Code:
deserializeAs_ChatAbstractServerMessage(input) {
    this._channelFunc(input);
    this._contentFunc(input);
    this._timestampFunc(input);
    this._fingerprintFunc(input);
  }
A quel moment ils peuvent connaitre la taille en octet à lire ? -_-
 
Inscrit
20 Octobre 2021
Messages
50
Reactions
42
#7
Le double c'est 8 bytes c'est fixe l'utf tu as 2 bytes avant pour avoir la taille de caractère tout est déjà expliqué dans les tutos

Après pour savoir ça tu peux regarder les fonctions directement dans le code source qui sont utilisés pour faire les read

Et les fonctions ils ont juste ranger tu vas lire les fonctions tu as 1 read a chaque fonctions.
 
Dernière édition:
Inscrit
4 Avril 2020
Messages
6
Reactions
0
#8
Tu aurais des liens de tutos qui explique ça stp ?
 
Inscrit
20 Octobre 2021
Messages
50
Reactions
42
#9
Tu aurais des liens de tutos qui explique ça stp ?
Regarde partie Tutoriel sur le site, mais sinon il suffit de regarder les fonctions dans la programmation.

Exemple de : com.ankamagames.jerakine.network.CustomDataWrapper

Code:
private static const INT_SIZE:int = 32;
private static const SHORT_SIZE:int = 16;
private static const SHORT_MIN_VALUE:int = -32768;
private static const SHORT_MAX_VALUE:int = 32767;
private static const UNSIGNED_SHORT_MAX_VALUE:int = 65536;
private static const CHUNCK_BIT_SIZE:int = 7;
private static const MAX_ENCODING_LENGTH:int = Math.ceil(INT_SIZE / CHUNCK_BIT_SIZE);
private static const MASK_10000000:int = 128;
private static const MASK_01111111:int = 127;


public function readVarInt() : int {
 var b:int = 0;
 var value:int = 0;
 var offset:int = 0;
 var hasNext:* = false;
 while(offset < INT_SIZE)
 {
    b = int(this._data.readByte());
    hasNext = (b & MASK_10000000) == MASK_10000000;
    if(offset > 0)
    {
       value += (b & MASK_01111111) << offset;
    }
    else
    {
       value += b & MASK_01111111;
    }
    offset += CHUNCK_BIT_SIZE;
    if(!hasNext)
    {
       return value;
    }
 }
 throw new Error("Too much data");
}


public function readVarShort() : int{
 var b:int = 0;
 var value:int = 0;
 var offset:int = 0;
 var hasNext:* = false;
 while(offset < SHORT_SIZE)
 {
    b = int(this._data.readByte());
    hasNext = (b & MASK_10000000) == MASK_10000000;
    if(offset > 0)
    {
       value += (b & MASK_01111111) << offset;
    }
    else
    {
       value += b & MASK_01111111;
    }
    offset += CHUNCK_BIT_SIZE;
    if(!hasNext)
    {
       if(value > SHORT_MAX_VALUE)
       {
          value -= UNSIGNED_SHORT_MAX_VALUE;
       }
       return value;
    }
 }
 throw new Error("Too much data");
}


private function readInt64(input:IDataInput) : Int64 {
 var b:* = 0;
 var result:Int64 = new Int64();
 var i:* = 0;
 while(true)
 {
    b = uint(input.readUnsignedByte());
    if(i == 28)
    {
       break;
    }
    if(b < 128)
    {
       result.low |= b << i;
       return result;
    }
    result.low |= (b & 127) << i;
    i += 7;
 }
 if(b >= 128)
 {
    b &= 127;
    result.low |= b << i;
    result.high = b >>> 4;
    i = 3;
    while(true)
    {
       b = uint(input.readUnsignedByte());
       if(i < 32)
       {
          if(b < 128)
          {
             break;
          }
          result.high |= (b & 127) << i;
       }
       i += 7;
    }
    result.high |= b << i;
    return result;
 }
 result.low |= b << i;
 result.high = b >>> 4;
 return result;
}

private function readUInt64(input:IDataInput) : UInt64 {
 var b:* = 0;
 var result:UInt64 = new UInt64();
 var i:* = 0;
 while(true)
 {
    b = uint(input.readUnsignedByte());
    if(i == 28)
    {
       break;
    }
    if(b < 128)
    {
       result.low |= b << i;
       return result;
    }
    result.low |= (b & 127) << i;
    i += 7;
 }
 if(b >= 128)
 {
    b &= 127;
    result.low |= b << i;
    result.high = b >>> 4;
    i = 3;
    while(true)
    {
       b = uint(input.readUnsignedByte());
       if(i < 32)
       {
          if(b < 128)
          {
             break;
          }
          result.high |= (b & 127) << i;
       }
       i += 7;
    }
    result.high |= b << i;
    return result;
 }
 result.low |= b << i;
 result.high = b >>> 4;
 return result;
}
 
Inscrit
4 Avril 2020
Messages
6
Reactions
0
#10
Thanks ! J'avais pas capter que cadernis était un site quasi spécialisé dans dofus :)
Yes j'ai déjà implémenté cette classe et celle chatServerMessage en nodejs, tout fonctionne bien après pas mal d'ajustement :(
Plus qu'à faire la même avec les autres classes qui m'intéresse :D :D
 
Haut Bas