Note: le tool a pas mal évolué depuis ce premier post. Pensez à regarder les différentes mises à jour:
- Update 1.
- Update 2.
- Update 3.
- Update 4.
- Update 5 (exécutable Windows fonctionnel).
Post originel:
-------------------------------------------------------------
Bien le bonjour la communauté!
Voici mon premier vrai post de partage ici. Je viens de finir mon parseur de protocole, un "remplacement" à l'outil d2json de @Lakh92 .
Le but de l'outil? Faire en sorte de ne pas dépendre de décompilateurs SWF lourds tels que FFDec et de systèmes d'expression régulières compliqués pour générer son protocole réseau.
Concrètement? Vous lancez l'outil sur le DofusInvoker.swf, et en quelques secondes vous obtenez un JSON ayant cette forme:
{
"default": {
"field": {
"boolean_byte_wrapper_position": -1,
"bounds": null,
"constant_length": 0,
"default_value": "",
"name": "",
"namespace": "",
"null_checked": false,
"prefixed_by_type_id": false,
"self_serialize_method": "",
"type": "",
"type_namespace": "",
"use_boolean_byte_wrapper": false,
"write_false_if_null_method": "",
"write_length_method": "",
"write_method": "",
"write_type_id_method": ""
}
},
"enumerations": [
{
"entries_type": "uint",
"members": {
"HOOK_POINT_CATEGORY_BASE_BACKGROUND": "4",
"HOOK_POINT_CATEGORY_BASE_FOREGROUND": "6",
"HOOK_POINT_CATEGORY_LIFTED_ENTITY": "3",
"HOOK_POINT_CATEGORY_MERCHANT_BAG": "5",
"HOOK_POINT_CATEGORY_MOUNT_DRIVER": "2",
"HOOK_POINT_CATEGORY_PET": "1",
"HOOK_POINT_CATEGORY_PET_FOLLOWER": "7",
"HOOK_POINT_CATEGORY_UNDERWATER_BUBBLES": "8",
"HOOK_POINT_CATEGORY_UNUSED": "0"
},
"name": "SubEntityBindingPointCategoryEnum"
},
// ...
],
"messages": [
{
"fields": [
{
"default_value": "false",
"name": "quiet",
"type": "Boolean",
"write_method": "writeBoolean"
},
{
"default_value": "false",
"name": "_isInitialized",
"namespace": "com.ankamagames.dofus.network.messages.common.basic",
"type": "Boolean"
}
],
"name": "BasicPingMessage",
"namespace": "com.ankamagames.dofus.network.messages.common.basic",
"protocolID": 182,
"super": "NetworkMessage",
"supernamespace": "com.ankamagames.jerakine.network",
"use_hash_function": false
},
// ...
],
"types": [
{
"fields": [
{
"bounds": {
"low": "-9007199254740992.000000",
"up": "9007199254740992.000000"
},
"default_value": "0",
"name": "contextualId",
"type": "Number",
"write_method": "writeDouble"
},
{
"name": "_dispositiontree",
"namespace": "com.ankamagames.dofus.network.types.game.context",
"type": "FuncTree",
"type_namespace": "com.ankamagames.jerakine.network.utils"
},
{
"name": "disposition",
"prefixed_by_type_id": true,
"self_serialize_method": "serialize",
"type": "EntityDispositionInformations",
"type_namespace": "com.ankamagames.dofus.network.types.game.context",
"write_type_id_method": "writeShort"
}
],
"name": "GameContextActorPositionInformations",
"namespace": "com.ankamagames.dofus.network.types.game.context",
"protocolID": 566,
"super": "",
"supernamespace": "",
"use_hash_function": false
},
// ...
],
"version": {
"client": {
"build": {
"date": {
"day": 1,
"full": "2020-4-1 13:45",
"hour": 13,
"minute": 45,
"month": 4,
"year": 2020
}
},
"major": 2,
"minor": 55,
"patch": 1
},
"parser": {
"major": 0,
"minor": 2
},
"protocol": {
"date": {
"day": 13,
"full": "2020-3-13 14:43",
"hour": 14,
"minute": 43,
"month": 3,
"year": 2020
},
"version": {
"current": 1966,
"minimum": 1966
}
}
}
}
L'outil n'en est qu'à sa version préliminaire, il y a encore quelques informations facilement accessibles que j'aimerai rajouter dans le JSON. Idéalement, j'aimerai aussi implémenter de quoi filtrer les informations contenues dans le JSON avec des flags lors de l'appel à l'exécutable.
J'ai pensé l'outil pour être facilement extensible. Si le JSON généré ne contient pas les informations que vous désirez, envoyez moi un petit message sur discord @Nelimee ou répondez à ce post, je ferais mon possible pour ajouter les informations demandées.
Le plus important, les dépôts git sont bien entendu en accès libre:
- IOs, la bibliothèque qui gère les I/Os de base.
- SwfParser, la bibliothèque qui s'occupe de parser le format SWF (le format du DofusInvoker.swf) et de désassembler le bytecode ABC (bytecode utilisé dans le DofusInvoker.swf pour l'implémentation de toutes les fonctions/méthodes).
- protocol_parser, qui va s'occuper d'extraire les informations qui nous intéressent du bytecode ABC désassemblé.
Quelques idées d'améliorations qui seront probablement implémentées dans les jours/semaines qui arrivent (si vous avez des idées pour allonger la liste, vous savez où me joindre):
- Ajouter une documentation digne de ce nom. Pour l'instant, on va dire que la documentation est plutôt parsemée et je la juge insuffisante pour rentrer dans le code facilement en partant de 0. Priorité numéro 1.
- Ajouter les 2-3 fonctionalités dont j'ai déjà parlé comme
- plus d'information dans le JSON généré. Il y a 2-3 informations accessibles que je n'ai pas sérialisés et ça ne sera pas très long à ajouter.
- pouvoir filtrer avec des flags les informations contenues dans le JSON.
- ajouter une entrée "default" quelque part dans le JSON pour éviter d'avoir à préciser dans chaque entrée les termes qui n'ont pas de sens.
- avoir 2 dates sous le même format dans le champs "version".
- (plus long terme) pouvoir faire des diff propres entre 2 versions du protocole.
- Même si la tâche me semble non triviale à réaliser correctement, j'aimerai bien avoir un bon moyen de tester l'implémentation de façon automatique. Soit des tests unitaires, soit des tests un peu plus larges tels que la comparaison
- Confirmer que la fonctionnalité de signalisation des sérialisations non-matchées par le parseur est solide. Pour l'instant le tool affiche un warning pour toute instruction qui vérifie toutes les conditions suivantes:
- Le nom de la méthode appellée commence par "write" ou "serialize"
- L'instruction d'appel de méthode ne fait pas partie d'un ensemble d'instruction qui a déjà été reconnu comme un "ensemble d'instruction connu".
J'inclus dans ce post une version du code compilée par mes soins pour Linux (outdated, voir updates en fin de post). J'ai essayé de cross-compiler pour Windows, je me suis souvenu de pourquoi j'étais passé sous Linux, et du coup je n'ai pas d'exécutable Windows à vous passer. Je vous invite à le compiler vous-même, en théorie le code est portable sur n'importe quelle plateforme ayant un compilateur avec un support partiel du C++17. D'ailleurs, je n'utilises qu'assez peu les fonctionnalités du C++17 donc ça ne devrait pas être trop dur de passer en C++14 (voire même C++11) si vous n'avez pas de compilateur C++17 sous la main.
Pour finir:
./protocol_parser --help
Protocol parser for the Botofu project
Usage: ./protocol_parser [OPTIONS] DofusInvokerPath ExportPath
Positionals:
DofusInvokerPath TEXT:FILE REQUIRED
Path to the DofusInvoker.swf
ExportPath TEXT REQUIRED Path to the file that will contain the output of the protocol parsing.
Options:
-h,--help Print this help message and exit
-i,--ident INT Number of spaces used to indent resulting JSON. Default to minified (0).
A plus!
Nelimee