C/C++ Quelques problèmes avec IdentificationMessage (id=4)

A

Anonymous

Invité
#1
Bonjour à tous,

Je me suis depuis 3 jours à essayer de créer un bot dofus (je remercie par la même occasion pour votre forum où j'ai récupéré beaucoup d'information).
Mon problème se situe sur la création du message 4 : je reçois bien le message 3 (HelloConnectMessage) avec le salt et la clé.
Voici ma classe qui permet de désérializer le message 3 : https://github.com/wamilou/DofusBot/blo ... essage.cpp
Et voici ma classe pour créer le message 4 : https://github.com/wamilou/DofusBot/blo ... essage.cpp

Maintenant en cherchant bien j'ai vu que pour créer le credential à envoyer, il fallait encoder avec le nom d'utilisateur et le mot de passe, mais je ne sais pas comment faire tout ça.
Après j'ai tout ce qu'il me faut : sources de Dofus, une sauvegarde d'un échange avec Wireshark pour analyser quand j'ai besoin.

D'autres part, je sais pas si ma fonction pour écrire un double est bonne :
Code:
void Packet::writeDouble(double val)
{
char *buftmp = new char [sizeof(double)];
*(double *)buftmp = val;
std::string str(buftmp);
int length = str.length();
for(int i=0; i<length; i++)
{
m_trame.push_back( str[i] );
m_curseur++;
}
}
Sinon le reste fonctionne correctement. J'ai juste du mal avec ça, vu que je suis "nouveau" dans ce domaine.
En espérant que quelqu'un pourra m'aiguiller sur ce que je dois faire, je vous remercie d'avance ! :)
 

BlueDream

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

ton code est assez maigre pour le IdentificationMessage.

Code:
//Flag

byte flag1 = 0;
flag1 = BooleanByteWrapper.SetFlag(flag1, 0, autoconnect);
flag1 = BooleanByteWrapper.SetFlag(flag1, 1, useCertificate);
flag1 = BooleanByteWrapper.SetFlag(flag1, 2, useLoginToken);
writer.WriteByte(flag1);

// Version

writer.WriteSByte(major);
writer.WriteSByte(minor);
writer.WriteSByte(release);
writer.WriteInt(revision);
writer.WriteSByte(patch);
writer.WriteSByte(buildType);

// VersionExtended

writer.WriteSByte(install);
writer.WriteSByte(technology);

// IdentificationMessage

writer.WriteUTF(lang);
writer.WriteUShort((ushort)credentials.Length);
foreach (var entry in credentials)
{
     writer.WriteSByte(entry);
}
writer.WriteShort(serverId);
writer.WriteDouble(sessionOptionalSalt);
Voila ce que cela donne avec des valeurs prédéfinis:

Code:
//Flag
writer.WriteByte(0);

//Version
writer.WriteSByte(2);
writer.WriteSByte(25);
writer.WriteSByte(1);
writer.WriteInt(90112);
writer.WriteSByte(3);
writer.WriteSByte(0);

// VersionExtended

writer.WriteSByte(1);
writer.WriteSByte(1);

// IdentificationMessage

writer.WriteUTF("fr");
writer.WriteUShort((ushort)credentials.Length);
foreach (var entry in credentials)
{
     writer.WriteSByte(entry);
}
writer.WriteShort(0);
writer.WriteDouble(0);
 
A

Anonymous

Invité
#3
Merci pour ta réponse. Effectivement, il me manquait quelques valeurs : au moins sa sera plus clair comme ça.
Une question par rapport à ton code, que signifie le S dans WriteSByte ?
Et aussi, par rapport au "credentials", faut-il le générer ? Si oui, comment ? Car je ne pense pas qu'il faut passer la clé récupérée directement.

Je sais que je vais paraitre pour un débutant, mais je ne comprends rien au code source de Dofus à par l'endroit où sont stockés les messages. Ex : où je peux voir comment on crée ce credential par exemple.
 
Inscrit
1 Mai 2014
Messages
20
Reactions
0
#4
Le credential c'est ton identifiant et ton mot de pass si j'ai bien suivi ^^(à confirmer)
 
A

Anonymous

Invité
#5
Oui, normalement encryptés avec la clé récupérée, je crois. Mais le problème, c'est que je sais pas dans quel ordre c'est encodé x)
 
