Pour ce cours, on va cette fois utiliser OllyDBG, qui est un Débuggeur / Désassembleur beaucoup plus complet que W32Dasm.
Je ne vais ( Hélas ;-) pas faire d'introduction à OllyDBG étant donné qu'il en existe beaucoup de très bonnes sur le net.
En voici par exemple un très bon fait par Crisanar, merci à lui :
Ceci étant fait, commençons ! Désassemblons Hexa.exe avec OllyDBG. Une fois le programme désassemblé
lancez-le avec F9 et essayez de vous enregistré avec un nom de 10 caractères ou plus
( C'est la raison des "..." à l'avant et à la fin de "Krom" ) :
Comme d'habitude, on note le message d'erreur pour retrouver l'endroit du code qui nous intéresse :
"Sorry, but the name and the key you entered cannot be accepted together.
A mistake often made when entering the name and the key is to confuse the letters O and l with the digits 0 and 1."
L'intérêt de noter le message d'erreur est de trouver la routine de vérification du sérial qui se trouve toujours avant le message d'erreur,
( logique non :)
( Eh voici mon traditionnel "Schéma de Vérification du Sérial" :) :
Alors pour chercher un message d'erreur sous OllyDBG, faites un clic droit puis "Search for" ->> "All referenced text strings"
Dans cette nouvelle fenêtre, montez tout en haut sur la ligne 00401002 ASCII "Boolean" et clique droit, "Search for text" ->> "Sorry"
( Ce "Sorry" que nous recherchons et bien sur celui de "Sorry, but the name and the key you entered cannot be accepted together". )
En décochant la "case sensitive" si ce n'est pas déjà fait.
Vous trouverez plusieurs occurrences en 00435BD0, 0043637D et en 00436698 mais c'est celle en 004358AA qui nous intéresse :
Double cliquer sur cette ligne et vous aller arriver à l'endroit où est affiché le message d'erreur :
Si vous remontez un peu plus haut, vous verrez alors que le JE SHORT HexDecCh.00435890 à l'adresse 0043585C saute par-dessus
le bon message pour afficher le message d'erreur après vérification du code. Vous voyez aussi que le fait de sauter ou non
est dû au TEST AL,AL à l'adresse 0043585A qui est lui aussi dû au CALL HexDecCh.00431B48 à l'adresse 00435855.
Redémarrer le programme avec CTRL + F2 et posez un breakpoint à l'adresse 00435855 en faisant CTRL + G ->> 00435855 ->> F2 ( BreakPoint ),
puis lancez le programme avec F9. Une fois le programme lancé, enregistrez-vous avec un nom de 10 caractères ou plus et un code bidon
( ...Krom... / 123456 ).
Le programme s'arrête au CALL HexDecCh.00431B48 à l'adresse 00435855. Entrer dans ce call avec F7 et parcourez-le ligne par lignes avec F8.
Rappelez-vous que pour que le programme soit enregistré, il faut avoir AL Différent de 0 sinon le "JE" ( Jump if Egual to 0 )
->> Saute vers le message d'erreur si le code entré n'est pas le bon. En faisant vos F8, vous allez sauter jusqu'au XOR EAX,EAX en 00431D17
à cause du JNZ HexDecCh.00431D17 et du JL HexDecCh.00431D17 en 00431BEF. La fonction XOR EAX,EAX à pour but de mettre EAX à 0
ce qui n'est pas bon pour nous car notre AL doit être différent de 0. Ressortez du CALL et vous verrez que AL est à 0 à cause du XOR EAX,EAX
en 00431D17.
...
...
Il faut donc annuler les 2 sauts qui mènent en 00431D17 pour éviter de mettre EAX ( Donc AL ) à 0.
Voici donc une petite marcha à suivre pour continuer :
Le programme affiche le message d'erreur si le code entré est différent du bon. On peut voir ca avec les 3 lignes :
0043585C |. 74 32 JE SHORT HexDecCh.00435890 ; " JE "
On peut donc comprendre que EAX ( AL ) contient le Sérial entré.
Et grâce au CMP ESI,EAX en 00431BDC ( juste avant les 2 Sauts JNZ HexDecCh.00431D17 et du JL HexDecCh.00431D17 )
on comprend que ESI contient le Vrai Sérial :)
En comparant le Vrai Sérial et le Sérial que l'on a entré, le programme saute soit en 00431D17 pour mettre EAX à 0
( donc code faux ) soit il ne saute pas et on aura EAX différent de 0 donc code Juste :)
Il ne reste alors plus qu'a aller voir se que cache le registre ESI en 00431BDC.
Pour ça, relancez une session avec CTRL + F2 ->> "Oui". Lancez ensuite le programme avec F9 et enregistrez-vous avec un nom de plus de
10 caractères ( ...Krom... / 123456 ) et cliquez sur "Ok". Le programme Break en :
F7 pour entrer dans le CALL puis une série de F8 jusqu'a arriver en 00431BDC juste avant les 2 Sauts.
Regardez bien les registres en dessous et leurs contenus :
On sait que EAX contient notre sérial entré donc 123456 mais que contient ESI ?
ESI à la valeur 2AA43 ( Les valeurs des registres sont en Hexadécimal ), pour la convertir en décimal faites
"Démarrer ->> exécuter ->> "Calc.exe". Choisissez l'affichage scientifique dans "Affichage" ->> Scientifique.
Cocher la Case "Hex" et mettez-y notre 2AA43.
Cliquez ensuite sur la case "Déc" et notre sérial apparaitra en décimal.
Registre :
Valeur Hexadécimale :
Valeur Décimale :
EAX
0001E240
123456
ESI
0002AA43
174659
Voici donc notre Sérial :) ->> 174659
Deuxième partie, pourquoi 10 caractères minimum ?
Nous avons toujours fait nos tests de Sérials avec un nom de 10 caractères ou plus, on va voir quels sont les conséquences si on en a moins.
Pour faire ces tests, nous avons besoin de remettre le programme en version d'évaluation, pour faire cela, aller dans "Démarrer" ->> "Exécuter..." ->> regedit
Allez ensuite dans "HKEY_LOCAL_MACHINE" puis "SOFTWARE", "Beyersdorf" et enfin "
".
Pour sauvegarder votre enregistrement, cliquez sur le dossier puis "Exporter..."
Enregistrez le en tant que "Hexa.reg" et vous n'aurez qu'a double cliquez dessus pour refaire l'enregistrement.
les information d'enregistrement étant sauvegardées, supprimer les 2 Clés "Name" et "Key"
Ceci étant fait, relancer une session de débugging avec CTRL + F2 ->> "Oui" et démarrer-le avec F9.
Enregistrez-vous avec un nom de moins de 10 caractères et un code au hasard.
Entrer dans le CALL avec F7 et descendez avec F8 jusqu'a arrivé en :
00431BDC . 3BF0 CMP ESI,EAX
Registre :
Valeur Hexadécimale :
Valeur Décimale :
EAX
0001E240
1234
ESI
0000062A
1578
Vous voyez ici que le code pour "Krom" serait 1578. Redémarrons OllyDBG avec CTRL + F2 ->> "Oui". Lancez le avec F9 et enregistrez-vous
avec Krom / 1578. Entrez dans le CALL 00435855 avec F7 et descendez avec F8 jusqu'au CMP ESI,EAX en 00435855. Un F8 de plus et vous arrivez
à notre premier saut. Le JNZ ne saute pas puisque le résultat du CMP donne 0 ( Pas de différences 62A = 62A :).
Arrivé un peu plus loin, vous voyez que le fait de sauter ou non dépend du résultat du CMP EAX,0A en 00431BEC qui lui aussi dépend
du résultat du CALL HexDecCh.00403594 à l'adresse 00431BE7. Entrez dans ce CALL avec F7 puis on verra ceci :
On voit que en 00403598 on a un MOV EAX,DWORD PTR DS:[EAX-4], cela veut dire mettre le contenue de [EAX-4] dans EAX,
pour que le deuxième saut ne saute pas, on devrais avoir une valeur supérieur à 0A dans EAX. Aller dans la fenêtre de Dump
( Celle en bas a Gauche ), faites ensuite CTRL + G puis noter la valeur de EAX ( 00283DD0 ( la valeur EAX peut varier suivant le nom entré )).
Vous voyez que EAX contient "Krom" sous forme Hexadécimale à l'adresse mémoire 00283DD0 ( 4B 72 6F 6D ). Ca c'est pour la valeur EAX,
mais nous c'est la valeur EAX-4 qui nous intéresse car c'est cette valeur qui est mise dans EAX. Regardez alors qu'a l'adresse 00283DCC
( [EAX-4] ) on a la Valeur 4, c'est le nombre de caractère du nom entré ( Krom = 4 caractères ). Cette valeur sera mise dans EAX et
comparée à 0A, la comparaison indiquera un résultat inférieur et le JL sautera pour remettre EAX à 0, donc mauvais enregistrement.
Petite parenthèse, Jl veut dire Jump if Less donc saute si inférieur, donc pour que le Jl ne saute pas, on devra avoir un nom entré
égal ou supérieur à 0A ( donc 10 en décimal ).
Réessayons de nous enregistrer avec cette fois un nom de 10 caractères ou plus et le bon code ( ...Krom... / 174659 ). Pour cela,
redémarrez le programme avec CTRL + F2, ->> "Oui", puis F9.
Entrez dans le CALL 00435855 avec F7 et descendez avec F8 jusqu'au CMP ESI,EAX en 00435855.
Un F8 de plus et vous arrivez a notre premier saut. Le JNZ ne saute pas puisque le résultat du CMP donne 0 ( Pas de différences 2AA43 = 2AA43 ).
Arrivé un peu plus loin, vous voyez que le fait de sauter ou pas dépend du résultat du CMP EAX,0A en 00431BEC qui lui aussi dépend
du résultat du CALL HexDecCh.00403594 à l'adresse 00431BE7. Entrez dans ce CALL avec F7.
On voit que en 00403598 on a un MOV EAX,DWORD PTR DS:[EAX-4], cela veut dire mettre le contenue de [EAX-4] dans EAX,
pour que le deuxième saut ne saute pas on devrais avoir une valeur égal ou supérieur à 0A dans EAX.
Allez dans la fenêtre de Dump ( Celle en bas a Gauche ), faites ensuite CTRL + G puis noter la valeur de EAX
( 00283C00 ( la valeur EAX peut varier suivant le nom entré )).
Vous voyez que EAX contient "...Krom..." sous forme Hexadécimale à l'adresse mémoire 00283C00 ( 2E 2E 2E 4B 72 6F 6D 2E 2E 2E ).
Ca c'est pour la valeur EAX, mais nous c'est la valeur EAX-4 qui nous intéresse car c'est cette valeur qui est mise dans EAX.
Regardez alors qu'a l'adresse 00283BFC ( EAX-4 ) on a la Valeur 0A. Cette valeur sera mise dans EAX et comparée à 0A,
Le JL ne sautera pas car il ne saute uniquement si la valeur entré est inférieur ( Jump if Less ) et en remettra pas EAX à 0,
donc bon enregistrement :).
En résumé :
Le premier Saut ( JNZ HexDecCh.00431D17 ) a pour but de contrôler la validité du Sérial.
Le deuxième Saut ( JL HexDecCh.00431D17 ) a pour but de contrôler si le nombre de caractères minimum est respecté.