1.29 Protocol dofus 1.29

Inscrit
5 Decembre 2010
Messages
114
Reactions
0
#1
Bonjour à tous,

Je suis actuellement en train de développer un bot MITM pour dofus 1.29 et pour ce faire j'aimerais savoir si il existait une source d'information concernant le fonctionnement du protocol de communication de dofus 1.29 (comment identifier les paquets, comment les comprendre, les lire, les écrire ...) un peu a l'instar du toto de Bouh2 sur le protocol de dofus 2.0.
J'ai déjà mener quelque recherche de mon côté et je suis tombé sur cette image qui récapitule un peu le fonctionnement du protocol 1.29 mais pas dans son intégralité je pense notamment aux paquets transmis lors des combats ou lors des échanges par exemple :

Je me tourne donc vers vous pour en savoir un peu plus sur le fonctionnement du protocol de communication de D1.29.

Cordialement,
Kangogoo.
 

Pièces jointes

Inscrit
1 Juin 2016
Messages
20
Reactions
2
#2
Tout n'est pas expliqué effectivement, mais il est très facile de sniffer les paquets soit-même: ce ne sont que des chaînes de caractères, même pas chiffrées. L'interprétation et l'envoi se trouvent tous deux dans les sources de Dofus, sinon oui, il n'y a qu'à sniffer quels paquets sont envoyés pour faire tels actions.
 
Inscrit
5 Decembre 2010
Messages
114
Reactions
0
#3
Je te remercie de ta réponse @Misuki

Pourrais-tu m'indiquer ou je pourrais trouver les sources du jeu car il me semble de ne pas les posséder directement sur mon disque (malgré l'installation du jeu et après lecture des fichiers swf) ? Notamment pour comprendre comment est encodé l'ip du serveur de jeu et le port pour pouvoir par la suite les remplacer par mon ip local.

Cordialement,
Kangogoo
 
Inscrit
1 Juin 2016
Messages
20
Reactions
2
#4
En général, tout ce qu'il te faut se trouve dans loader.swf (à décompiler avec JPEXS par exemple).
 
Inscrit
5 Decembre 2010
Messages
114
Reactions
0
#5
En général, tout ce qu'il te faut se trouve dans loader.swf (à décompiler avec JPEXS par exemple).
J'ai bien trouver la fonction qui déchiffre l'adresse ip envoyer avec le paquet AXK :
Code:
var _loc8_ = sExtraData.substr(0,8);
            var _loc9_ = sExtraData.substr(8,3);
            var _loc7_ = sExtraData.substr(11);
            var _loc10_ = new Array();
            var _loc11_ = 0;
            while(_loc11_ < 8)
            {
               var _loc12_ = _loc8_.charCodeAt(_loc11_) - 48;
               var _loc13_ = _loc8_.charCodeAt(_loc11_ + 1) - 48;
               _loc10_.push((_loc12_ & 15) << 4 | _loc13_ & 15);
               _loc11_ = _loc11_ + 2;
            }
            var _loc5_ = _loc10_.join(".");
            var _loc6_ = (ank.utils.Compressor.decode64(_loc9_.charAt(0)) & 63) << 12 | (ank.utils.Compressor.decode64(_loc9_.charAt(1)) & 63) << 6 | ank.utils.Compressor.decode64(_loc9_.charAt(2)) & 63;
que j'ai reproduis en C# (avec les valeurs en dures)
C#:
// IP
            string data = "50>?:=:7";
            char[] c = data.ToCharArray();
            int i = 0;
            List<int> toto = new List<int>();
            while (i < 8)
            {
                int a = c[i] - 48;
                int b = c[i + 1] - 48;
                toto.Add((a & 15) << 4 | b & 15);
                i = i + 2;
            }
            string res = "";
            foreach (var item in toto)
            {
                res += item.ToString() + ".";
            }
            Console.Write(res);
            // PORT
            char[] p = "ag7".ToCharArray();
            string port = ((DAOUtils.Decode64(p[0]) & 63) << 12 | (DAOUtils.Decode64(p[1]) & 63) << 6 | DAOUtils.Decode64(p[2]) & 63).ToString();
            Console.Write(":" + port);
