C/C++ Packet ID 3

Gohu

Membre Actif
Inscrit
16 Novembre 2013
Messages
222
Reactions
2
#1
Bonjour/Bonsoir

J'ai un petit problème avec mon script C++ qui possède un thread qui écoute l'ip du serveur de connexion D2 (213.248.126.39, sur le port 5555) sauf que je ne reçois que très rarement le packet d'ID 3...
J'ai l'impression que ca deconne.

Mon code:
Code:
#include "SocketIO.h"

SocketIO::SocketIO(const QString &serverIp, const quint16 &port) :
    m_serverIp(serverIp),
    m_port(port),
    m_socket(NULL)
{   
    tryConnect();
}

SocketIO::~SocketIO()
{
    m_socket->disconnectFromHost();
    delete m_socket;
}

bool SocketIO::tryConnect(bool tryUntilConnection)
{
    delete m_socket;
    m_socket = new QTcpSocket(this);
    m_socket->connectToHost(QHostAddress(m_serverIp),m_port);

    if (!m_socket->waitForConnected(WAIT_TIME_CONNECTION))
    {
        m_isActive = false;
        qDebug()<<"SOCKET - CONNECTION SERVEUR : " +m_serverIp+ "  PORT : " + QString::number(m_port)+ "  A  ECHOUEE";
             if (tryUntilConnection)
        QTimer::singleShot(WAIT_TIME_CONNECTION, this, SLOT(reconnect()));
    }

    else
    {
        m_isActive = true;
        qDebug()<<"SOCKET - CONNECTION SERVEUR : " +m_serverIp+ "  PORT : " + QString::number(m_port)+ "  REUSSITE";
        connect(m_socket, SIGNAL(readyRead()), this, SLOT(dataReceived()));
        connect(m_socket,SIGNAL(disconnected()), this, SLOT(socketDisconnection()));
    }

    return m_isActive;
}

void SocketIO::disconnectFromHost()
{
    m_isActive = false;
    m_socket->disconnectFromHost();
}

bool SocketIO::isActive() const
{
    return m_isActive;
}

void SocketIO::dataReceived()
{
  if (m_socket->isValid())
      emit dataReceived(m_socket->read(m_socket->size()));

  else
      qDebug()<< "SOCKET - SOCKET INVALIDE";
}

void SocketIO::socketDisconnection()
{
    m_isActive = false;
    qDebug()<< "SOCKET - CONNECTION TERMINEE - IP: "+m_serverIp+" PORT: " <<QString::number(m_port);
}

PS: J'ai une autre classe qui deserialize les packets se qui me permet de me rendre compte que je ne reçois que le 1
 

ToOnS

Membre Actif
Inscrit
8 Avril 2009
Messages
974
Reactions
0
#2
bonjour , 1 n'est pas un paquet , c'est un message , il peut y avoir plusieurs messages dans un paquet
 

Gohu

Membre Actif
Inscrit
16 Novembre 2013
Messages
222
Reactions
2
#3
Soit, ca ne regle pas vraiment mon problème, mais merci de l'info!
 

ToOnS

Membre Actif
Inscrit
8 Avril 2009
Messages
974
Reactions
0
#4
il y'a quoi comme octets quand tu arrives ici (meme juste m_socket->size() ca va me suffir) :
if (m_socket->isValid())
emit dataReceived(m_socket->read(m_socket->size()));
?
 

Gohu

Membre Actif
Inscrit
16 Novembre 2013
Messages
222
Reactions
2
#5
Voila je sais pas ce que je viens de faire mais maintenant ca marche une fois sur 2:
1 fois j'obtiens 2 packets comme tu peux le voir sur l'image,
parfois j'abtiens 1 packet or sa taille est de 356 bytes (la somme des de taille qui est affichée juste avent chaque
paquets quand j'en recoit 2 (donc 11 et 345)

bizzarre... De plus peux tu me confirmer que c'est bien la public key de RSA que j'affiche dans le second paquet (affiche en base64) ?

Merci d'avance
 

ToOnS