Inscrit
1 Mai 2014
Messages
20
Reactions
0
#6
A vrai dire j'en suis au même stade que toi dans mon bot mais je me presse pas loin de là :D.
Il y avait le tuto de RaphyTheGeek publié en 2011 dans la section C# qui montre clairement que tu doit d'abord envoyer ton non de compte, ensuite envoyer ton mot de passe concaténé à la clé l'ensemble hashé avec MD5. Mais je doute que cela soit toujours d'actualité.
 
A

Anonymous

Invité
#7
Peut être, que cela marche toujours. A voir !

EDIT : Si quelqu'un peut confirmer ou expliquer, ça serait cool :)
 

ToOnS

Membre Actif
Inscrit
8 Avril 2009
Messages
974
Reactions
0
#8
Bonjour , non ca marche plus du tout mais alors plus du tout , c'est meme plus encodé avec le meme systeme
 
A

Anonymous

Invité
#9
As-tu donc des astuces comme les classes du client qui font ça ou directement un petit algorithme pour expliquer comment on crée ce credential ?

EDIT : En cherchant un peu, j'ai trouvé qu'il fallait utiliser le cryptage RSA mais je n'ai pas trouvé le librairie RSA en C++ pour le moment.
 
A

Anonymous

Invité
#11
Effectivement, je suis un bouley, j'y avais pas penser. Tu aurais un petit code d'exemple pour crypter ?
Et sinon pour le packet, je vais comment pour le credentials, j'y mets quoi exactement dedans ? Le nom d'utilisateur puis mot de passe tous les 2 cryptés ?
 

BlueDream

Administrateur
Membre du personnel
Inscrit
8 Decembre 2012
Messages
2 010
Reactions
149
#12
Le RSA de dofus est différent. Va voir dans les sources du côté de 'com/ankamagames/jerakine/utils/crypto/SignatureKey.as'.
 
A

Anonymous

Invité
#13
Merci ! J'ai regardé, effectivement, c'est pas tout à fait pareil.
Sinon je me demandais si vous connaissiez une petite librairie qui permet de manipuler des BigInteger en c++ : j'en ai trouvé sur le net, mais soit pas portable, soit trop vieille...
 

BlueDream

Administrateur
Membre du personnel
Inscrit
8 Decembre 2012
Messages
2 010
Reactions
149
#14
Je demanderais a gohu ce soir si il ne passe pas avant sur ce poste.
 

Gohu

Membre Actif
Inscrit
16 Novembre 2013
Messages
222
Reactions
2
#15
Tu as pas vraiment besoin, fin perso dans mon projet je ne les utilises pas
 

Labo

Membre Actif
Inscrit
16 Aout 2013
Messages
799
Reactions
15
#16
Même si tu en as besoin, tu peux toujours la programmer toi-même :)
Avec des tableaux (ou même des listes) d'int, c'est pas trop dur (sauf la multiplication).
Ou tu peux utiliser Qt.
 
A

Anonymous

Invité
#17
Bon voilà j'ai une petite erreur quand j'essaye de décrypter la clé reçue de 305 bytes.

Voici la clé publique du client que j'ai trouvé :


Je stock cette clé dans un std::string. Ensuite pour décrypter je fais ça :


Sauf que j'obtiens l'erreur : error0407006A:rsa routines:RSA_padding_check_PKCS1_type_1:block type is not 01

Est-ce que quelqu'un sait pourquoi ? J'ai bien ma clé reçu de 305 bytes copié dans inputSignature et buflen est égal à -1 donc il y a bien une erreur !
 

Gohu

Membre Actif
Inscrit
16 Novembre 2013
Messages
222
Reactions
2
#18
Tu as vérifié que la clef du client que tu utilises était la plus récente ? ou l'as tu trouvée ?
 
A

Anonymous

Invité
#19
C'est bon j'ai résolu mon problème ! Par contre maintenant, il y a un truc que j'ai du mal à comprendre.
Je me connecte maintenant au serveur de jeu Dofus où il faut que j'envoie un ticket de connexion précédé de la langue. Mais j'arrive pas à trouver d'où on tire ce ticket :/
Quelqu'un pourrait me dire à quoi ça correspond exactement ?
 

BlueDream

Administrateur
Membre du personnel
Inscrit
8 Decembre 2012
Messages
2 010
Reactions
149
#20
SelectedServerDataMessage, paquet 42, variable Ticket.
 
Haut Bas