Cours n°12 : Reverse Engineering sur la calculatrice Windows

 

    Objectif : 

        1° Rajouter un menu.

        2° Afficher une boîte de dialogue quand on clique sur notre nouveau menu.

    Niveau :

        - Elevé.

    Ce qu'il vous faut :

        - Connaître les bases de l'Assembleur (lire mon cours)

        - WinDasm (Voir page "Outils")

        - Un éditeur hexadécimal comme HexDecCharEditor (Idem)

        - Un éditeur de ressources (Restorator ou ResHacker)

        - La calculatrice de Windows XP (dans Windows/System32/Calc.exe)

        - Et un brin de logique !

 

    Introduction

        Cette fois-ci ce n'est pas vraiment du cracking mais du Reverse Engineering ! Domaine dans lequel je suis encore débutant mais qui est tellement passionnant et intéressant ! Car ce qu'on va faire ne sert pas à grand chose sinon de se faire plaisir !

        Pourquoi la calculatrice de Windows particulièrement ? Je ne sais pas trop, j'ai pris le premier petit programme avec un menu que j'ai vu ! Et de plus tout le monde doit l'avoir. Par contre je pense que la calculatrice de Windows 98 doit être légèrement différente.

 

    A l'attaque !

        Bon alors tout d'abord on va prendre la calculatrice de Windows (dans Windows/System32/Calc.exe) et la copier dans un autre dossier, pour ne pas abîmer l'original car on sait jamais !

        On va tout d'abord ajouter un menu à coté du menu "?". Pour cela on va utiliser un éditeur de ressources. Ces logiciels sont très utilisés pour la traduction de programmes. Je vais détailler la méthode à utiliser avec 2 éditeurs : Restorator et ResHacker (appelé aussi RessourceHacker ou ResHack). Personnelement j'utilise Restorator mais le plus utilisé est ResHacker.

 

    Avec Restorator

        Vous lancez donc Restorator, vous faîtes File --> Open et vous sélectionnez la calculette que vous avez copié dans un dossier. vous pouvez voir différents dossier sous "Calc.exe". Voici un rapide descriptif de ces dossiers :

    Donc ce qui nous intéresse ici c'est Menu. On regarde donc dans menu puis 106. Là on voit les menus de la calculette (Edition, Affichage et ?). Pour mieux visualiser tout ça cliquer sur le bouton "ab]" (ou Vievew et Edit Mode). Là une fenêtre s'ouvre avec la représentation du menu.

    On va donc ajouter un menu que je nommerai "Infos" et un sous-menu "Reverse". Comme vous pouvez le voir un menu s'écrit comme ceci :

 POPUP "&Edition"
{
MENUITEM "Co&pier\tCtrl+C", 300
MENUITEM "C&oller\tCtrl+V", 301
}

    Le caractère & signifie que la fonction peut être appelé avec le raccourci clavier : ALT+[lettre qui suit le &]. Ici ALT+E pour Edition.
    Le \tCtrl+C est le raccourci qui exécute la fonction.
    Le 300 ou 301 ici sont les ID des menus. Leur numéro pour que le programme les identifie.

    On va donc mettre après le menu "&?" :

 POPUP "&Infos"
{
MENUITEM "&Reverse", 318
--> Je mets 318 car il ne semble pas être utilisé par une autre fonction, mais vous pouvez mettre ce que vous voulez du moment qu'il n'est pas déjà pris.
}

    Une fois cela fait on appuie sur F7 afin de mettre à jour la fenêtre de visualisation. Et on voit bien notre nouveau menu. Ensuite on appuie sur Commit changes (ou F8) pour appliquer les changements. Mais comme vous avez pu le voir il y a plusieurs menus (106 ; 107 ; 108 et 109). Car suivant le mode de la calculatrice (standard ou scientifique) vous n'aurez pas les mêmes menus. Il faut donc rajouter notre menu "Info" - "Reverse" dans les 3 premiers (le 4ème est pour l'aide). L'ID de notre menu doit être le même pour les 3.
    Pensez à faire F8 après chaque modification.

    Voici ce que vous devez obtenir pour le menu 106 :

