Introduction:
Dans ce tutoriel on va voir comment patcher un crippleware pour l'utiliser à notre convenance.
Les cripplewares sont des sous-ensembles des demowares. Ils empêchent le shareware de remplir ses fonctions essentielles.
Les outils
Pour appliquer ce tutoriel il vous faudra...
OllyDbg v2.01 (http://Ollydbg.de/)
Detect It Easy (https://github.com/horsicq/DIE-engine/releases)
G*T*P*S*i*m v2.3.3.3 (Setup_GTPsim_Demo_2333.zip)
I: Reconaissance
On installe le programme et on l'exécute pour voir comment ça se passe.
Bon, et bien on dirait qu'après l'installation, on ne peut même pas le lancer!
Une boite de dialogue s'affiche et nous informe que notre licence d'essai est déjà terminée et que le programme va maintenant ce fermer.
Demo license period ended. Contact www.bu*b-ag*em*a.de for registration and licenses. The program will now be closed.
On scanne l'exécutable principal (G*T*P*S*i*m.exe) avec DiE (Detect It Easy) pour voir s'il est compressé, on ne dirait pas, super.
II: Patché le time-lock
Chargez l'application dans le débogueur.
On va regarder en premier les strings pour se faire une idée de ce fichier:
Click droit>Search for>All referenced strings
Ctrl+F, ou bien: clique droit>Search for text
On rentre "demo license" dans le champ de recherche, on coche "Ignore case" puis on valide
Pas de chance, aucun résultat.
Bon... on va partir sur une méthode un peu plus à la dure, tracer l'exécution depuis le début et voir ce qu'il se passe. (Comme si on cherchait un crc-check à l'ouverture.)
C'est parti, on tapote F8, et on regarde ce qu'il se passe.
On traverse 01B020F0, le splash screen commence à s'initialiser.
On traverse 01B020FE, maintenant l'image du splash screen et le texte sont chargés.
On continue puis on arrive sur un dernier call avant la fermeture d'une procédure, si on le passe la messagebox s'affiche.
On va donc recharger la cible et recommencer, mais en entrant dans ce call, et ainsi de suite jusqu'à ce que l'on tombe potentiellement sur ce qui nous intéresse.
Au final notre chaine de traçage donnera:
Arrivé sur la procédure en 0106A990, le code nous parle déjà beaucoup plus.
On va continuer à tracer avec F8 mais un peu plus attentivement.
La première partie nous intéresse plus particulièrement, on y voit une procédure, suivie d'une comparaison de nombres flottants.
Suivant le résultat, on passe sur le texte d'expiration ou non.
On rentre dans la procédure, le temps local de notre machine est récupéré, puis on sort.
Ensuite on arrive sur fucomp.
On peut convertir ça rapidement avec python pour savoir de quoi il en retourne.
datetime.datetime(2021, 8, 5, 13, 40, 18)
Soit le 5/08/2021 13h 40m 18s (la date d'expiration du programme.)
On va donc remplacer simplement JAE SHORT 0106A9E5, par: JMP SHORT 0106A9E5
On continue de tracer puis cette messagebox s'affiche.
Ça serait bien qu'on enlève aussi ce message, aller on recharge.
Et à la place de JMP SHORT 0106A9E5, on va simplement sauter plus loin dans le segment: JMP SHORT 0106A9E5
On presse F9, et.. Impeccable, le programme s’ouvre.
III: Patcher le titre
Maintenant qu'on a patché le time-lock, on a encore un peu de boulot.
On retourne chercher dans les strings, à la recherche du titre.
Clic droit>Search for>All referenced strings
Ctrl+F, ou bien: clique droit>Search for text
On rentre "time limited" dans le champ de recherche, on coche "Ignore case" puis on valide
Super, aller hop on va dessus pour poser un breakpoint au début de ça procédure.
Puis on relance, ensuite on trace.
Au bout d'un moment on arrive sur une procédure de comparaison qui semble partager.
Ici EAX, et EDX, contiennent les informations du titre de la fenêtre.
On sort de la comparaison et on arrive devant un saut conditionnel.
Si on force le saut puis qu'on lance l'exécution:
Le problème c'est que la procédure là et aussi partager et gère l'affichage du texte en général.
On ne peut donc pas faire un patch permanent sur cette offset.
On va faire un truc de goret, remplacer simplement le string par rien du tout.
Après tout, on connaît la position du texte.
On remplace simplement la première lettre par '00'
Maintenant qu'on a fait le cosmétique, il nous reste à déverrouiller la fonction la plus importante.
Pouvoir sauvegarder le travail.
IV: Patcher les routines de sauvegarde
Quand on démarre un nouveau projet avec G*T*P*s*i*m celui-ci nous demande d'enregistrer d'abord notre fichier projet.
Le problème c'est qu'ensuite on ne peut pas sauvegarder nos modifications, donc le fichier projet reste vide.
On retourne dans les strings pour chercher "saving project changes".
Et on repère des choses.
On retrouve ce string même plusieurs fois un peu plus bas, cela doit dépendre de quel bouton est pressé, car il y a plusieurs boutons d'enregistrement.
On va donc poser des breakpoints un peu partout et voir où ça va break en premier.
On note donc ses procédures:
Et apparemment pour sauvegarder depuis le menu c'est l'offset 019FBEBC
On trace vite fait, mais rien de bien probant, si on ferme le projet et qu'on essaye d'en refaire un nouveau.
Là c'est à l'offset 019F73DC que ça break.
Maintenant il faudrait rediriger le flow sur cet endroit, vu qu'on sait que ça sauvegarde à la création de nouveau projet.
Si on revient à 019FBEBC, enfaite en dessous du JMP ce trouve une autre petite procédure qui renvoie sur cet endroit.
Aller, on va faire un patch et voir ce que ça donne en traçant si on casse la stack ou pas.
Le flow est redirigé, mais il nous manque un flag.
On patch: JNE SHORT 019F7423
Par: JMP SHORT 019F7423
On lance avec F9
Impeccable !
On en profite pour répéter l'opération pour le dernier offset que l'on a trouvé (019FBFEC)
Où l'on remplace: OR ECX,FFFFFFFF
Par: JMP SHORT 019FC001
On doit répéter l'opération d'une manière similaire à deux autres endroits: 01945FD6
Et 019457C4, pour activer la sauvegarde des tables en .csv
Puis à 4 autres offsets pour sauvegarder les graphs.
Pour trouver toutes les positions, il suffit d'aller dans les strings et de chercher "inhibited"
La première procédure à patcher: 01416355
014165F2
0141690D
Le dernier: 01416ABD
Voilà, on a enfin fini de court-circuiter la "démonstration" du logiciel.
Ça fait un bon paquet de patchs aussi.
V: Essais en vracs et conclusion
Voici quelques notes en vracs de mes essais pendant le reverse de ce programme.
Le pointeur pour la sauvegarde des fichiers semblent être en 019E358E: MOV BYTE PTR DS:[EBX+85F],0
On trouve la version enregistrer possiblement en 019E2852: MOV BYTE PTR DS:[EAX+85F],1
Mais je n'ai pas trouvé/compris qui appelle cette procédure.
J'ai réussi à dévier le flow d'exécution pour faire apparaitre un dialogue d'enregistrement (auquel on n’a pas accès même en démo).
Les cases par défaut sont grisées, il semble y avoir un évènement de surveillance de touche sur l'input pour entrer le nom.
les textes 'hello' sont récupérés de la clé de registres:
Mais bon rien de bien concluant pour essayer de comprendre le mécanisme.. Tout est en pièce, j'ai cru repérer une proc de base64 à un endroit.
Pour conclure, je dirais que ces genres de logiciels sont bien plus compliqués d'un point de vue réflexion.
Contrairement au shareware classique où à partir d'une condition on va à droite ou à gauche, ici on n’a pas le choix.
On va tout droit, et pour tourner à gauche et bien... Il faut tracer ça propre route, cela demande du temps pour comprendre les procédures du programme et trouver un moyen de connecter les fonctionnalités, sans produire de crashs.
Dans le warez, en général les crackers possèdent les versions retails, donc ils ne s'embêtent pas à reconstruire les versions crippled/démo distribuées au publique.
Xylitol, 24/o1/2o22
Copyright (C)- xtx Team (2021)