Mais maintenant pour reproduire l'effet inverse je sèche un peu, surtout pour encoder l'ip :(
 

Arth

Contributeur
Inscrit
28 Aout 2016
Messages
80
Reactions
3
#6
Salut,
pour t'aider, il faut savoir qu'une adresse IP est souvent écrite dans une chaîne de caractère. Et c'est le cas ici, même si elle est un peu étrange.
Donc quand tu fait des opérations sur les caractères, tu devrait le faire avec d'autre caractère ^^

tu as une valeur 48 qui semble un peu étrange, mais en vérité, si tu la convertie en code ascii cela donne le caractère zéro '0'.

Donc si je ré-écrit cela (en C/C++, mais l'idée est la même) :
C++:
int a = (int)(c[i] - '0');
int b = (int)(c[i + 1] - '0');

Tu pourrait alors demander :
Mais cela sert à quoi de soustraire un caractère à un autre ?
tout simplement à récupérer la valeur qui correspond au caractère, c'est pas forcement très claire alors voila des exemples:
'0' - '0' = 48 - 48 = 0
'1' - '0' = 49 - 48 = 1
'2' - '0' = 50 - 48 = 2
...
'9' - '0' = 57 - 48 = 9
...
'?' - '0' = 63 - 48 = 15

On voit que cela marche bien :p !


Pour la ligne suivante :
Code:
toto.Add((a & 15) << 4 | b & 15);
Lorsque l'on fait du traitement bit à bit, la notation hexadécimal ou binaire des nombres est plus judicieuse:
Code:
toto.Add((a & 0b1111) << 4  |  b & 0b1111);
Du coup, maintenant, on voit plus clairement qu'on stock les 4 premiers bit de a et b dans un seul octet.
Et si on réfléchi un peu, nos valeurs sont des nombres entre 0 et 15, cela tient donc juste dans 4 bits, cela veut dire qu'on ne perd pas d'information dans a et b.
Et la donnée reconstitué est un octet, il en faut 4 pour faire une adresse IP. (en IP V4 en tout cas)
Cela tombe bien il y a une boucle qui parcours chaque caractères de la chaîne, et il y a 8 caractères.

Maintenant tu as juste à faire l’opération inverse : prendre les 4 octets de l'IP, chaque octet est découpé en bloc de 4 bits, qui sont convertis en code ASCII lisible.
C'est important de bien comprendre un algo avant de faire le changement de langage, et encore plus pour faire la fonction inverse.

J’espère que cela va t'aider !
Bonne chance
 
Dernière édition:
Inscrit
5 Decembre 2010
Messages
114
Reactions
0
#7
Merci pour ta réponse et tes explications on ne peut plus claire @Arth , un grand merci :)
J'ai bien compris comment fonctionner l'encodage de l'adresse IP et du port grâce à toi et j'ai pu faire mes deux petites fonctions pour encoder une ip et un port en respectant le format attendu par le jeu.
C#:
        /// <summary>
        /// Méthode pour encoder une adresse ip selon l'encodage de D
        /// </summary>
        /// <param name="ip">Ip à encoder</param>
        /// <returns>Ip encodée</returns>
        public static string EncodeIPAdress(string ip)
        {
            string res = "";
            foreach (string part in ip.Split('.'))
            {
                string bin = Convert.ToString(Convert.ToInt32(part), 2).PadLeft(8, '0');
                int dec = Convert.ToInt32(bin.Substring(0, 4), 2);
                res += ((char)(dec + '0'));
                dec = Convert.ToInt32(bin.Substring(4, 4), 2);
                res += ((char)(dec + '0'));
            }
            return res;
        }

        /// <summary>
        /// Méthode pour encoder le port selon l'encodage de D
        /// </summary>
        /// <param name="port">port à encoder</param>
        /// <returns>port encodé</returns>
        public static string EncodePort(int port)
        {
            string res = "";
            string bin = Convert.ToString(port, 2).PadLeft(18, '0');
            for (int cpt = 0; cpt <= 12; cpt += 6)
            {
                res = res + DAOUtils.Encode64(Convert.ToInt32(bin.Substring(cpt, 6), 2));
            }
            return res;
        }
Le méthode Encode64 proviens directement des sources du jeu
Maintenant j'ai juste une petite question pour mon MITM mais c'est pour être sur d'avoir bien compris :
  • Lors de la réception du paquet AXK je vais devoir "l'intercepter" et remplacer l'ip: port du serveur de jeu par mon ip: port local
  • Envoyer le paquet modifier au client
  • Déconnecter ma socket au serveur d'authentification
  • Reconnecter ma socket au serveur de jeu sur l'ip: port reçu dans le AXK
Est-ce le bonne marche à suivre et le bon ordre d’enchaînement des actions ?

Cordialement,
Kangogoo
 

ToOnS

Membre Actif
Inscrit
8 Avril 2009
Messages
974
Reactions
0
#8
oui c'est ca , sauf peut etre le 3ieme point qui se fait tout seul (c'est le serveur qui va deco ton socket) mais tu peux quand meme le faire pour etre sur que c'est fait avant de reco au serveur de jeu et n'oubli pas de remettre le socket bot/client en ecoute (avec le bon port si tu le changes entre 2) , histoire que le client ai de quoi se connecter quelquepart parceque le client va se deco de ton socket bot/client en pensant se deco du serveur de connections (ou faut que tu forces sa deco depuis ton socket, je sais plus mais dans les 2 cas le client sera deco et tentera de se reco au soit disant serveur de jeu donc a ton socket bot/client)
 