106 MENU
{
POPUP "&Edition"
{
MENUITEM "Co&pier\tCtrl+C", 300
MENUITEM "C&oller\tCtrl+V", 301
}
POPUP "&Affichage"
{
MENUITEM "S&tandard", 305
MENUITEM "S&cientifique", 304
MENUITEM SEPARATOR
MENUITEM "Groupement des ch&iffres", 303
}
POPUP "&?"
{
MENUITEM "&Rubriques d'aide ", 317
MENUITEM SEPARATOR
MENUITEM "À &propos de la Calculatrice", 302
}
POPUP "&Infos"
{
MENUITEM "&Reverse", 318
}

}

    Une fois tout cela fait, vous pouvez sauvegardez votre calculette avec le nouveau menu, avec File --> Save As.

 

    Avec ResHacker

        C'est presque identique ! Vous ouvrez la calc.exe, vous allez dans Menu, puis 106 et enfin 1036. Là il apparaît directement la fenêtre de visualisation du menu. Vous rajoutez :

POPUP "&Infos"
{
MENUITEM "&Reverse", 318
}

        Et enfin vous cliquez sur Enregistrer. Vous faites la même chose pour le menu 107 et 108. Et pour finir vous enregistres le .exe.
 

    Note

        Suivant que vous avez modifié avec Restorator ou ResHacker les bytes du programmes ne seront pas identiques, mais je ne pense pas que cela change quelque chose dans la correspondance avec la suite de mon cours. Si quelque fois il y a des différences dans les adresses et offset par la suite, sachez que je vais utiliser la version modifié avec Restorator.

 

    Ajout de la MessageBox

        Comme vous avez pu le constater, notre menu il est beau mais pour l'instant il ne sert à rien car quand on clique dessus rien ne se passe ! Il va donc falloir ajouter l'affichage d'une boite de dialogue. Mais il va falloir que quand on clique sur le menu le programme passe par le bout de code qu'on aura rajouté. Pour cela on va chercher avec WinDasm l'endroit où le programme regarde sur quel menu on a cliqué. On va donc désassemblé notre calculette modifiée. Et tout au début on peut voir :

MenuID_006A

Edition {Popup}
Copier Ctrl+C [ID=012Ch]
Coller Ctrl+V [ID=012Dh]

Affichage {Popup}
Standard [ID=0131h]
Scientifique [ID=0130h]
Groupement des chiffres [ID=012Fh]

? {Popup}
Rubriques d'aide [ID=013Dh]
À propos de la Calculatrice [ID=012Eh]

Infos {Popup}
Reverse [ID=
013Eh]
--> Notre menu avec son ID.
 

        Comme vous l'avez vu l'ID du menu "Reverse" est 13E alors que l'on avait mis 318 ! Et bien comme le "h" l'indique c'est que l'ID est en hexadécimal ici alors que nous l'avions noté en décimal tout à l'heure.

        Pour savoir quel menu a été cliqué le programme va comparer la valeur que lui a renvoyé le clic avec les ID des menus. On va donc faire une recherche dans WinDasm de 013D par exemple (l'ID de la rubrique d'aide). On tombe premièrement sur  :

:010026DA 83FE51 cmp esi, 00000051
:010026DD 7411 je 010026F0
:010026DF 83FE52 cmp esi, 00000052
:010026E2 740C je 010026F0
:010026E4 81FE3D010000 cmp esi, 0000013D
:010026EA 0F85DF000000 jne 010027CF
 

        Mais les autres ESI sont comparés à 51 et 52. et en regardant les autres ID, aucun ne correspond à 51 et 52. On continue donc notre recherche. Et on arrive ici :

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:01003A9F(C)

