|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Ce cours est un reflet fidèle du cours intégré au crack de ma création de PowerArchiver 9.20.07 fr
Windasm 8.9 Pour désassembler le programme (transformation en langage d'assemblage) et pour trouver les string data references nécessaires pour élaborer le crack. WinHex 10.2
Offset Déplacement depuis le début de la zone de code d'un programme. EB 90
Détail des modifications POWERARC.EXE
POWERARC.EXE
Aujourd'hui on s'attaque à un logiciel très connu dans le monde de la compression de fichiers.
1/ La procédure d'enregistrement dans POWERARC.EXE
En ouvrant le logiciel on voit une fenêtre avec un bouton "Entrez le code d'enregistrement".Si on clique sur ce bouton on arrive dans une boîte d'enregistrement avec 2 champs à remplir. Entrons comme couple nom / code le couple pifoman / 123456. Une boîte s'affiche disant "Enregistrement incorrect. Essayez de réentrer le code que vous avez reçu.Si vous rencontrez de nouveau un problème, contactez ordering@conexware.com pour de l'aide". Prenons dans ce message le mot "incorrect" (je l'ai choisi car c'est le même mot en anglais) et cherchons le dans les string data référence de POWERARC.EXE que nous avons au préalable désassemblé dans w32dasm par la commande Disassembler -> Open File to disassemble -> POWERARC.EXE. Les string data reference dans w32dasm on y accède par le bouton nommé Strn Ref dans la barre de bouton de w32dasm. Rien qui nous parle d'enregistrement incorrect. Bizarre ! On va faire une recherche de la chaîne "Enregistrement incorrect" en ouvrant POWERARC.EXE dans winhex. Faites dans winhex Recherche -> texte -> Enregistrement incorrect en cochant la case "jeu de caractères unicode".Vous trouvez alors la chaîne "Enregistrement incorrect" à l'offset 250C00 (regardez la barre de statut de winhex une fois le E de Enregistrement sélectionné).En descendant un peu vous voyez la chaîne "Enregistrement accepté! Merci d'avoir acheté PowerArchiver.".L'offset du début de cette chaîne est en 250D54. On va maintenant travailler exclusivement sur cette dernière chaîne.
a/ Conversion d'un offset dans winhex en adresse dans w32dasm à l'aide des sections On revient à POWERARC.EXE désassemblé dans w32dasm. On va calculer l'adresse à laquelle correspond l'offset 250D54 dans POWERARC.EXE désassemblé.Pour cela regardons les sections de POWERARC.EXE en haut du listing de désassemblage de POWERARC.EXE dans w32dasm.
Disassembly of File: C:\Program Files\PowerArchiver\POWERARC.EXE Number of Objects = 0008 (dec), Imagebase = 00400000h Object01: CODE RVA: 00001000 Offset: 00000400 Size: 00336800 Flags: 60000020
L'offset 250D54 est compris entre l'offset de début de section 00000400 et l'offset de début de section 00336C00. Donc l'offset 250D54 appartient à la section nommée CODE. Pour calculer l'adresse correspondant à l'offset 250D54 on utilise la formule suivante : Prenons la calculatrice de windows dans Démarrer -> exécuter -> calc.exe en mode hexadécimal (bouton hex) Conclusion : l'adresse dans POWERARC.EXE correspondant à l'offset 250D54 est 00651954
b/ Localisation de la routine de calcul du vrai serial Maintenant qu'on a l'adresse faisons une recherche de cette adresse dans le code désassemblé pour voir où est le message "Enregistrement accepté! Merci d'avoir acheté PowerArchiver.". Dans w32dasm faites Search -> Find Text -> 00651954.Vous repérez alors l'utilisation de cette adresse à l'adresse 006517B1.Voici le code qui précéde l'endroit où la chaîne "Enregistrement accepté! Merci d'avoir acheté PowerArchiver." est appelée.
La routine d'enregistrement est située à l'adresse 00651680.Comment est ce que je sais ça ? Eh bien je pars de l'adresse trouvée 006517B1 et je remonte dans le code en utilisant ce qui est dit dans les Referenced by. En l'occurence ici w32dasm nous dit que l'on arrive en 006517B1 par l'une des 2 adresses 00651791, 0065179F. Prenons en une au choix. Par exemple 00651791. Ensuite faites SHIFT F12 -> 00651791 pour aller à l'adresse 00651791 et appuyez sur la flèche haut du clavier.En réitérant le procédé vous arrivez sur l'adresse 00651688. Là juste au dessus vous voyez un call à la suite duquel on effectue un saut conditionnel (jne 00651719).C'est le schéma classique de test d'enregistrement ; le call faisant l'appel à la procédure de comparaison serial entré / serial calculé.Ce qu'on va faire maintenant c'est tracer l'exécution du programme depuis l'adresse 00651679. c/ Session de debugging de POWERARC.EXE dans la routine d'enregistrement Pour cela chargez POWERARC.EXE en mémoire via le débugger par la commande CTRL L de w32dasm.Démarrez ensuite le programme par F9 puis allez saisir le couple nom / code suivant pifoman / 123456 dans la boîte d'enregistrement de POWERARC.EXE sans faire OK dans POWERARC.EXE. Revenez ensuite à w32dasm et faites SHIFT F12 -> 00651679 -> OK puis F2. Vous venez de mettre un point d'arrêt (on dit encore breakpoint , en abrégé bp) sur l'adresse 00651679. Faites OK dans la fenêtre d'enregistrement de POWERARC.EXE. A ce moment le debugger de w32dasm surgit. Il vient de s'arrêter sur l'adresse 00651679 où on vient de mettre le bp.Faites 3 fois F8 (exécution pas à pas des lignes de code sans entrer dans les call mais en les exécutant quand même).Dans la grande fenêtre du debugger (celle qui s'était ouverte quand vous aviez fait CTRL L) en cliquant sur le bouton ebp vous voyez l'état de la pile du registre ebp.
[ebp-0000000C] - 010428a8 .(..
Si vous cliquez sur 010428a8 (cette adresse est peut être différente chez vous) vous voyez en bas dans le rectangle Source For Data Disp 2 que l'adresse 010428a8 est l'adresse du premier octet de la chaîne contenant le faux serial entré à savoir 123456
Address: 010428A8 is Not in a Loaded Module.
De même vous voyez que 0103fc98 (cette adresse est peut être différente chez vous) pointe vers la chaîne contenant le nom entré à savoir pifoman.Ca c'est typique d'une procédure d'enregistrement. En effet en général on passe le code et le nom à la fonction de calcul et de comparaison des serials (ici le call 0065156C ) puis ensuite on appelle la fonction (avec un call).Allons explorer l'intérieur de la fonction en appuyant sur F7.Après plusieurs F8 vous arrivez ici.
Arrivé sur 006515A6 vous voyez en interrogeant la valeur du registre [ebp-10] (clic dans la grande fenêtre du débugger sur le bouton ebp puis clic sur [ebp-00000010]) que [ebp-10] pointe sur la chaîne 3086307F (regardez en bas dans le rectangle Source For Data Disp 2).C'est le vrai serial correspondant au nom entré pifoman.Il est de longueur 8. On pourrait s'arrêter là mais nous ce qu'on veut c'est craquer le programme.Donc on continue. Arrivé en 006515B1 vous voyez que le ZF (Zero Flag) vaut 0 (regardez en dessous de la lettre Z en haut dans la grande fenêtre du débugger sous le O D I T S Z A P C).Le jne 006515B9 (jump if not equal to zéro) fait sauter le programme vers l'adresse 006515B9 si dans le dernier calcul on n'a pas obtenu 0 auquel cas ZF=0. Ici ZF = 0 (cf grande fenêtre du debugger). Donc on saute par dessus le mov [ebp-09], 01.Il faut annuler ce saut pour exécuter cette instruction mov [ebp-09], 01 et dire au programme que le code entré correspond au serial attendu.Comment faire cela : 2 techniques possibles au choix.
Solution 1 : on modifie ZF en le mettant à 1 (ZF est un bit qui vaut 0 ou 1).
Solution 2 : on transforme l'instruction assembleur jne 006515B9 avec le patcher asm
Faites ensuite F9 une fois la modification effectuée.Voila on est enregistré.Le problème c'est que si vous effectuez physiquement la modification dans une copie de POWERARC.EXE ouvert dans winhex en remplaçant par la commande ALT G -> 2509B1 (2509B1 c'est offset donné dans w32dasm dans la barre de statut quand vous sélectionnez l'adresse 006515B1) le code hexadécimal suivant en rouge vous voyez que l'enregistrement ne dure que la durée pendant laquelle le logiciel reste ouvert. :006515B1 7506 jne 006515B9
2/ Enregistrement complet dans POWERARC.EXE
On commence par annuler le changement que l'on vient de faire avec winhex. Ce que l'on va faire puisque [ebp-10] = 3086307F = vrai serial et que [ebp-08] = 123456 = faux serial quand on arrive sur 006515B1 et que le call 00405550 en 006515AC ne sert à rien (il ne sert qu'à comparer le vrai serial au faux serial) on va dérouter ce call vers une zone de code que l'on va nous même coder et qui va se charger de copier le vrai serial à la place du faux en mémoire. Vous vous demandez comment est ce que l'on va faire cela ? On va le faire en assembleur. Ca devient très technique mais je vais essayer être le plus précis possible.
a/ Test d'utilité d'un call Premièrement vérifions que le call 00405550 en 006515AC ne sert à rien.Allez dans copie de POWERARC.EXE ouvert dans winhex puis à l'offset 2509AC remplacez le code hexadécimal suivant en rouge.
:006515AC E89F3FDBFF call 00405550 Si vous lancez le programme après avoir fait la modification vous voyez que le programme ne plante pas quand on s'enregistre (pas de fermeture brutale ou d'erreur fatale).Donc le call 00405550 ne sert à rien.
b/ Choix de la zone de code où installer notre patch On commence par choisir l'endroit où l'on va mettre notre code qui va se charger d'écraser en mémoire le faux serial par le vrai. J'ai choisi l'offset 336AA0 dans POWERARC.EXE car il est situé à la fin d'une section (là où il y a plein de 00 qui ne servent à rien, ces 00 sont des bytes rajoutés par le compilateur au moment de la compilation du programme). L'offset 336AA0 (cf paragraphe plus haut) est situé à la fin de la section CODE et juste avant le début de la section suivante la section DATA).
c/ Branchement vers notre zone de code Nous avons déterminé la zone de code où insérer notre patch.Elle est à l'offset 336AA0.Cet offset correspond dans w32dasm à l'adresse 007376A0 (007376A0 = 336AA0 - 00000400 + 00001000 + 400000).On veut brancher le call en 006515AC sur notre patch : On a On veut Nous on veut savoir quoi mettre dans les 4 bytes ??. On fait 007376A0 - 006515B1 = adresse d'arrivée - adresse instruction suivante = E60EF = 00 0E 60 EF (on complète avec des 0 car les adresses sont toujours sur 4 bytes). En inversant les bytes cela donne EF600E00.On a donc à la place des 4 bytes ?? (à partir de l'offset 2509AD dans copie de POWERARC.EXE ouvert dans winhex) :006515AC E8EF600E00 call 007376A0
d/ Ajout d'une boîte de dialogue Suite à une série de tests il s'avère que le serial calculé fait toujours 8 caractères.Si le serial entré fait moins de 8 caractères POWERARC.EXE lève des exceptions à la suite de l'application de mon patch même si l'enregistrement est effectué correctement dans le registre avec le bon serial au moment de la fermeture du programme après l'enregistrement. Par la suite (relancement de POWERARC.EXE) ces erreurs n'apparaissent plus du tout une fois enregistré avec le patch. Comme je ne suis pas adepte des plantages d'application (c'est seulement 1 seule fois au moment de la fermeture de l'application que ça arrive, après avoir entré un code inférieur à 8 caractères ou un nom inférieur à 2 caractères) j'ai décidé d'ajouter une boîte de dialogue à l'application.Celle-ci affiche si le code entré fait moins de 8 caractères le message "Message de pifoman : \nLe code d'enregistrement doit faire minimum 8 caractères." et si le nom entré fait moins de 2 caractères le message "Message de pifoman : \nLe nom d'enregistrement doit faire au moins 2 caractères.". L'affichage de cette boîte dans les 2 cas ne touche pas au programme (ne l'enregistre pas au nom donné).Si le code entré fait au moins 8 caractères et que le nom a au moins 2 caractères mon patch s'applique et ma boîte de dialogue ne s'affiche pas. On va utiliser la documentation sur les API windows (allez sur la MSDN de Microsoft).Une boîte de dialogue est gérée par la fonction MessageBoxA de l'API User32.On la trouve dans C:\windows\system32\User32.dll. Cette dll contient le code de la fonction MessageBoxA. Sur la MSDN vous avez la signature de la fonction qui est la suivante MessageBoxA( identifiant de la boîte de dialogue , message , titre, icône et boutons). En assembleur cela donne le schéma suivant. push 00000010 // passage de l'argument 4 à MessageBoxA : icône erreur avec un bouton OK On écrit alors les messages suivants dans copie de POWERARC.EXE ouvert dans winhex à partir des offsets suivants en écrivant chaque lettre de chaque phrase une par une à la queue leu leu : Titre messages : offset 336B10 : Attention ! (offset 336B11 on écrit le premier t de Attention! ...)
e/ Remplacer le faux par le vrai serial en mémoire Voici le code assembleur de ma composition que je vais utiliser.On écrira dans une copie de POWERARC.EXE ouverte dans winhex à partir de l'offset 336AA0 à la queue leu leu le code hexadécimal en rouge suivant (86 octets à écrire)
Pour connaître le code hexadécimal des instructions assembleur j'utilise le patcher asm de w32dasm.Pour cela je désassemble POWERARC.EXE qui n'a pas été enregistré, puis CTRL L puis SHIFT F12 -> 006515AC -> OK -> F2 et F9.Je clique sur le bouton Patch Code de la petite fenêtre du debugger de w32dasm qui apparaît aussitôt une fois pifoman / 123456 entré et validé avec le bouton OK de la boîte d'enregistrement de POWERARC.EXE.J'entre alors call 007376A0 suivi de entrée puis Apply Patch -> Close -> Oui -> Oui. Ensuite je fais F7 pour descendre dans le call 007376A0 puis je clique sur le bouton Patch Code de la petite fenêtre du debugger et je tapes chaque ligne de code asm (par exemple mov eax, dword ptr [ebp-08]) suivi d'une pression sur la touche entrée du clavier. Je vois ainsi apparaître en même temps le code hexadécimal correspondant aux instructions asm (ne tapez pas les dword ptr).Une fois terminé je clique sur les boutons Copy puis Close du patcher asm et je colle le tout dans notepad.
f/ Détails de calculs hexadécimaux sur les adressages 007376A0 = 336AA0 - 00000400 + 00001000 + 400000
:007376A0 8B45F8 mov eax, dword ptr [ebp-08]
:007376AC 7418 je 007376C6
:007376DF 668A11 mov dl, byte ptr [ecx]
g/ Localiser la longueur du faux serial dans la mémoire Dans le code du patch paragraphe e/ j'ai dit qu'à l'adresse 007376B9 l'adresse eax-04 avec eax = [ebp-08] = adresse du premier byte du faux serial 123456 contenait la longueur de la chaîne 123456.Comment est-ce que j'ai trouvé ça ? Eh bien j'ai lancé POWERARC.EXE et saisi comme nom / code pour l'enregistrement pifoman / 1111...2 (996 fois le chiffre 1 et 1 fois le chiffre 2) puis OK.Le code a donc 997 caractères.Cela donne en hexadécimal 03E5. Ensuite j'ai ouvert winhex et j'ai été dans le menu Outils -> éditeur de RAM. J'ai cliqué sur le processus powerarc qui tourne en mémoire puis sur powerarc.exe (6.9 Mo). J'ai ensuite recherché par la commande CTRL ALT F -> 000003E5 la valeur hexadécimale 000003E5 pour voir si le programme calcule cette donnée. J'ai trouvé un endroit très intéressant 4 bytes juste avant l'adresse du premier byte du code entré 1111...2. Comme l'adresse du premier byte du faux serial est dans [ebp-08] on en déduit que l'adresse où est stockée la longueur du faux serial est [ebp-08] - 4. Pour accéder au contenu de cette variable il suffit de rajouter les crochets qui veulent dire "contenu de" soit au total [[ebp-08] - 4] ou encore en remplaçant [ebp-08] par sa valeur on obtient [eax - 4].
h/ Banchement de notre boîte de dialogue sur POWERARC.EXE Les boîtes de dialogue "Message de pifoman : \nLe code d'enregistrement doit faire minimum 8 caractères." et "Message de pifoman : \nLe nom d'enregistrement doit faire au moins 2 caractères." n'existent pas dans le programme POWERARC.EXE. Il nous faut d'abord les créer. Comme les 2 boîtes ont les mêmes caractéristiques (titre, bouton OK, icône erreur) on ne crée qu'une seule boîte de dialogue qui affichera le premier ou le second message. Pour cela (cf plus haut) il faut passer les 4 paramètres à la fonction MessageBoxA (c'est elle qui gère l'affichage de la boîte) et ensuite trouver dans le listing de désassemblage de POWERARC.EXE désassemblé dans w32dasm l'adresse d'appel de cette fonction. Vous tombez par exemple ici * Reference To: user32.MessageBoxA, Ord:0000h L'adresse d'appel des MessageBox est l'adresse 00408AD0. On veut l'appeler depuis l'adresse 007376D5 :007376D5 E8F613CDFF call 00408AD0 Comment calculer le code hexadécimal correspondant au call 00408AD0 ? Il nous faut d'abord le code E8 correspodant au call et ensuite 4 bytes F6 13 CD FF pour l'adresse 00408AD0. Voici le détail du calcul : 007376DA - 00408AD0 = 32EC0A (nombre de bytes sautés - 1 depuis 007376DA).
-> Une fois enregistré sous le nom pifoman en examinant le registre par démarrer -> exécuter -> regedit.exe à la recherche de pifoman vous voyez l'endroit où est stocké le nom et le code entrés.Il sont sous la clé HKEY_CURRENT_USER\Software\PowerArchiverFR\General "Regname"="pifoman" Pour repasser en version d'évaluation effacez la clé Regnumber. -> Un conseil pour éviter le problème d'écriture sur fichier : désassemblez toujours une copie de l'exécutable à craquer et effectuez les modifications avec winhex dans l'exécutable d'origine (où l'inverse : c'est ce qu'on a fait). En effet w32dasm verrouille en écriture tout fichier ouvert dedans. -> Le désassemblage de POWERARC.EXE est très long : 9 minutes avec un pentium III 1Ghz et 640 Mo de mémoire vive. Donc allez faire vous faire chauffer un chocolat en attendant ! Dès que c'est fini faites "Disassembler -> Save Disassembly Text File and Create Project File". Vous obtenez alors 2 fichiers POWERARC.wpj (1.96 Mo) et POWERARC.alf (67 Mo). A quoi est-ce que ça sert me direz vous ? Eh bien si vous êtes amené à fermer w32dasm pour une raison quelquonque ; au lieu de passer 9 minutes à attendre la fin d'un nouveau désassemblage de POWERARC.EXE vous ne passerez qu'une seconde à désassembler le fichier POWERARC.EXE en faisant dans w32dasm Project -> open Project File -> POWERARC.EXE.
Dans ce cours vous apprenez à exploiter un message d'erreur donné lors de l'enregistrement du logiciel en fouillant dans les string data références du logiciel désassemblé.En remontant dans le code vous retrouvez ensuite l'endroit où se fait la comparaison du mauvais serial au vrai serial. Cette comparaison vous permet ensuite d'annuler un saut et ainsi de forcer l'enregistrement du logiciel. Malheureusement cette technique qui marche dans de nombreuses situations ne fonctionne pas ici.Le programme recopiant le mauvais serial dans la base de registre au lieu du bon.Pour contourner ce problème nous avons directement assemblé (en langage d'assemblage) une fonction qui recopie en mémoire le bon code par dessus celui entré.Cette technique assez complexe à mettre en oeuvre nous a permis de nous familiariser avec le langage d'assemblage, le calcul d'adressage et a été l'occasion pour nous d'introduire un nouveau concept : l'ajout d'une boîte de dialogue non existante dans le programme d'origine. Cette boîte demande à l'utilisateur de saisir un nom d'enregistrement supérieur ou égal à 2 caractères et un code supérieur ou égal à 8 caractères pour que notre patch opère la recopie.
Bonne matinée à tous. ![]()
|