Dernière édition:
Inscrit
5 Decembre 2010
Messages
114
Reactions
0
#9
Merci @ToOnS

Autre petites questions subsidiaires concernant la lecteur des paquets :
  • (1) : J'ai actuellement deux classes différentes, une pour lire les paquets envoyés par le client (DAOClientSideReader.cs) et une autre pour lire les paquets envoyés par le serveur (DAOServerSideReader.cs). La première lit donc uniquement les paquets envoyés depuis le client de jeu vers mon serveur local et la second lit les paquets envoyés depuis le serveur de D. vers mon client local (faux client). Est-ce la bonne méthode à adopter ?
  • (2) : Un simple String.Contains(); suffit-il pour identifier les paquets ? Une regex est-elle préférable ?
  • (3) : Faut-il un reader par couple vrai/faux client ou un seul reader pour l'ensemble des clients suffit-il ?
Cordialement,
Kangogoo
 

ToOnS

Membre Actif
Inscrit
8 Avril 2009
Messages
974
Reactions
0
#10
1 : une seule classe suffit , de toute facon c'est la meme , tu peux l'appeler dans les 2 sens , apres dans le sens DAOClientSideReader.cs , je doute que tu ais un jour a t'en servir
2 : pour identifier oui ca suffit , apres pour separer faut regex
3 : un seul suffit pour le memes raison que 1

edit : pour 2 verifier quand meme que c'est bien au depart du string ou ne verifier que les 3 premiers caracteres , si jamais un petit malin se met a taper un ID dans le chat
 
Dernière édition:
Inscrit
5 Decembre 2010
Messages
114
Reactions
0
#11
2 : pour identifier oui ça suffit , après pour séparer faut regex
edit : pour 2 verifier quand meme que c'est bien au depart du string ou ne verifier que les 3 premiers caracteres , si jamais un petit malin se met a taper un ID dans le chat
Oui justement j'y avais penser aussi c'est pour ça que j'ai remplacer mon String.Contains(); par une String.StartWith(); pour m'assurer de comparer uniquement les premiers caractères de la chaine.
J'ai également déclarer une petit méthode utilitaire pour séparer les données reçu dans le cas ou plusieurs message sont envoyé en même temps (un simple split sur le byte 0 a fais l'affaire).