|
:01004166 81FE8D000000 cmp esi, 0000008D
:0100416C 0F8458010000 je 010042CA
:01004172 81FE2B010000 cmp esi, 0000012B
:01004178 0F8667010000 jbe 010042E5
:0100417E 81FE31010000 cmp esi, 00000131
:01004184 7620 jbe 010041A6
:01004186 81FE35010000 cmp esi, 00000135
:0100418C 0F8653010000 jbe 010042E5
:01004192 81FE3C010000 cmp esi, 0000013C
:01004198 7617 jbe 010041B1
:0100419A 81FE3D010000 cmp esi, 0000013D
:010041A0 0F853F010000 jne 010042E5
 

        C'est ici que le programme regarde quel menu a été cliqué. Ce qu'il faudrait qu'on fasse c'est mettre une comparaison de esi avec 13E (notre ID) et faire un saut vers la messagebox si c'est égal. Mais où mettre la comparaison ? Il n'y a pas de place ici ! On voit que cette partie du code est appelée par un saut conditionnel. Et bien c'est parfait ça ! Voici le saut qui mène vers la comparaison des ID.

:01003A9F 0F87C1060000 ja 01004166

        On va donc remplacer ce JA 01004166 par un JA qui ira vers un endroit où nous allons mettre :

cmp esi, 13E    --> regarde si c'est bien notre menu qui a été cliqué
jne 01004166    --> si c'est pas le menu saute en 01004166 pour continuer la comparaison
afficher la messagebox    --> nous verrons plus tard comment l'écrire
jmp 01004166    --> retourne en 01004166

        Maintenant il va falloir trouver de la place pour mettre tout ça. On va donc aller voir tout en bas du code dans Windasm. Là où on voit :

