C/C++ En-tete TCP et protocole connexion

Inscrit
2 Juillet 2015
Messages
41
Reactions
0
#1
Bonjour!
Je suis nouveau sur ce forum et je découvre l'émulation dofus ;)
J'ai développé un sniffeur dofus avec la bibliothèque winpcap. (c'est équivalent à l'utilisation de wireshark).
J'ai filtré pour n'obtenir que les paquets échangés en TCP entre le jeu (mon client) et le serveur de connexion dont j'ai trouvé l'ip dans le "config.xml" (deux ips possibles).
Cependant bien que j’obtienne les paquets 3 et 4 qui ont une taille importante (>66 octets), je me demande à quoi servent les paquets qui font moins de 66 octets.
Le premier paquet qui va du client au serveur est la connexion du socket mais les autres? est ce que ce sont des paquets qui évitent la fermeture de la connexion ou ont ils un role précis? leur en-tete est il incomplet?

Je vous remercie de votre réponse, je suis débutant en programmation réseau ;)
 

zahid98

Membre Actif
Inscrit
13 Decembre 2014
Messages
352
Reactions
2
#2
La plus part des paquets "vides" servent de request demandant au serveur certaines informations , sinon pour l'ip que tu as trouvé dans le config.xml n'est que l'ip du LoginServer , l'ip du GameSever se trouve dans le SelectedServerDataMessage (Id 42 ) .
J’espère que je ne me suis pas trompé .
 
Inscrit
2 Juillet 2015
Messages
41
Reactions
0
#3
Bonsoir!
Merci beaucoup pour ta réponse, effectivement je m'en suis rendu compte, une fois connecté, plus aucun paquets n'arrivait. L'ip du serveur de jeu ne dépend pas du serveur choisi? il me semble pourtant.
 

BlueDream

Administrateur
Membre du personnel
Inscrit
8 Decembre 2012
Messages
2 010
Reactions
149
#4
Bonsoir,

Dans un premier temps le client se connecte au serveur de Login, les identifiants sont vérifiés.
Ensuite le client choisit le serveur de jeu sur lequel il souhaite se connecter, on lui fournit un tiquet et l'adresse du serveur de jeu.
Le client se connecte au serveur de Game, fournit le tiquet au serveur et basta :mrgreen:

La plus part des paquets vides, comme l'a dit Zahid, sont des 'Requests' : demande d'informations, actions en jeu ...

Pour pouvoir continuer ton sniffer il va falloir que tu récupères les informations contenues dans le paquet SelectedServerDataMessage (ou dérivé):

C#:
public class SelectedServerDataMessage : NetworkMessage
{

public const uint Id = 42;
public override uint MessageId
{
    get { return Id; }
}

public uint serverId;
        public string address;
        public ushort port;
        public bool canCreateNewCharacter;
        public sbyte[] ticket;
        

public SelectedServerDataMessage()
{
}

public SelectedServerDataMessage(uint serverId, string address, ushort port, bool canCreateNewCharacter, sbyte[] ticket)
        {
            this.serverId = serverId;
            this.address = address;
            this.port = port;
            this.canCreateNewCharacter = canCreateNewCharacter;
            this.ticket = ticket;
        }
        

public override void Serialize(IDataWriter writer)
{

writer.WriteVarShort((int)serverId);
            writer.WriteUTF(address);
            writer.WriteUShort(port);
            writer.WriteBoolean(canCreateNewCharacter);
            writer.WriteVarInt((int)(ushort)ticket.Length);
            foreach (var entry in ticket)
            {
                 writer.WriteSByte(entry);
            }
            

}

public override void Deserialize(IDataReader reader)
{

serverId = reader.ReadVarUhShort();
            if (serverId < 0)
                throw new System.Exception("Forbidden value on serverId = " + serverId + ", it doesn't respect the following condition : serverId < 0");
            address = reader.ReadUTF();
            port = reader.ReadUShort();
            if (port < 0 || port > 65535)
                throw new System.Exception("Forbidden value on port = " + port + ", it doesn't respect the following condition : port < 0 || port > 65535");
            canCreateNewCharacter = reader.ReadBoolean();
            var limit = (ushort)reader.ReadVarInt();
            ticket = new sbyte[limit];
            for (int i = 0; i < limit; i++)
            {
                 ticket[i] = reader.ReadSByte();
            }
            

}


}

Bonne chance :D
 
Dernière édition:
Inscrit
2 Juillet 2015
Messages
41
Reactions
0
#5
Bonsoir!
Merci pour votre réponse très complète, mais comment savez-vous que ce sont des requêtes?
Si j'ai bien compris ce sont juste des en-tête tcp qui sont envoyés?
C'est pas plutôt une façon de dire "youhou je suis la" et d’éviter la fermeture de la connexion?
si j'ai compris le fonctionnement du système :
le client se connecte au serveur de connexion et lance un socket tcp vide.
Le serveur de connexion lui envoie la clef RSA.
Le client prend la clef, crypte les identifiants et les renvoi
Le serveur accepte ou refuse la connexion.