Par contre pour séparer les données dans un même message j'y vais a coup de String.Substring(int offset, int lenght); , si on prends l'exemple du paquet AXK qui est écrit comme ci :
"AXK" + 8 caractères pour l'ip + 3 caractères pour le port + 7 caractères pour le GUID
Je me contente de faire une message.Substring(3, 8); pour récupérer les caractères concernant l'adresse ip, et ainsi de suite pour le reste des données mais est-ce que cela suffit-il ou vaut-il mieux vraiment passer par une regex ?
Étant donné que la version 1.29 du jeu n'est pas amené à être mise à jour, les paquets non plus, est-il vraiment nécessaire de vérifier le bon formatage des données avant de les lires ?

Cordialement,
Kangogoo
 

Arth

Contributeur
Inscrit
28 Aout 2016
Messages
80
Reactions
3
#12
Les Regex c'est cool, mais c'est pas magique, il n'y a pas vraiment de raison que cela soit plus performant qu'un simple split, par contre le code des regex est sûrement plus opti (je pense qu'il évite de faire des split de partout car c'est lourd de copier des données). Au final c'est plus ou moins équivalent (à part si tu code très mal, et dans un langage pas top ;)) et surtout pour un bot.

Dans les sources 1.29, je n'ai pas de souvenir qu'il utilise la moindre regex. Cela veut dire qu'il faudra que tu les écrivent toi même.

Pour la propreté du code, cela dépend de comment tu l’écrit.
 
Inscrit
1 Juin 2016
Messages
20
Reactions
2
#13
Pas besoin de regex pour ce genre de chaînes. Elles ne sont pas trop complexes.
 
Inscrit
20 Janvier 2017
Messages
5
Reactions
0
#14
Pas besoin de regex pour ce genre de chaînes. Elles ne sont pas trop complexes.
Pour avoir étudié ce protocole dans les détails je peut t'assurer qu'elles le sont (aka GameMovement), et je peut aussi assurer que tout parse en regex est un acte de suicide :teeth: ! @Misuki Toi qui code un bot tu est bien placé pour le savoir (d'ailleurs je confirme que si en plus de faire un bot tu t'amuse a flood t'es un vrai cancer :mad:.. Pourquoi les gens n'ont pas des projets intéressant qui font avancer la commu plutôt de que de la polluer -_- et oui je sait tu te moque de notre avis)