:010136AE 00000000000000000000 BYTE 10 DUP(0)
:010136B8 00000000000000000000 BYTE 10 DUP(0)
:010136C2 00000000000000000000 BYTE 10 DUP(0)

        Ce sont des bytes libres. On aura donc la place de les mettre ici. Regardons cela dans l'éditeur hexadécimal. Effectivement à l'offset 12AAE (adresse 010136AE Windasm) on voit des 00. Pas la peine de trop coller au code qui est au-dessus. On commencera à écrire en 12AC0 (mais on pourrait commencer n'importe où) donc à l'adresse 010136C0 de WinDasm. On retient cette adresse WinDasm car on va installer notre saut JA. On ouvre donc le débuggeur. Et on pose un break point en 01003A9F (adresse du JA qu'on a décidé de changer). On fait Run et on clique sur la Rubrique d'aide et là bien sur ça break.

        On clique sur Patch Code pour mettre notre nouveau saut : ja 010136C0. On fait entrée et là on clique sur Copy ! Car ce qui nous intéresse c'est le code en hexa. On fait "Apply Patch", on valide et on ferme le Patch Code.

 

        Avant de continuer je vais vous montrer comment marche une MessageBox :

MessageBox(
HWND hWnd, // Handle de la fenêtre (si 00, pas de fenêtre attribuée)
LPCTSTR lpText, // adresse du texte de la MessageBox
LPCTSTR lpCaption, // adresse du titre de la MessageBox
UINT uType // style de la messagebox (bouton Ok, Annuler...etc) ;

        Donc en assembleur il faut écrire ça à l'envers (car on utilise des PUSH donc à cause de la pile). Ce qui donnera :

Push code_du_style_souhaité
Push adresse_du_titre
Push adresse_du_texte
Push 00
Call MessageBox

        Pour le code du style vous pouvez mettre 00 si vous n'avez rien de particulier à mettre (mais on verra ça après).

        Il va falloir écrire le titre et le texte de la message box dans l'éditeur hexa à une adresse que nous aurons définie. On va donc mettre le titre en 12B00 et le texte en 12B20 (adresse windasm : 01013700 et 01013720).

        Le Call MessageBox il faut trouver dans le programme l'adresse de celle ci. Pour cela on va regarder dans les Imports de Windasm. On trouve USER32.MessageBoxW cela devrait faire l'affaire. On double clique dessus plusieurd fois pour voir les Call qui l'appelle. On voit qu'il s'agit de :

FF15A8110001 Call dword ptr [010011A8]
 

        Donc maintenant nous avons tous les éléments nécessaires. Nous pouvons donc continuer.

 

        Donc toujours dans le débuggeur vous devez être sur le break du JA qui vient d'être modifié. On va donc faire F7 ou F8 (Avance pas à pas). On voit bien dans la fenêtre de droite :  :010136C0 add byte ptr [eax], al

        Ce qui signifie que nous sommes bien sur notre bytes vides. On lance Patch Code et on va rentrer ces instructions (faites entrée après chaque instruction tapée) :

cmp esi, 0000013E    --> Compare pour savoir si c'est le menu Reverse qui a été cliqué
jne 01004166    --> Retourne à la routine si c'est pas le menu Reverse
push 00    --> Style de la MessageBox
push 01013700     --> Adresse du titre de la MessageBox
push 01013720     --> Adresse du texte de la MessageBox
push 00        --> Handle de la fenêtre
call [010011A8]    --> Appel l'API MessageBoxW
jmp 01004166        --> Retourne à la routine

        N'oubliez surtout pas de faire "copier" et de coller ça dans n'importe quel fichier pour garder les valeurs hexadécimal à rentrer.

        Vous pouvez faire Apply Patch et cliquez sur Run. Là vous cliquez désormais sur "Infos" --> "Reverse"? Il va breaker si vous n'avez pas enlevé le BP et vous recliquez sur Run pour continuer. Et là une boite de dialogue vide apparaîtra. Bon ça à l'air de marcher notre modification ! Il n'y a plus qu'à rentrer tout ça dans l'éditeur hexa :

:01003A9F 0F871BFC0000 ja 010136C0 --> Offset 2E9F
--------------------------------------------------
:010136C0 81FE3E010000 cmp esi, 0000013E --> Offstet 12AC0
:010136C6 0F859A0AFFFF jne 01004166
:010136CC 6A00 push 00000000
:010136CE 6800370101 push 01013700
:010136D3 6820370101 push 01013720
:010136D8 6A00 push 00000000
:010136DA FF15A8110001 call dword ptr [010011A8]
:010136E0 E9810AFFFF jmp 01004166
 

        Ensuite vous allez pouvoir marquer le titre que vous souhaitez pour votre messagebox à l'offset : 12B00 (01013700). Mais il faut mettre des 00 entre chaque lettre. Par exemple "I n f o r m a t i o n s". Attention à bien laisser 2 octets ( 2 x "00") avant le 12B20 (adresse du texte). Si votre titre est trop long alors changez l'adresse du texte.

        Une fois le titre écrit on fait pareil pour le message en 12B20. Par exemple "R e v e r s e   b y   D e a m o n !". Pour séparer 2 mots il faut bien mettre un espace (20 en hexa).

        On enregistre et on teste ! Et voilà ! C'est-y pas beau ? :-) Pour faire mieux on peut changer le style de la messagebox (avec le push 00). Pas besoin de passer par le Patch Code de WinDasm car le PUSH 00 correspond à 6A 00 donc vous pouvez le remplacer directement dans l'éditeur. Attention c'est le premier PUSH 00 (qui se trouve après le jne) car le 2ème c'est la handle de la fenêtre. Voici par quoi remplacer le 00 d'après mes tests ! :-)

        Le premier chiffre correspond au type de message box :

        Le second chiffre correspond aux boutons disponibles (Ok, Annuler ...)

        Donc en mettant un PUSH 24 vous obtiendrez une question avec Oui et Non comme choix de boutons. Mais sachez que en appuyant sur n'importe quel bouton le résultat est le même car nous avons pas fait de test sur le bouton appuyé.

 

        Voilà ce cours touche à sa fin ! Je viens de vous faire découvrir le reverse engineering, discipline très peu utilisée. On peut l'utiliser pour par exemple intégrer un keygen à un programme en ajoutant un menu qui nous donnerait le bon serial. Mais il y a pleins d'autres possibilités...

 

Deamon le 22 et 23 août 2003

Passer au cours suivant >>>
[ Donne le serial au monsieur ]