Paquets en double

Inscrit
1 Avril 2016
Messages
20
Reactions
0
#1
Salut,

EDIT: J'ai modifié le titre et le sujet, car le problème c'est que je reçois et envois quelques paquets en double (le problème viens de réception des paquets, vu que je n'utilise pas le Parser a l'envoie).

Quand j'utilise le Parser sur mon bot MITM je reçois quelques paquets en doubles, j'ai utilisé plusieurs Parsers mais, le problème est toujours ici.

Screens de quelques paquets quand je me connecte au serveur d'authentification.

Des fois comme ça :



J'ai ça en logs sur le premier screen :


Paquet Envoyé
---------------------
Paquet Reçu : 1
---------------------
Paquet Reçu : 3
---------------------
Paquet Reçu : 183
---------------------
Paquet Envoyé
---------------------
Paquet Reçu : 10
---------------------
Paquet Reçu : 6314
Paquet Reçu : 10
Paquet Reçu : 22
Paquet Reçu : 30


Des fois comme ça :



J'ai ça en logs sur le deuxième screen :

Paquet Envoyé
---------------------
Paquet Reçu : 1
---------------------
Paquet Reçu : 3
Paquet Reçu : 183
---------------------
Paquet Envoyé
---------------------
Paquet Reçu : 10
---------------------
Paquet Reçu : 6314
Paquet Reçu : 10
Paquet Reçu : 22
Paquet Reçu : 30
---------------------
Paquet Envoyé




Voici quelques classes:


C#:
private void OnClientLoginServerConnected(Client client)
        {
            Server server = new Server(loginServerEndpoint);

            this.client = client;
            this.server = server;

            server.Connect();

            client.onReception += ToServer;
            server.onReception += ToClient;
        }

private void ToClient(byte[] buffer)
        {
           ParseData(buffer);
        }

private void ToServer(byte[] buffer)
        {
            Log("Paquet Envoyé");
            server.send(buffer);
        }

private void ParseData(byte[] buffer_To_Parse)
        {
            int header;
            int packet_Id;
            int lenght_count;
            int lenght;
            byte[] packet_Content = new byte[0];

            using (BigEndianReader reader = new BigEndianReader(buffer_To_Parse))
            {
                while (reader.BytesAvailable >= 2)
                {
                    header = reader.ReadShort();

                    packet_Id = header >> 2;
                    lenght_count = header & 3;

                    if (reader.BytesAvailable >= lenght_count)
                    {
                        if ((lenght_count < 0) || (lenght_count > 3))
                        {
                            throw new Exception("Malformated Message Header, invalid bytes number to read message length (inferior to 0 or superior to 3)");
                        }
                        else
                        {
                            lenght = 0;

                            for (int i = lenght_count - 1; i >= 0; i--)
                            {
                                lenght |= reader.ReadByte() << (i * 8);
                            }

                            if (lenght == 0)
                            {
                                packet_Content = new byte[0];
                            }

                            if (reader.BytesAvailable >= lenght)
                            {
                                packet_Content = reader.ReadBytes(lenght);
                            }
                            else if (reader.BytesAvailable < lenght)
                            {
                                packet_Content = reader.ReadBytes((int)reader.BytesAvailable);
                            }

                            string content_hex = string.Empty;
                            int huit_bytes = 0;

                            foreach (byte b in packet_Content)
                            {
                                if (huit_bytes == 8)
                                {
                                    content_hex += "\r\n";
                                    huit_bytes = 0;
                                }
                                content_hex += b.ToString("X2") + " ";
                                huit_bytes++;
                            }
                            Log("Paquet Reçu : " + packet_Id.ToString());
                            // Console.WriteLine(content_hex);
                            TreatPacket(packet_Id, packet_Content, buffer_To_Parse);
                        }
                    }
                }
            }
        }

private void TreatPacket(int packet_Id, byte[] packet_Content, byte[] buffer_To_Parse)
        {
            if (packet_Id != 42)
            {
                client.Send(buffer_To_Parse);
            }
        }
Thread de réception des données de Client et Server:

C#:
private void Receive()
        {
            Thread.Sleep(500);
            while (socket.Connected)
            {
                if (socket.Available > 0)
                {
                    byte[] buffer = new byte[socket.Available];
                    socket.Receive(buffer);
                    if (onReception != null) onReception(buffer);
                    Logs("---------------------");
                }
                Thread.Sleep(1);
            }
        }
Et finalement voila un screen de ce que je reçois et envoie sans MITM :



Merci d'avance
 
Dernière édition:

BlueDream

Administrateur
Membre du personnel
Inscrit
8 Decembre 2012
Messages
2 010
Reactions
150
#2
Hypothèse:

private void ToServer(byte[] buffer)
{
server.Send(buffer);
}
Tu as essayé de parser les données vers le serveur ? Comme pour le client.
 
Inscrit
1 Avril 2016
Messages
20
Reactions
0
#3
Oui mais j'ai toujours le même résultat.
 
Inscrit
1 Avril 2016
Messages
20
Reactions
0
#4
J'ai modifié le sujet, merci de relire.
 
Inscrit
1 Avril 2016
Messages
20
Reactions
0
#6
Encore modifié, merci de relire les codes :)
 

neross

Membre Actif
Inscrit
20 Decembre 2014
Messages
150
Reactions
0
#7
Le parser de packets ne permet pas de voir en double ou en triple tes messages. Il permet uniquement de récupérer les informations dans ce que tu reçois.
Le packet numero 10 = LoginQueueStatusMessage et normale que tu le reçois en double - triple - quadruple car il te l'envois a chaque fois qu'il actualiser la file d'attente pour ce connecter.
Le minimum de fois ou il t'envois ce packet c'est deux car au premier tu est 1er dans la file d'attente et le deuxième tu a finis la file d'attente. :)

Maintenant si tu crois toujours recevoir des packets en double, moi a ta place je regarderais plutôt si tu n'a pas de problème niveau Socket a la réception des données.
 
Inscrit
1 Avril 2016
Messages
20
Reactions
0
#8
Oui je sais que le Parser récupère les informations c'est tout, mais quand je l'utilise dans la réception des paquets j'ai un problème, mais si je ne l'utilise pas ça fonctionne bien.
Quand je parlais de paquet en double je parlais du paquet 3 que je reçois en double car c'est lui qui provoque l'envoie du paquet 4 en double et aussi le problème qu'un paquet s'ajoute sur l'autre paquet (je ne sais pas très bien expliqué :p), regarde le 1er screen, je reçois au numéro 3 : 345 Bytes et au 2eme screen au même numéro je reçois 349 Bytes par contre le numéro 5 du 1er screen disparait sur le 2eme screen, il a 4 Bytes et 345 + 4 = 349 Bytes, ça veut dire que sur le 1er screen je reçois le paquet 3 après j'envoie le 4 après je reçois le 183 etc, par contre sur le 2eme screen je reçois le paquet 3 et 183 sur le même paquet et j'envoie le 4.
La même chose pour numéro 7.
PS : j'ai ajouter un screen de ce que j'ai sans MITM et c'est ce que je devais avoir.
 
Dernière édition:
Inscrit
1 Avril 2016
Messages
20
Reactions
0
#9
J'ai aussi utiliser ce Parser avec la classe Queue mais j'ai toujours le même problème.
Le Parser viens de ce sujet : https://cadernis.fr/index.php?threads/mauvais-id-de-paquet.999/ aussi cette ligne de code : Timer _timer_Parsing_Thread = new System.Threading.Timer(TimerReceptionThreadFinished, null, 60000, 250); j'ai pas compris ce qu'il veux appeler et a quoi sert t'il d'appeler ce qui appel.

C#:
private void Receive()
       {
            Thread.Sleep(500);
           while (socket.Connected)
           {
               if (socket.Available > 0)
               {
                   byte[] buffer = new byte[socket.Available];
                    socket.Receive(buffer);
                   _buffer_Queue.Enqueue(buffer); // Stockage du buffer dans une queue
                    if (onReception != null) onReception(buffer);
                    Logs("---------------------");
               }
                Thread.Sleep(1);
           }
       }

