Cours n°13

Donne le serial au monsieur



Objectif

Rajouter un bouton au crackme pour que, lorsque l'on clique dessus, un message nous indique quel est le bon serial !

Niveau

Elevé

Ce qu'il vous faut

- WinDasm (voir "Outils > Désassembleurs")

- Un éditeur hexadécimal (voir "Outils > Editeurs")

- Un éditeur de ressources (Restorator ou ResHacker)

- Le cracke-me



Introduction

Dans la lignée du cours précédent voici le 13ème cours. Vous allez voir à quoi sert ce que vous avez appris dans le dernier cours, car il faut bien le dire : l'exercice sur la calculette de Windows ne sert pas à grand chose.

Bon tout d'abord on regarde, avec Stup_Pe par exemple, en quel langage ce crackme a été programmé. On voit qu'il a été fait en assembleur. Donc aucun signe de compression quelconque.

Donc maintenant on examine ce crackme. Il y a comme la plupart du temps 2 champs à remplir : le nom et le serial. Le bouton "Ok" est grisé, en remplissant les cases il ne s'active toujours pas donc on en conclut que le bouton se dégrisera lorsque le serial sera bon. Pour savoir s'il faut ou non débloquer le bouton, le crackme est obligé de vérifier le serial à chaque fois qu'on tapera quelque chose. Contrairement à d'autres crackme où la vérification du serial s'effectue qu'au moment de cliquer sur "Ok". Il va donc falloir qu'on rajoute un bouton dans ce crackme pour ensuite afficher une messagebox en cliquant dessus pour nous donner le bon serial par rapport au nom qu'on aura précédemment tapé.

 

Ajout d'un bouton

On ouvre donc le crackme avec votre éditeur de ressources favoris. On va dans 'Dialog' pour rajouter un bouton qu'on appellera "Serial". Pour cela regardons comment sont faits les autres boutons.

 

Avec Restorator :

Après avoir cliqué sur [abI] ou 'Viewer' --> 'Edit Mode' on voit :

DEFPUSHBUTTON "&OK", 1, 37, 70, 50, 16, WS_DISABLED

Ainsi la syntaxe est la suivante :

TYPE Texte , ID , x , y , longueur , largeur , options

Donc on va rajouter :

 DEFPUSHBUTTON "&Serial", 3, 67, 90, 50, 16

On mettra 3 comme ID car le 1 est déjà attribué au bouton "OK" et le 2 au bouton "Annuler". On fait F7 pour visualiser ce que ça donne. Le nouveau bouton colle un peu trop au bas de la fenêtre. On va donc augmenter la hauteur de la fenêtre du crackme.

On change : MYDIALOG DIALOG 0, 0, 186, 106 par MYDIALOG DIALOG 0, 0, 186, 116. Et voilà. Vous pouvez organiser comme vous le voulez les boutons.

On appuie sur F8 pour valider et on enregistre.

 

Avec ResHacker :

Pour ceux qui n'aiment pas taper du code un peu à l'aveugle comme on vient de la faire avec Restorator utilisez plutôt ResHacker.

Faîtes un clic droit sur l'aperçu du crackme et sélectionner "Insérer un contrôle". Cliquez ensuite sur l'icône représentant un bouton "Ok" pour ajouter un bouton (BUTTON in english ;-) ), sélectionnez "BS_DEFPUSHBUTTON" dans style. Dans "text" tapez ce que vous voulez (pour moi ce sera "Serial") et surtout n'oubliez pas de bien mettre "3" dans l'ID. Et pour finir validez.
Vous pouvez voir votre bouton sur l'aperçu. Déplacez-le avec la souris où vous le souhaitez (vous pouvez également déplacer les autres éléments à votre guise). Une fois vos changements effectués, cliquez sur "Enregistrer" à coté de "Cacher". Puis 'Fichier' --> 'Enregistrer sous...' pour sauvegarder votre crackme modifié.

 

Pour info : pour dégriser le bouton dans les 2 éditeurs il suffit de supprimer "WS_DISABLED". Le bouton sera ainsi dégrisé. Cela peut vous servir pour vos prochains cracks. Mais si on essaye cette méthode avec ce crackme, cela marchera (il affichera le bon message) si vous ne tapez rien. Mais dès que vous tapez votre nom le bouton redeviendra grisé car il vérifie à chaque frappe de clavier.

 

