Bonsoir à tout le monde!

EDIT: comme l'a fait remarquer DrBrooklyn dans sa réponse, la méthode utilisée ici n'est pas vraiment la "bonne" méthode. Ça devrait fonctionner, mais il existe des méthodes bien plus pratiques et efficaces sur le forum. Je laisse quand même le post original pour ceux qui sont intéressés.

Développant 100% sous Linux et commençant à m'intéresser à l'écosystème de Dofus, je suis tombé sur le besoin d'avoir la possibilité de récupérer les messages envoyés/reçus par le client sous Linux. Chose pensée chose faite, j'ai développé """l'équivalent""" (il y a beaucoup de guillemets, voir paragraphe suivant) de No.Ankama.dll mais pour Linux.

N'ayant pour l'instant uniquement besoin de pouvoir lire les messages entrants/sortants du client, le hook partagé ici n'est pas vraiment un équivalent de No.Ankama.dll: il ne fait que dupliquer les messages pour les envoyer autre part, sans toucher aux messages reçus/envoyés par le client.

Sans plus attendre, le lien vers le dépôt Gitlab. Tout est expliqué dans le README, en gros le hook duplique et envoie:

- les messages reçus par le client vers 127.0.0.1:53453.

- les messages envoyés par le client vers 127.0.0.1:53452.

Il vous suffit d'avoir un programme qui écoute sur ces ports pour recevoir tous les messages envoyés/reçus par le client hooké.

Quelques remarques en vrac:

- Vous ne pouvez pas hooker 2 clients en même temps en laissant la bibliothèque comme ça. Il faudra modifier les ports dans le code source et re-compiler une autre version de la bibliothèque afin d'avoir 2 versions de la bibliothèque avec des ports différents pour éviter que les messages des 2 clients se mélangent.

- Les ports comme l'adresse IP sont au tout début du fichier source. Vous pouvez les changer pour mettre les valeurs que vous voulez (attendez-vous néanmoins à des problèmes si vous vous amusez à mettre 22 ou 80 - les ports réservés aux protocoles SSH et HTTP).

- Je n'ai pas testé, mais théoriquement il est possible de mettre une adresse IP externe et donc d'envoyer les messages dupliqués à un autre programme qui va écouter sur une machine différente, en passant par le réseau Internet. Je suis preneur de retours si quelqu'un teste.

- Ca a été testé/compilé avec GCC 9.3, GCC 8.3 (il me semble), clang 9 et clang 11. Ne cherchez pas à compiler ça sur Windows, ça utilise des headers système de Linux qui sont absents de Windows.

- Je n'ai pas encore filtré les messages avec les IPs des serveurs de connexion et de jeu. Ça signifie que tous les messages envoyés/reçus par le client seront transférés. Je crois qu'il y a quelques messages qui ne viennent ni du serveur de jeu ni du serveur de connexion au tout début de la connexion, mais je n'ai pas vérifié correctement (on voit du JSON dans le hexdump de mémoire).

- Il n'est pas nécessaire de lancer le serveur qui va écouter sur les ports avant le client hooké. Si aucun programme n'écoute sur les ports, le hook écrira un message de log sur la sortie standard (qui normalement n'est pas visible quand vous lancez le client) et essaiera de nouveau de se connecter au prochain message.

- Pas besoin de changer vos habitudes, vous lancez le client avec le launcher, comme d'habitude. Vous pouvez même garder le hook H24 sur le client et jouer normalement sans avoir un serveur qui va écouter les ports. Tout est complètement transparent (modulo la modification initiale et unique d'une ligne). Néanmoins je n'ai aucune idée de si le fichier est checké par le client. Quelqu'un pourra peut-être m'éclairer sur ce point?

Merci à @Turing#4686 (Papa Ising) pour l'aide!

Salut,

Pour le coup je pense que tu devrais t'orienter vers Frida : https://frida.re/

c'est multi-plateforme (y compris iOS/Android), ca fonctionne via Python et le JavaScript (moteur V8 de Google), c'est très bien testé et bullet-proof.

Sinon c'est cool ton truc, mais j'ai du mal à saisir l'idée (un sniffer mono client tout au plus?) et pour la 7, théoriquement Ankama peut détecter un hook mais ils ne l'ont jamais fait (à cause de la plateforme Flash), tu peux partir du principe que c'est indétectable :)

Coucou!

J'ai justement utilisé Frida pour débugger. J'ai donc quelque chose qui marchouille avec Frida, mais le but pour moi était:

- Inclure ça dans la collection de tools que je suis en train de construire au fur et à mesure, du coup je voulais quelque chose qui s'intègre assez bien avec le C++.

