Reverse Engineering sur la calculatrice Windows
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 à ce sujet)
- WinDasm
- Un éditeur hexadécimal
- 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 ! :-P Et utilisez nos
connaissances.
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
des Windows précédent au XP ne doit pas être identiques, donc pour faire le
cours il faudra vous adapter.
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 ne 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 notamment. Je vais détailler la méthode à
utiliser avec 2 éditeurs : Restorator et ResHacker (appelé aussi RessourceHacker
ou ResHack) comme ça tout le monde sera content. Personnellement 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 dossiers 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 cliquez 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" (mais prenez les noms que vous voulez ça n'a pas
d'importance). 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. C'est à dire leur numéro pour que le
programme puisse les identifier.
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
sauvegarder votre calculette avec le nouveau menu, avec File --> Save As.
Avec ResHacker :
C'est
quasi-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 enregistrez 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 toutefois il y a des différences pour les adresses et offsets par la suite, sachez que je vais utiliser la version modifiée avec Restorator.
Ajout de la MessageBox :
Comme vous avez pu le constater, notre menu est beau mais pour l'instant il ne sert à rien car lorsqu'on clique dessus rien ne se passe ! Il va donc falloir ajouter l'affichage d'une boite de dialogue. Mais il va falloir que le programme passe par le bout de code qu'on aura rajouté lorsqu'on clique sur le menu. Pour cela on va chercher avec WinDasm l'endroit où le programme analyse quel menu a été cliqué. On va donc désassembler 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 donc
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 (octets) 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 par exemple à é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 on inverse, cf. cours sur
l'assembleur). 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).
Il faut maintenant trouver dans le programmes l'adresse du 'Call MessageBox'.
Pour cela on va regarder dans les Imports de Windasm. On
trouve USER32.MessageBoxW cela devrait faire
l'affaire. On double clique dessus plusieurs fois pour voir les Call qui
l'appellent. 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.
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 nos octets 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) en n'oubliant pas les deux "00" qui
entourent l'espace "20".
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
qu'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 intéressante. 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 ] |