Membre Actif
Inscrit
8 Avril 2009
Messages
974
Reactions
0
#6
on va dire que 1 paquet = 1 reception donc pour ce post tu peux remplacer "paquet" par "reception" pour arriver a dechiffrer plus facilement :

en fait c'est parceque par fois le serveur envoie le message 1 et 3 dans le meme paquet (ca c'est le cas ou ca marche pas , en fait ca marche mais c'est le "parser" qui est fait juste pour recuperer un message par paquet alors que peu en avoir plusieurs par paquet , ce qui te donne l'impression que tu as que le message 1 , mais apres le message 1 il te reste plein d'octets a lire , en fait le message 3) , par fois il envoie dans 2 paquets (ca c'est quand ca marche)

pour la clef j'ai pas compté mais si elle fait 341 caracteres (octets) , c'est pas ca (enfin c'est ca mais y'a aussi autre chose avant , genre VQAga c'est pas la clef , c'est autre chose qui est avant la clef , je sais plus ce que sait et sur combien d'octets , faudrais que je regarde , mais la fin c'est bien la clef) , y'a pas que la clef dans le message 3
 

BlueDream

Administrateur
Membre du personnel
Inscrit
8 Decembre 2012
Messages
2 010
Reactions
149
#7
J'ai 341 pour mon HelloConnectMessage,
[Receive] Id: 3 Name: HelloConnectMessage Lenght: 341
Si uniquement ta clé fait 341 ya en effet un problème.
 

Gohu

Membre Actif
Inscrit
16 Novembre 2013
Messages
222
Reactions
2
#8
Non enfait c'est pas la cle qui fait 341, c'est juste tout le corps du message
mais j'ai cru comprendre qu'il y avait un salt avec?

Donc quel est le protocol pour 'purifier' cette clef, donc virer le salt, et quelle gueule a t elle?
 

BlueDream

Administrateur
Membre du personnel
Inscrit
8 Decembre 2012
Messages
2 010
Reactions
149
#9
Le salt est une chaîne de caractère généré aléatoirement par le serveur dont on se sert pour crypter les identifiants.

 

Gohu

Membre Actif
Inscrit
16 Novembre 2013
Messages
222
Reactions
2
#10
ok tres bien mais comment tu fais pour sortir le salt du message,
et quelle est cette technique de crypatage RSA qui se sert du salt?

Merci d'avance
 