public void ParseData()
        {
            while ((client.socket != null) && (client.socket.Connected)) // On traite les paquets tant qu'on est connectés (c'est pas nécessaire du tout vu que je lance pas le thread)
            {
                if (_buffer_Queue.Count != 0) // Si la queue contient des buffers, on traite
                {
                    int index = 0;
                    ushort header;
                    ushort packet_ID = 0;
                    byte packet_Length_Type = 0;
                    int packet_Length = 0;
                    int packet_Start = 0;
                    int packet_End;
                    byte[] packet_Temporary;
                    int _bytes_Wanted;
                    byte[] _packet_Out = new byte[0];

                    byte[] packet_In = (byte[])_buffer_Queue.Dequeue();

                    // Timer _timer_Parsing_Thread = new System.Threading.Timer(TimerReceptionThreadFinished, null, 60000, 250);

                    if (_bytes_Wanted > 1) // Le buffer précédent ne contenait pas tout le message
                    {
                        packet_Temporary = new byte[packet_In.Length + _packet_Out.Length]; // Création du message temporaire
                        Array.Copy(_packet_Out, 0, packet_Temporary, 0, _packet_Out.Length); // Copie de début du message dans le message temporaire
                        Array.Copy(packet_In, 0, packet_Temporary, _packet_Out.Length, packet_In.Length); // Copie du buffer suivant dans le message temporaire
                        packet_In = packet_Temporary;
                    }

                    while (index < packet_In.Length) // Tant qu'il y a un header à lire dans le buffer
                    {
                        packet_Start = index;
                        header = (ushort)(packet_In[index] * 256 + packet_In[index + 1]); // Récupération de l'header
                        packet_Length_Type = (byte)(header & 3); // Récupération du type de longueur de message
                        packet_ID = (ushort)(header >> 2); // Récupération de l'ID du message
                        index += 2 + packet_Length_Type;

                        if (packet_ID == 6440)
                        {
                        }

                        switch (packet_Length_Type) // Récupération de l'hedaer
                        {
                            case 0:
                                packet_Length = 0;
                                break;
                            case 1:
                                packet_Length = packet_In[index - 1];
                                break;
                            case 2:
                                packet_Length = 256 * packet_In[index - 2] + packet_In[index - 1];
                                break;
                            case 3:
                                packet_Length = 65536 * packet_In[index - 3] + 256 * packet_In[index - 2] + packet_In[index - 1];
                                break;
                        }

                        if (index + packet_Length > packet_In.Length) // Le buffer ne contient pas tout le message
                        {
                            _bytes_Wanted = packet_Length - packet_Start;
                            _packet_Out = new byte[packet_In.Length - packet_Start];
                            Array.Copy(packet_In, packet_Start, _packet_Out, 0, packet_In.Length - index); // Copie le début du message dans un buffer
                            break;
                        }
                        else
                        {
                            byte[] final_Packet = new byte[0];

                            if (packet_Length > 0)
                            {
                                final_Packet = new byte[packet_Length];
                                Array.Copy(packet_In, index, final_Packet, 0, packet_Length); // On copie le message final
                            }

                            Log("Paquet reçu, ID : " + packet_ID);

                            TreatPacket(packet_ID, final_Packet, packet_In); // Traite le packet

                            index += packet_Length;
                            packet_End = index;

                            if (packet_End <= packet_In.Length) // Réinitialisation
                            {
                                _bytes_Wanted = 0;
                                _packet_Out = new byte[0];
                            }
                        }
                    }
                }
            }
        }
 
Inscrit
25 Février 2012
Messages
178
Reactions
3
#10
Vaut mieux que tu re-code ton parser là, dans une classe pour lui seul.
Sépare le parser de packets du Network du client(compte), c'est plus propre. Et évite les 20 While et tout ^^
 
Inscrit
1 Avril 2016
Messages
20
Reactions
0
#11
Ce n'est pas mon Parser je l'est prit d'ici, là je veux connaitre ou est l'erreur c'est ce qui est important là.
Et pour l'architecture de codes je vais changer pas mal de choses, c'est juste que je veux que tout fonctionne parfaitement après je passerai a autre chose et pour les While je n'ai pas trop, j'ai seulement un peu et c'est très bien juste sur le Parser je dois la supprimer j'avais déjà commenté que je n'ai pas besoin c'était pour un test de Thread.