(je me répète un peu, au risque de paraitre obtus mais je ne voudrai pas mal interpréter vos infos)
 

BlueDream

Administrateur
Membre du personnel
Inscrit
8 Decembre 2012
Messages
2 010
Reactions
149
#6
Tu as bien compris le fonctionnement de l'envoi des identifiants, c'est un RSA assez basique malgré quelques modifications de la part d'Ankama.
Pour ce qui est du protocole, @Labo et @bouh2 ( https://cadernis.fr/index.php?threads/comprendre-le-protocole-de-d20.115/ PS: je ne trouve pas le lien de Labo, désolé pour le favoritisme :mrgreen: ) ont écrits de très bons tutoriels, je ne pourrais pas mieux te l'expliquer qu'eux.

Pour que tu comprennes mieux le fonctionnement de la connexion, nous allons passer par des logs.

Serveur <- ID=1 ProtocolRequired Version du protocole nécessaire pour communiquer
Serveur <- ID=3 HelloConnectMessage Informations permettant le cryptage RSA
Client -> ID=4 IdentificationMessage Envois des identifiants cryptés
Serveur <- ID=10 LoginQueueStatusMessage Place dans la file d'attente
Serveur <- ID=6314 CredentialsAcknowledgementMessage Le serveur reconnait la clé utilisé pour le cryptage
Serveur <- ID=22 IdentificationSuccessMessage Identifiants validés
Serveur <- ID=30 ServersListMessage Liste des serveurs de jeu
Client -> ID=40 ServerSelectionMessage Choix du serveur
Serveur <- ID=42 SelectedServerDataMessage Informations pour la connexion au serveur de jeu (Ticket, Address, Port..)

Ensuite le Client se connecte au serveur de jeu.

Serveur <- ID=1 ProtocolRequired Version du protocole nécessaire pour communiquer
Serveur <- ID=101 HelloGameMessage Bonjour :ugeek:
Client -> ID=110 AuthenticationTicketMessage Envoi du ticket
Serveur <- ID=111 AuthenticationTicketAcceptedMessage Ticket validé, Bienvenue

Voilà, nous allons nous arrêter la dans les logs. L'ensemble des noms de paquets que j'ai utilisé sont les noms officiels utilisés par Ankama.
Tu peux les retrouver en décompilant les sources du client (JPEXS par exemple).

Tu peux aussi ajouter un fichier 'debug.txt' vide dans le dossier 'app' de ton jeu (penses à redémarrer le client), et lorsque tu le souhaite, tu peux générer un rapport en appuyant sur la touche F11.
Tu auras accès a tout le trafic du client et d'autres informations très utiles.

Bonne chance
 

zahid98

Membre Actif
Inscrit
13 Decembre 2014
Messages
352
Reactions
2
#7
Voilà le lien du tutoriel de labo : viewtopic.php?f=25&t=1523 .
Concernant les requêtes , le nom du paquet montre son rôle , tu peux utiliser le sniffer d'BlueDream (viewtopic.php?f=41&t=1816) pour voir les échanges client/serveur officiaux espérant que ça t'éclairera .
 
Dernière édition par un modérateur:
Inscrit
2 Juillet 2015
Messages
41
Reactions
0
#8
Merci beaucoup!
On ne peut pas faire plus complet!
Je vais regarder ça et je reviendrai vous montrer mon avancée!
Merci pour les liens, j'avais déjà vu ces deux posts, c'est pour cela que l'histoire des en-têtes de 66 octets me surprenait :)

Bonne soirée!
 

Labo

Membre Actif
Inscrit
16 Aout 2013
Messages
799
Reactions
15
#9
Merci zahid98 :) Alexandre tu exagères, le lien est dans ma signature, donc sur à peu près la moitié des topics du forum ! (tu l'as peut-être pas trouvé parce qu'il est dans la partie Analyse)
Sinon, il faut savoir que le protocole TCP, contrairement à l'UDP, vérifie à chaque fois que le message envoyé a bien été reçu (en gros). D'où ces paquets en apparence vides. Même si je salue tes efforts pour avoir fait ton propre sniffeur (moi il m'a fallu plusieurs heures, peut-être aussi parce que je pouvais pas utiliser pcap), il est peut-être plus convivial au début pour regarder le protocole d'utiliser wireshark, qui indique par exemple quels paquets contiennent des données (ils ont un champ data). Enfin tu as visiblement déjà largement dépassé ce stade. Je sais pas comment c'est avec pcap, mais par exemple avec scapy que j'ai utilisé ici, on a une méthode "haslayer(Raw)".
Bonne chance !
 

zahid98

Membre Actif
Inscrit
13 Decembre 2014
Messages
352
Reactions
2
#10
HS : 10Eu Mr.Labo , on fait pas de la pub gratuite ici quand même ... :lol:
 
Haut Bas