Ajout de la msgbox

Bon alors on ouvre le crackme avec WinDasm. Et on va essayer de trouver le moment où il regarde si un bouton a été cliqué ou non. L'ID du bouton "Ok" est 0001. Donc on cherche "0001" en regardant si on voit pas un truc du genre "cmp [registre], 1" (vous pouvez le faire également avec le bouton "Annuler"). Et effectivement on voit un :

:00401092 6683F801 cmp ax, 0001 --> regarde si c'est le bouton "Ok" qui a été cliqué
:00401096 7518 jne 004010B0
--> saute si ce n'est pas le bouton "Ok"
:00401098 6A30 push 00000030

* Possible StringData Ref from Data Obj ->"Enregistrement..."
|
:0040109A 6816304000 push 00403016

* Possible StringData Ref from Data Obj ->"Merci de vous "  
--> le bon message !
 

Et en 004010B0 :

:004010B0 6683F802 cmp ax, 0002  --> regarde si c'est le bouton "Annuler" qui a été cliqué
:004010B4 0F85C9000000 jne 00401183 --> si ce n''est pas "Annuler" alors saute
 

Donc là il y a pleins de solutions différentes, moi je vais changer le cmp ax, 0001 pour mettre à la place un JMP qui nous emmènera vers notre bout de code. Dans ce code on mettra :

 

Recherche du serial

Maintenant on va voir où le programme stocke le bon serial afin de l'afficher avec la msgbox.

:00401090 753B jne 004010CD  --> saute si c'est pas le bon serial
:00401092 6683F801 cmp ax, 0001
--> regarde si c'est le bouton "Ok" qui a été cliqué
:00401096 7518 jne 004010B0
--> saute si c'est pas le bouton "Ok"
:00401098 6A30 push 00000030

* Possible StringData Ref from Data Obj ->"Enregistrement..."

 

Comme le programme vérifie tout le temps le serial (comme expliqué dans l'introduction) on va voir où nous mène le JNE. On tombe sur des API GetDlgItemTextA (pour info le "A" signifie qu'il fonctionne en 32 bits). Voici leur fonctionnement :

La fonction GetDlgItemText retrouve le titre ou le texte associé à un control dans une boîte de dialogue.

UINT GetDlgItemText (
HWND hDlg, // handle de la boîte de dialogue.
int nIDDlgItem, // n°ID du control
LPTSTR lpString, // adresse du buffer recevant le texte
int nMaxCount // nombre maximal de caractères formant la chaîne.
);
 

En assembleur il faut inverser, donc ce qui donne :

Ainsi voici ce que l'on a :

:004010D8 6800020000 push 00000200  --> nombre maximal de caractères
:004010DD 6850344000 push 00403450
--> le serial que nous avons tapé est stocké à cette adresse

* Possible Reference to Dialog: MYDIALOG, CONTROL_ID:03E9, ""
|
:004010E2 68E9030000 push 000003E9  
--> l'ID du champ pour le serial
:004010E7 FF7508 push [ebp+08]
--> handle

* Reference To: USER32.GetDlgItemTextA, Ord:0102h
|
:004010EA E8CD000000 Call 004011BC  
--> appel de l'API
:004010EF 6800020000 push 00000200 
--> nombre maximal de caractères
:004010F4 6850324000 push 00403250
--> le nom que nous avons tapé est stocké à cette adresse

* Possible Reference to Dialog: MYDIALOG, CONTROL_ID:03E8, ""
|
:004010F9 68E8030000 push 000003E8 
--> l'ID du champ pour le nom
:004010FE FF7508 push [ebp+08]
--> handle

* Reference To: USER32.GetDlgItemTextA, Ord:0102h
|
:00401101 E8B6000000 Call 004011BC
--> appel de l'API
:00401106 8D3550324000 lea esi, dword ptr [00403250]
--> met notre nom dans ESI
:0040110C 8D3D55364000 lea edi, dword ptr [00403655]
--> met ce qui est à l'adresse 00403655 dans EDI
 