Le gros problème c'est comme j'ai dis je n'arrive pas a comprendre d'ou viens l'erreur exactement car si je n'utilise pas le Parser tout fonctionne bien mais si je l'utilise j'ai le problème, et en + j'ai utiliser pleins de Parser.pour les tests.
 
Inscrit
1 Avril 2016
Messages
20
Reactions
0
#12
J'ai même utiliser ce Parser :

C#:
private void ParseData(byte[] data)
        {
            m_Reader.Add(data, 0, data.Length);
            if (m_Reader.BytesAvailable <= 0)
                return;
            while (m_Reader.BytesAvailable >= 0)
            {
                if (Build())
                {
                    server.Send(data);
                    Log("Paquet envoyé, ID : " + m_ProtocolID);

                    m_Header = null;
                    m_Length = null;
                    m_Data = null;
                    m_LenghtType = null;
                    m_ProtocolID = null;
                }
                else
                    break;
            }
        }

        private bool Build()
        {
            if ((m_Header.HasValue) && (m_Length.HasValue) && (m_Length == m_Data.Length))
                return true;
            if ((m_Reader.BytesAvailable >= 2) && (!m_Header.HasValue))
            {
                m_Header = m_Reader.ReadShort();
                m_ProtocolID = m_Header >> 2;
                m_LenghtType = m_Header & 0x3;
            }
            if ((m_LenghtType.HasValue) &&
            (m_Reader.BytesAvailable >= m_LenghtType) && (!m_Length.HasValue))
            {
                if ((m_LenghtType < 0) || (m_LenghtType > 3))
                    throw new Exception("Malformated Message Header, invalid bytes number to read message length (inferior to 0 or superior to 3)");
                m_Length = 0;
                for (int i = m_LenghtType.Value - 1; i >= 0; i--)
                    m_Length |= m_Reader.ReadByte() << (i * 8);
            }
            if ((m_Data == null) && (m_Length.HasValue))
            {
                if (m_Length == 0)
                    m_Data = new byte[0];
                if (m_Reader.BytesAvailable >= m_Length)
                    m_Data = m_Reader.ReadBytes(m_Length.Value);
                else if (m_Length > m_Reader.BytesAvailable)
                    m_Data = m_Reader.ReadBytes((int)m_Reader.BytesAvailable);
            }
            if ((m_Data != null) && (m_Length.HasValue) && (m_Data.Length < m_Length))
            {
                int bytesToRead = 0;
                if (m_Data.Length + m_Reader.BytesAvailable < m_Length)
                    bytesToRead = (int)m_Reader.BytesAvailable;
                else if (m_Data.Length + m_Reader.BytesAvailable >= m_Length)
                    bytesToRead = m_Length.Value - m_Data.Length;
                if (bytesToRead != 0)
                {
                    int oldLength = m_Data.Length;
                    Array.Resize(ref m_Data, m_Data.Length + bytesToRead);
                    Array.Copy(m_Reader.ReadBytes(bytesToRead), 0, m_Data, oldLength, bytesToRead);
                }
            }
            return m_Data != null && ((m_Header.HasValue) && (m_Length.HasValue) && (m_Length == m_Data.Length));
        }
 

BlueDream

Administrateur
Membre du personnel
Inscrit
8 Decembre 2012
Messages
2 010
Reactions
150
#13
Hello,

On dirait une version modifiée à la va vite du MessagePart de BiM, autant utiliser l'officiel.

