2.0 Patch DofusInvoker

Inscrit
20 Avril 2017
Messages
12
Reactions
0
#1
Bonjour,

Depuis ce matin je m’intéresse fortement au fonctionnement d'un patch du DofusInvoker.swf nous permettant d'utiliser nos émulateurs. J'aimerai comprendre comment "patcher" ce fichier.
J'aimerai savoir quelles sont les routines de protection, qu'est ce qu'elles protègent, et comment les contourner sans que le client ne me pète à la figure.
Jusqu'ici j'utilisais des clients déjà patché mais j'en ai un marre de ne pas comprendre ce que j'utilise donc si quelqu'un peut partager son savoir à ce sujet, ça serai avec grand plaisir.

Merci,
bonne journée.
 

BlueDream

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

Le meilleur outils connu à ce jour pour de l'édition gratuite c'est JPEXS. https://www.free-decompiler.com/flash/download/
Tu as deux choix, soit tu modifies le code directement au risque d'avoir quelques soucis (en actionscript), soit tu édites avec ce qu'on appelle du processcode.
Il s'agit d'un langage "universel" dans le sens ou c'est du codage compréhensible par tous très simplifié, c'est le meilleurs moyen d'avoir un bon résultat sur du Patch.
Tu peux t'inspirer de patchs déjà existants sur le forum.
 
Inscrit
20 Avril 2017
Messages
12
Reactions
0
#3
Bonsoir,

J'utilise déjà JPEXS et j'ai déjà pas mal analyser le code. J'ai aussi bien compris qu'il fallait éditer le Pcode qui ressemble un peu a des instructions assembleurs (dans la syntaxe et la simplicité) et donc ça m'est assez familier.
J'arrives très bien à supprimer des lignes, à en rajouter, j'arrive à faire toutes les bricoles nécessaire dans le Pcode.
Le vrai problème c'est que je ne sais pas à quelle routine m'attaquer pour contourner par exemple l'erreur d'authentification.
J'ai beau comparé les fichiers d'un DofusInvoker.swf patché a ceux qu'un DofusInvoker.swf de la même version non patché, je n'arrive pas à trouver les petites subtilités entre les deux versions.
En plus de ça, j'aimerai vraiment comprendre la portée globale de mon action sur le fonctionnement du client.
Merci en tout cas pour tes débuts de pistes qui confirme que le travail que j'avais déjà effectué n'est pas sans utilité !

Bonne journée !
 

tazman59

Contributeur
Inscrit
20 Decembre 2012
Messages
149
Reactions
27
#4
Salut, déjà depuis pas mal de versions il est impossible de modifier les Ip et les Ports du serveur de connexion depuis le fichier de configuration.

- Tu peux déjà chercher dans les sources quelle classe connecte le client et changer les paramètres de la fonction connect() en mettant en ip de connection "120.0.0.1" par exemple (pour du MITM). Voilà un premier patch possible.

- Un second patch, toujours pour la connexion, serait de supprimer la vérification de la clef (je ne me souviens plus de son nom) qui se trouve dans la config et qui empêche de modifier les Ip et Ports.

Néanmoins fais attention si tu patch un client à jour et que tu essayes de te connecter, car Ankama punit le fait de modifier ses fichiers :teeth:
 
Inscrit
20 Avril 2017
Messages
12
Reactions
0
#5
Salut, déjà depuis pas mal de versions il est impossible de modifier les Ip et les Ports du serveur de connexion depuis le fichier de configuration.

- Tu peux déjà chercher dans les sources quelle classe connecte le client et changer les paramètres de la fonction connect() en mettant en ip de connection "120.0.0.1" par exemple (pour du MITM). Voilà un premier patch possible.

- Un second patch, toujours pour la connexion, serait de supprimer la vérification de la clef (je ne me souviens plus de son nom) qui se trouve dans la config et qui empêche de modifier les Ip et Ports.

Néanmoins fais attention si tu patch un client à jour et que tu essayes de te connecter, car Ankama punit le fait de modifier ses fichiers :teeth:
Bonjour,

Pour patch la vérification de la signature, j'ai essayé de m'attaquer a la fonction verify() du module de crypto mais c'est vraiment vraiment galère (elle est subdivisé en 3 fonction verify, verifyV1 et verifyV2). Du coup j'ai été check la fonction process() de la frame AuthentificationFrame et plus précisément la case LoginValidationAction. J'ai réussi a me bloquer l'access au serveur Ankama mais pas à ouvrir l'access au mien.