Pour savoir ce que contient 00403655 lançons le débuggeur. On fait "Run", on tape un nom et un serial bidon. Ensuite dans la fenêtre des registres (celle en bas à gauche) tapez  00403655 dans le champ "User Addr 1". Après il suffit de cliquer en dessous sur "UA1". Et là à droite du bouton vous pourrez apercevoir un numéro ! Tapez ce serial dans le crackme tout en gardant votre nom. Et là ça marche : le bouton "Ok" se dégrise et affiche le bon message.

Pendant qu'on y est on va chercher l'adresse de l'API MessageBoxA. On clique sur les Imports on double clique plusieurs fois pour être sûr sur l'API MessageBoxA. Et on tombe sur "Call 004011C2"

Bon maintenant qu'on sait où se situe le serial et l'adresse de l'API, il va falloir trouver de l'espace dans le crackme pour insérer notre code.

 

Mise en place de notre code

On ouvre le crackme avec l'éditeur hexa et on recherche de la place (là où il y a des octets vides c'est à dire avec des 00). Allez hop il y a de la place de l'offset 750 jusqu'à 800. Ça devrait suffire. Bon on va commencer à l'offset 760 pour éviter de trop coller au texte qui est au dessus. Il va falloir trouver la correspondance de l'offset avec l'adresse WinDasm. Pour cela on prend une ligne au hasard dans Windasm, par exemple 004010CD, et on regarde l'offset, ici 4CD. On fait la différence (avec la calculatrice de Windows en mode scientifique et en hexa) : 004010CD - 4CD = 00400C00.

Donc avec notre offset 760 cela donne : 760 + 00400C00 = 00401360. Ce qui nous donne l'adresse Windasm.

Bon il n'y a plus qu'à rentrer notre code. On va voir ça avec le débuggeur de WinDasm avec le Patch Code. On pose un break point sur la ligne du :

:00401092 6683F801 cmp ax, 0001

Pour qu'il break cliquez sur "Serial". Et on remplace par un JMP 00401360. N'oubliez pas de copier la correspondance si vous voulez recopier le code hexa dans l'éditeur hexadécimal par la suite. Ce qui nous donne :

:00401092 E9C9020000 jmp 00401360

Mais il faut remplacer ces 2 lignes :

:00401092 6683F801 cmp ax, 0001
:00401096 7518 jne 004010B0

Et là il y a 6 octets (66-83-F8-01-75-18) contre 5 pour notre JMP. Donc l'octet suivant pourra mettre le bazar à la suite du code. Donc on va rajouter un NOP :

:00401092 E9C9020000 jmp 00401360
:00401097 90 nop

Donc on applique le changement et on fait un F7 pour avancer dans le code vers nos bytes libres (mais plus pour longtemps ;-) ).

Et on va entrer le code suivant (les explications de chaque ligne ont été expliquées plus haut) :

:00401360 6683F801 cmp ax, 0001
:00401364 0F842EFDFFFF je 00401098
:0040136A 6683F803 cmp ax, 0003
:0040136E 0F853CFDFFFF jne 004010B0
:00401374 6A40 push 00000040  --> Cf. cours précédent pour choisir le type de messagebox (ici Informations - Ok)
:00401376 6850324000 push 00403250 --> Titre : notre nom
:0040137B 6855364000 push 00403655 --> Message : le bon serial
:00401380 6A00 push 00000000
:00401382 E83BFEFFFF call 004011C2 --> Appel l'api MessageBoxA
:00401387 E9F7FDFFFF jmp 00401183

 

Pour tester, on applique, on enlève le BP et on clique sur "Run". On retape un nom puis on clique sur "Serial" et là apparaît un beau message avec notre nom en titre et le serial en message. On recopie le serial dans le champ prévu à cet effet et là le bouton "Ok" se dégrise et ça marche.

Vous n'avez plus qu'à faire les modifications dans votre éditeur hexa. Je ne vous explique plus comment faire, je vous fais confiance ;-) (sinon voir le dernier cours). Je rappelle qu'il faut commencer à l'offset 760.

 

Voilà ce cours touche à sa fin. J'espère que vous avez compris et que ce cours vous a plu. N'hésitez pas à me demander si vous avez un problème, une question, une suggestion ou même une critique, soit par l'intermédiaire du forum : www.forumcrack.fr.st ou par email : deamon.crack@netcourrier.com

 

Deamon le 31 août 2003

 

Passer au cours suivant >>>
[ Nag d'un crackme en Visual Basic ]