C#:
public class MessagePart
  {
  /// <summary>
  /// Set to true when the message is whole
  /// </summary>
  public bool IsValid
  {
  get
  {
  return Header.HasValue && Length.HasValue &&
  Length == Data.Length;
  }
  }

  public int? Header
  {
  get;
  private set;
  }

  public int? MessageId
  {
  get
  {
  if (!Header.HasValue)
  return null;

  return Header >> 2; // xxxx xx??
  }
  }

  public int? LengthBytesCount
  {
  get
  {
  if (!Header.HasValue)
  return null;

  return Header & 0x3; // ???? ??xx
  }
  }

  public int? Length
  {
  get;
  private set;
  }

  private byte[] m_data;

  public byte[] Data
  {
  get { return m_data; }
  private set { m_data = value; }
  }

  private byte[] m_completeData;

  public byte[] CompleteData
  {
  get { return m_completeData; }
  private set { m_completeData = value; }
  }

  /// <summary>
  /// Build or continue building the message. Returns true if the resulted message is valid and ready to be parsed
  /// </summary>
  public bool Build(BigEndianReader reader)
  {
  if (IsValid)
  return true;

  m_completeData = reader.Data;

  if (reader.BytesAvailable >= 2 && !Header.HasValue)
  {
  Header = reader.ReadShort();
  }

  if (LengthBytesCount.HasValue &&
  reader.BytesAvailable >= LengthBytesCount && !Length.HasValue)
  {
  if (LengthBytesCount < 0 || LengthBytesCount > 3)
  throw new System.Exception("Malformated Message Header, invalid bytes number to read message length (inferior to 0 or superior to 3)");

  Length = 0;
   
  // 3..0 or 2..0 or 1..0
  for (int i = LengthBytesCount.Value - 1; i >= 0; i--)
  {
  Length |= reader.ReadByte() << (i * 8);
  }
  }

  // first case : no data read
  if (Data == null && Length.HasValue)
  {
  if (Length == 0)
  Data = new byte[0];

  // enough bytes in the buffer to build a complete message
  if (reader.BytesAvailable >= Length)
  {
  Data = reader.ReadBytes(Length.Value);
  }
  // not enough bytes, so we read what we can
  else if (Length > reader.BytesAvailable)
  {
  Data = reader.ReadBytes((int) reader.BytesAvailable);
  }
  }
  //second case : the message was split and it missed some bytes
  if (Data != null && Length.HasValue && Data.Length < Length)
  {
  int bytesToRead = 0;

  // still miss some bytes ...
  if (Data.Length + reader.BytesAvailable < Length)
  bytesToRead = (int)reader.BytesAvailable;

  // there is enough bytes in the buffer to complete the message :)
  else if(Data.Length + reader.BytesAvailable >= Length)
  bytesToRead = Length.Value - Data.Length;

  if(bytesToRead != 0)
  {
  int oldLength = Data.Length;
  Array.Resize(ref m_data, (int)( Data.Length + bytesToRead ));
  Array.Copy(reader.ReadBytes(bytesToRead), 0, Data, oldLength, bytesToRead);
  }
  }

  return IsValid;
  }
  }
 
Inscrit
1 Avril 2016
Messages
20
Reactions
0
#14
Oui je l'ai prit de BlueSheepBot.
 

BlueDream

Administrateur
Membre du personnel
Inscrit
8 Decembre 2012
Messages
2 010
Reactions
150
#15
Ah bah voila tout s'explique :p

Normalement avec celui que je t'ai envoyé, tu ne devrais pas avoir de problème.
Sinon le problème vient de ta partie network.
 
Inscrit
1 Avril 2016
Messages
20
Reactions
0
#16
Ok merci je vais le test après je dirais si tout fonctionne ou pas.
 
Inscrit
1 Avril 2016
Messages
20
Reactions
0
#17
J'ai régler mais j'avais pas dit.
j'ai utiliser le Parser de BIM mais surtout ce qui me causait l'erreur c'est qu'il me fallait à chaque fois que je reçois les données j'analyse avec cette méthode:

C#:
private void ThreatBuffer()
        {
            if (currentMessage == null)
                currentMessage = new MessagePart();

            if (currentMessage.Build(reader))
            {
                //Send Method
                currentMessage = null;
                ThreatBuffer();
            }
        }
Cette méthode gère bien tout les messages.
A chaque fois y'a un message ou - ou + dans le paquet reçu il fais le nécessaire car avant j'envoyer directement les données au Parser qui parsait que le premier message sans qu'il regarde si il y'a d'autres messages dans le paquet.
J'espere sa aidera si qq a un problème comme celui la :D
 
Dernière édition:
Haut Bas