J'ai fait avec un collègue un grosse library java du protocol et je t'aurai aidé avec plaisir si ton but n'était pas d'en faire en bot (étant joueur je suis plutôt maladif de bots :vicieux:)
cependant pour que ce msg ne soit pas non plus inutile, plutôt que de t'amuser avec jpexs utilise plutôt le repo d'émudofus (j'ai juste fork pour back au commit de suppression 1.29)

T'a aussi sur le forum plusieurs tuto sur le parsing du protocol
Enfin bon j’espère que tu t'en servira pour fait autre chose qu'un bot sérieux y'a déjà des centaines de kevin qui détruise les serveurs restant n'en devient pas un :(

(et en passant change de langage par pitié :p)
 
Dernière édition:
Inscrit
1 Juin 2016
Messages
20
Reactions
2
#15
GameMovement est un 'packet' complexe effectivement. Je parlais plutôt de "pas trop complexes" dans le sens où tu n'as réellement pas besoin de te triturer la tête avec des regex pour parse les messages, à part si, comme tu le dis, tu es suicidaire.

Je ne sais pas toi, mais personnellement je trouve cela assez contre-productif de lui dire de changer de langage ET de lui proposer ton aide "si il ne codais pas un bot". La plupart des nouveaux dans le domaines veulent découvrir et comprendre comment ça fonctionne justement dans le but d'en créer des tâches automatisées, et un langage de haut niveau est parfaitement adapté à ce genre de personne. Ici surtout, il y a beaucoup de ressources en C#.Net, alors c'est même plutôt "intelligent" si il ne connait justement pas ce monde.

Merci pour le git, après il aurait très bien pu exporter les scripts sur sa machine à l'aide de JPEXS (au final, ça revient au même :) ).

Juste pour en revenir à ces "centaines de kevin qui détruise les serveurs" à cause de la création de bot, je dirais que c'est une bonne expérience dans le domaine de la programmation de créer un bot complètement. Parfois même, c'est les premiers "vrais projets" de certains, et en fin de compte on apprend vraiment plein de choses quand on n'avait jamais fait ça avant.

Étant donné que la version 1.29 du jeu n'est pas amené à être mise à jour, les paquets non plus, est-il vraiment nécessaire de vérifier le bon formatage des données avant de les lires ?
Je dirai que oui. On est jamais trop prudent après tout, il suffit que tu reçoives mal une data pour que ton appli crash par exemple. C'est un choix à faire :)
 
Inscrit
20 Janvier 2017
Messages
5
Reactions
0
#16
C'est une très bonne expérience en effet mais ils ne vont jamais se restreindre à une utilisation privée ou honnête.. par conséquent ça participe à la destruction des serveurs offis..
 
Inscrit
5 Decembre 2010
Messages
114
Reactions
0
#18
J'ai fait avec un collègue un grosse library java du protocol et je t'aurai aidé avec plaisir si ton but n'était pas d'en faire en bot (étant joueur je suis plutôt maladif de bots :vicieux:)
Enfin bon j’espère que tu t'en servira pour fait autre chose qu'un bot sérieux y'a déjà des centaines de kevin qui détruise les serveurs restant n'en devient pas un :(
Je t'invite à aller faire un tour du côter de la section "Projets" pour comprendre que je ne souhaite pas faire un bot à proprement dit comme tu sembles le penser si fortement.
T'a aussi sur le forum plusieurs tuto sur le parsing du protocol
Je pense être présent sur ce forum depuis un bon petit moment maintenant pour avoir lu l'ensemble des tutos sur les différentes versions du protocol de D.
(et en passant change de langage par pitié :p)
Je répondrais simplement :
Je ne sais pas toi, mais personnellement je trouve cela assez contre-productif de lui dire de changer de langage ET de lui proposer ton aide "si il ne codais pas un bot". La plupart des nouveaux dans le domaines veulent découvrir et comprendre comment ça fonctionne justement dans le but d'en créer des tâches automatisées, et un langage de haut niveau est parfaitement adapté à ce genre de personne. Ici surtout, il y a beaucoup de ressources en C#.Net, alors c'est même plutôt "intelligent" si il ne connait justement pas ce monde.
Disons juste qu'après être passer par le C, le C++, le JAVA, le Python, le C# est la suite logique du langage dans le quel j'ai envie de m'investir à présent.
Juste pour en revenir à ces "centaines de kevin qui détruise les serveurs" à cause de la création de bot, je dirais que c'est une bonne expérience dans le domaine de la programmation de créer un bot complètement. Parfois même, c'est les premiers "vrais projets" de certains, et en fin de compte on apprend vraiment plein de choses quand on n'avait jamais fait ça avant.
Exactement, la création de bot ou d'outils externe apparentés à des bots est un très bon moyen pour apprendre un langage et toutes ses spécificités qu'on à pas forcement l'occasion d'aborder que soit durant les études ou dans le monde du travail (Socket, multithreading, protocol réseau, ...).
ils ne vont jamais se restreindre à une utilisation privée ou honnête..
C'est partout pareil j'ai envie de te dire.

Kangogoo.
 
Inscrit
20 Janvier 2017
Messages
5
Reactions
0
#19
My bad alors même si je comprend pas comment tu peut apprécier le C# ou même le java après être passé par le C++ u_u
 
Inscrit
31 Octobre 2016
Messages
1
Reactions
0
#20
Grace à votre aide j'ai réussi a crée mon bot en MITM, merci ;)
 
Haut Bas