Inscrit
15 Avril 2011
Messages
457
Reactions
1
#11
Dans HelloConnectMessage.as, voici la méthode pour récupérer la clé et le salt :
Code:
      public function deserializeAs_HelloConnectMessage(param1:IDataInput) : void {
         var _loc4_:* = 0;
         this.salt = param1.readUTF();
         var _loc2_:uint = param1.readUnsignedShort();
         var _loc3_:uint = 0;
         while(_loc3_ < _loc2_)
         {
            _loc4_ = param1.readByte();
            this.key.push(_loc4_);
            _loc3_++;
         }
Dans AuthentificationManager.as, dans la fonction setPublicKey, cette ligne permet de purifier la clé :
Code:
var _loc5_:RSAKey = PEM.readRSAPublicKey((new this._verifyKey() as ByteArray).readUTFBytes((new this._verifyKey() as ByteArray).length));

gohu a dit:
quelle est cette technique de crypatage RSA qui se sert du salt?
Dans AuthentificationManager.as, c'est la fonction cipherRsa qui se sert du salt.
 

BlueDream

Administrateur
Membre du personnel
Inscrit
8 Decembre 2012
Messages
2 010
Reactions
149
#12
Une fois que ton parseur est opérationnel, tu vas devoir te plonger dans les sources de D0fus.

Utilises un décompileur SWF gratuit comme "JPEXS Free Flash Decompiler".
http://www.free-decompiler.com/flash/

Une fois téléchargé, décompile grace a JPEXS "D0fusInvoker.SWF" (C:\Program Files\D0fus2\app).

Normalement tu te retrouves avec cela:

Va dans : Script/Com/Ankam@Games/D0fus/Network

Dans ce dossier tu retrouveras toutes les classes du jeu permettant de communiquer avec le serveur.

Donc toi tu recois le paquet 1 et 3.

1: ProtocolRequiredMessage, mais on en a pas besoin
3: HelloConnectMessage -> Voila la classe qui nous intéresse.

En effectuant une recherches dans JPEXS, tu retrouveras HelloConnectMessage à cet emplacement:
Network/Messages/Connection

On sait que le paquet 3 correspond à cette classe car dans les sources de la classe tu retrouves cette variable:
Code:
public static const protocolId:uint = 3;
Présente dans tous les messages de d0fus.

A partir de cette classe tu vas devoir 'deserializer' les datas recu par le serveur après qu'ils soient parsés.

Code:
public function deserializeAs_HelloConnectMessage(param1:IDataInput) : void {
         var _loc4_:* = 0;
         this.salt = param1.readUTF();
         var _loc2_:uint = param1.readUnsignedShort();
         var _loc3_:uint = 0;
         while(_loc3_ < _loc2_)
         {
            _loc4_ = param1.readByte();
            this.key.push(_loc4_);
            _loc3_++;
         }
      }
Une fois la classe déserializé tu vas pouvoir récupérés les variables présentes dans la classe, tel que le fameux SALT et la Clé public RSA.

En ce qui concerne le cryptage, c'est un RSA modifié par le jeu.

Déserialize la classe et après je t'aiderais pour le cryptage.

EDIT: Et biensur avec la fonction serialize:
Code:
public function serializeAs_HelloConnectMessage(param1:IDataOutput) : void {
         param1.writeUTF(this.salt);
         param1.writeShort(this.key.length);
         var _loc2_:uint = 0;
         while(_loc2_ < this.key.length)
         {
            param1.writeByte(this.key[_loc2_]);
            _loc2_++;
         }
      }
Tu pourras parser des classes pour les envoyer au serveur.

Par exemple, VersionExtended que l'on envoi une fois HelloConnectMessage recu, qui correspond à la version du jeu cela donne ce pseudo code:
Define Version : VersionExtented
Version.Serialize(2, 16, 2, 79439, 1, 0)
Version.Pack(ServerSock)
Pack servant a envoyer directement la classe sérializé au serveur :)

Voila donc pour ce résumé assez rapide, il te faudra faire un reader et un writer afin de serializer et deserializer les classes du jeu.
Penche toi la dessus et transmet nous les problèmes rencontrés.

Cordialement
 

Gohu

Membre Actif
Inscrit
16 Novembre 2013
Messages
222
Reactions
2
#13
Super merci beaucoup pour vos réponse tout est plus claire dans
ma tete!
 

BlueDream

Administrateur
Membre du personnel
Inscrit
8 Decembre 2012
Messages
2 010
Reactions
149
#14
Pas de problème, n'hésite pas à poster une nouvelle question.

Bonne soirée
 

Gohu

Membre Actif
Inscrit
16 Novembre 2013
Messages
222
Reactions
2
#15
Juste l'histoire de lever un petit doute:
la clef publique c'est toujours la meme? Je peux la coder en dure dans mon bot?

Cimer
 
Inscrit
15 Avril 2011
Messages
457
Reactions
1
#16
Il y a la clé publique du client qui est dans le fichier "binaryData/363.bin" et la clé publique du serveur qui est envoyée avec le paquet HelloConnectMessage. Par contre, j'ai un doute sur le fait que la clé publique du serveur diffère ou non à chaque envoi...
 

ToOnS

Membre Actif
Inscrit
8 Avril 2009
Messages
974
Reactions
0
#17
non , c'est jamais la meme
 

Gohu

Membre Actif
Inscrit
16 Novembre 2013
Messages
222
Reactions
2
#18
Comment accéder à cette clef publique client sachant que je m’oriente sur un bot full socket.
Autrement dit: comment mon programme doit-il s'y prendre pour récupérer la clef publique client?

Merci bien
 

Gohu

Membre Actif
Inscrit
16 Novembre 2013
Messages
222
Reactions
2
#20
Oui ca je sais faire merci ^^. Mais si je veux filer mon bot a des potes qui y connaisse rien en C++,
je vais pas leur dire de decompiler leur jeu et tout et tout...
 
Haut Bas