De ça:
Code:
 case msg is LoginValidationAction:
               lva = LoginValidationAction(msg);
               GuestModeManager.getInstance().isLoggingAsGuest = lva is LoginValidationAsGuestAction;
               if(this._lastLoginHash != MD5.hash(lva.username))
               {
                  this._streamingBetaAccess = false;
                  UiModuleManager.getInstance().isDevMode = XmlConfig.getInstance().getEntry("config.dev.mode");
               }
               this._lastLoginHash = MD5.hash(lva.username);
               connexionPorts = new Array();
               ports = XmlConfig.getInstance().getEntry("config.connection.port");
               for each(porc in ports.split(","))
               {
                  connexionPorts.push(int(porc));
               }
               connectionHostsEntry = XmlConfig.getInstance().getEntry("config.connection.host");
               if(BuildInfos.BUILD_TYPE < BuildTypeEnum.INTERNAL)
               {
                  connectionHostsSignatureEntry = XmlConfig.getInstance().getEntry("config.connection.host.signature");
                  output = new ByteArray();
                  try
                  {
                     signedData = Base64.decodeToByteArray(connectionHostsSignatureEntry);
                  }
                  catch(error:Error)
                  {
                     _log.warn("Host signature has not been properly encoded in Base64.");
                     commonMod.openPopup(I18n.getUiText("ui.common.error"),I18n.getUiText("ui.popup.connectionFailed.unauthenticatedHost"),[I18n.getUiText("ui.common.ok")]);
                     KernelEventsManager.getInstance().processCallback(HookList.SelectedServerFailed);
                     return false;
                  }
                  signedData.position = signedData.length;
                  signedData.writeUTFBytes(connectionHostsEntry);
                  signedData.position = 0;
                  signature = new Signature(SignedFileAdapter.defaultSignatureKey);
                  validHosts = signature.verify(signedData,output);
                  if(!validHosts)
                  {
                     _log.warn("Host signature could not be verified, connection refused.");
                     this.commonMod.openPopup(I18n.getUiText("ui.common.error"),I18n.getUiText("ui.popup.connectionFailed.unauthenticatedHost"),[I18n.getUiText("ui.common.ok")]);
                     KernelEventsManager.getInstance().processCallback(HookList.SelectedServerFailed);
                     return false;
                  }
               }
               connexionHosts = connectionHostsEntry.split(",");
               ...
Je peux passer a ça très facilement mais apparemment c'est pas suffisant:
Code:
                  validHosts = signature.verify(signedData,output);
                  if(false)
                  {
                     _log.warn("Host signature could not be verified, connection refused.");
                     this.commonMod.openPopup(I18n.getUiText("ui.common.error"),I18n.getUiText("ui.popup.connectionFailed.unauthenticatedHost"),[I18n.getUiText("ui.common.ok")]);
                     KernelEventsManager.getInstance().processCallback(HookList.SelectedServerFailed);
                     return false;
                  }
               }

Merci en tout cas pour la réponse.
 
Dernière édition:

tazman59

Contributeur
Inscrit
20 Decembre 2012
Messages
149
Reactions
27
#6
"if(!validHosts)" et "false" revient exactement à dire la même chose :p
À ta place, j'aurais simplement supprimé tout le bloc if(!validHosts) et le tour est joué ;)
 
Inscrit
20 Avril 2017
Messages
12
Reactions
0
#7
"if(!validHosts)" et "false" revient exactement à dire la même chose :p
À ta place, j'aurais simplement supprimé tout le bloc if(!validHosts) et le tour est joué ;)
Ah non je t'arrête dessuite, if(false) on ne rentre jamais dans le bloc d'instructions du if peu importe que l'host soit valide ou non, alors que if(!validHost) rentre dans le bloc d'instructions du if lorsque validHost = false.

C:
#include "stdio.h"
#include "stdlib.h"

int main(int argc, char** argv) {
    if(0)
       printf("Hello World\n");
    return EXIT_SUCCESS;
}
Bash:
ncls@ubuntu:~/work$ ./a.out
ncls@ubuntu:~/work$
De toute façon, modifier le if, ou supprimer le bloc d'instructions ne me permet pas de me connecter :'(
 
Dernière édition:

tazman59

Contributeur
Inscrit
20 Decembre 2012
Messages
149
Reactions
27
#8
Ah, autant pour moi. Vu que validHosts = false je pensais que if(false) et if(!validHosts) revenait au même, eheh.

Pour ma part en supprimant ce bloc ça marche. (Sur un client 2.36)
Au pire essaye de supprimer le return et le KernelEventManager.etc

Dis moi quoi :)
 

BlueDream

Administrateur
Membre du personnel
Inscrit
8 Decembre 2012
Messages
2 010
Reactions
149
#9
En supprimant ces quelques lignes tu ne devrais plus avoir de problème:
Code:
if(!validHosts)
                  {
                     _log.warn("Host signature could not be verified, connection refused.");
                     this.commonMod.openPopup(I18n.getUiText("ui.common.error"),I18n.getUiText("ui.popup.connectionFailed.unauthenticatedHost"),[I18n.getUiText("ui.common.ok")]);
                     KernelEventsManager.getInstance().processCallback(HookList.SelectedServerFailed);
                     return false;
                  }
En te rappelant une seconde fois que l'édition de code en temps réel avec JPEXS est expérimentale et aboutis très souvent à des erreurs au lancement du jeu.
D’où l’intérêt de se servir du ProcessCode (PPCode) même si ce n'est pas le plus simple.
 
Inscrit
20 Avril 2017
Messages
12
Reactions
0
#10
En supprimant ces quelques lignes tu ne devrais plus avoir de problème:
Code:
if(!validHosts)
                  {
                     _log.warn("Host signature could not be verified, connection refused.");
                     this.commonMod.openPopup(I18n.getUiText("ui.common.error"),I18n.getUiText("ui.popup.connectionFailed.unauthenticatedHost"),[I18n.getUiText("ui.common.ok")]);
                     KernelEventsManager.getInstance().processCallback(HookList.SelectedServerFailed);
                     return false;
                  }
En te rappelant une seconde fois que l'édition de code en temps réel avec JPEXS est expérimentale et aboutis très souvent à des erreurs au lancement du jeu.
D’où l’intérêt de se servir du ProcessCode (PPCode) même si ce n'est pas le plus simple.
Je poste le code ActionScript pour la lisibilité mais je modifies évidemment le PCode, désolé si c'était pas claire.;)

Merci pour vos réponses, le problème doit venir d'ailleurs du coup, je continue d'investiguer.
 
Haut Bas