- Apprendre un peu comment marchaient toutes ces histoires de hook. Du coup même si ce n'est utile pour personne, j'aurais appris des choses :)

Pour ce qui est du multi-plateforme, ça n'est pas une nécessité ici puisque de toute façon les appels bas niveau sont différents entre Windows et Linux (il me semble que sur Windows c'est du

send
/
recv
alors que sur Linux c'est du
sendmsg
/
recvmsg
).

Tu peux adapter le hook pour plusieurs clients, mais c'est vrai que tel qu'il est pour l'instant c'est surtout du mono-client. Ca doit être techniquement possible (et facile?) de passer à du multi-client, mais je n'en ai pas le besoin donc je n'y avait pas pensé. Je garde ça de côté :)

Finalement, pour le hook, ce qui m'embête c'est que je dois modifier un fichier texte à côté du DofusInvoker.swf (donc dans les fichiers de Dofus). C'est le fichier

zaap-start.sh
qui n'est probablement pas présent sur Windows et qui s'occupe de lancer l'exécutable avec
wine
.

Si je vois que l'approche que j'ai choisie est trop limitée/risquée, je partirai sur une approche différente. Ton commentaire à commencé à me montrer certaines faiblesses, merci ;)

Sendmsg/recv msg c'est udp, c'est bien send et recv sur les deux plate-formes ;)

Re! Du coup je viens de re-tester. Tout ce que je dis dans ce message n'est valable que pour le client Linux.

Une fois le client connecté et le personnage en jeu, j'ai lancé

frida-trace -d -i "send" -i "recv" "*Dofus*"
. Quelques sorties (2 appels à
send
), mais absolument rien quand je me déplace sur la map. Pendant ma session de capture (où seulement 2
send
ont été capturés par Frida), je me suis déplacé sur la carte une dizaine de fois.

J'ai eu la même réflexion que toi au début: "bon, sur Windows c'est du

send
/
recv
donc je n'ai qu'à trouver les équivalents Linux et basta". Et bien non, les messages sont bel et bien envoyés et reçus par
sendmsg
/
recvmsg
. En tous cas, en ne hookant que les fonctions
sendmsg
/
recvmsg
, je reçois le contenu des messages.

Ensuite, encore une fois pour Linux, les fonctions de la famille de

send
/
recv
(i.e.
send
/
recv
,
sendto
/
recvto
et
sendmsg
/
recvmsg
) n'ont rien à voir avec le protocole utilisé. Elles envoient leurs données sur un descripteur de fichier qui doit être un socket ouvert. Si tu veux de l'UDP, tu ouvres ton socket avec les bons paramètres, si tu veux du TCP tu choisis d'autres paramètres, si tu veux de l'IPC, tu as encore d'autres paramètres d'ouverture. Dans tous les cas l'appel à
send
et consorts sera le même, et l'effet aussi: tu écriras/liras des données sur un socket. Toute la gestion du protocole est réalisée par le socket en interne (très probablement par l'OS du coup).

Ok j'ai vu un nombre incalculable d'exemples où ils utilisaient send/recv peu importe la plateforme

Du coup tu peux juste hook selon la plate-forme visée, Frida te permet de détecter où tu tournes :_)

    DrBrooklyn

    Du coup tu peux juste hook selon la plate-forme visée, Frida te permet de détecter où tu tournes :_)

    Je vais regarder un peu plus en détails ce que propose Frida, pour l'instant je n'ai touché qu'à la CLI de

    frida-trace
    .

    un mois plus tard

    Salut et merci pour ton taff :)

    Je suis récemment passé sur linux mais au lancement de dofus, il y a une erreur :

    Error: ld.so: object from LD_PRELOAD cannot be preloaded (wrong ELF class ELFCLASS64): ignored

    J'ai aussi essayé avec la version 32 bits, même résultat.

    Quelqu'un aurait une idée ?

    En attendant, j'ai essayé de sniffé via pcap (https://github.com/node-pcap/node_pcap) mais les résultats sont mauvais.

      Claudine

      Sous Windows, il ne fonctionne pas aussi. J'utilise : https://www.npmjs.com/package/cap qui fonctionne très bien (et conçu nativement pour linux).

      yes j'ai vu ton projet gitlab je me suis aussi dirigé vers cette librarie, elle marche très bien :) en plus pas de hook donc indétectable.

      Coucou!

      Je vais éditer mon post principal sur ce thread. Comme l'a fait remarquer à juste titre DrBrooklyn la méthode utilisée n'est vraiment pas optimale et pratique. Peut-être qu'un jour j'essaierai autre chose, mais en attendant j'ai d'autres projets sur le feu qui m'intéressent plus.