1) un peu de théorie
Nous allons partir à la péche au sérial. Dans le cours précédent, nous
avons identifié
la routine de verification du sérial. Dans ce tutorial, je montrerais une
autre méthode
pour arriver au même endroit.
On va utiliser les fonctions de l'API pour windows. Quand un programme
veut afficher
une boite de message, il utilise par exemple la fonction MessageBoxA. Pour
récupérer les données
entrées au clavier par l'utilisateur et pour connaitre le nb de caractère
entrées, le programme
utilise la fonction GetDlgItemTextA. Cette fonction demande des paramétres
pour savoir dans
l'ordre, quel est le nb maximum de caractères à recuperer, ou mettre le texte
récupéré, l'identifiant du
controle, la handle de la fenetre. Le programme va transférer ces
paramétres par la pile.
A la fin, la fonction retourne dans le registre EAX le nb de
caractères saisis et stocke le texte a l'adresse indiquée.
Voila comment cette fonction se présente:
push 29 ......................................--> le nb maximum de caractères en hexadecimal (soit 41 en décimal)
push 4d81e0...............................--> adresse ou elle va mettre le texte
push 0c80...................................--> identifiant du controle
push 880....................................--> handle de la fenetre ou se trouve le controle
Call dword ptr DS: [<&USER32.getdlgitemtexta].....--> appel de la fonction getdlgitemtexta
si on saisi comme nom loloko, la fonction met loloko à l'adresse 4d81e0 et
eax est égal au nb
de caractères saisis c'est à dire 6. Pour recupérer le sérial, la fonction
getdlgitemtexta doit
être appelée à nouveau
On va donc mettre un breakpoint sur cette fonction. De cette façon, on
arrivera avant la routine
qui calcule le bon sérial en fonction du nom, et compare le sérial qu'on a
entré avec le bon sérial.
2) la pratique
Pour mettre un breakpoint sur une fonction, cliquez sur le menu View puis
sur Executable modules.
Selectionnez le programme winzip, clic droit et selectionnez view names.
Vous obtenez une liste des
fonctions (si les fonctions ne sont pas triées par ordre alphabétique,
clic droit et sort by names)
Faites un clic droit sur la fonction getdlgitemtexta et selectionnez "set
breakpoint on every références".
pressez F9, Winzip apparait avec le nagscreen et cliquez sur "Enter
registration code", rentrez loloko
comme nom et comme serial 123456. Ollydbg break sur le premier
GetDlgItemTextA, remontez 3 lignes
plus
haut et vous voyez sur la partie droite que le nom a été
mis dans un buffer qui correspond a l'adresse
4E6574, et eax est
à 6 dans les registres (soit le
nb de caractères du nom loloko). Rappuyer sur F9.
On arrive en
40DD19 sur le deuxième getdlgitemtexta. Le serial est mis dans
un buffer qui correspond
à l'adresse 4E65A0 et eax est
à 6 (le nb de caracteres du serial)
appuyez sur F8 jusqu'a ce qu'on soit à l'adresse 40DD3F. La, ou
retrouve le call de verification du sérial
du tut
précedent. si al=0 à la fin du call, le serial est faux, si al =1 le serial est valide.
Si on rentre dans cette routine avec F7, on pourra sans doute voir à un
moment donné le bon serial dans
les registres ou dans la pile. Appuyer sur F7 pour rentrer dans le
CALL, puis sur F8 pour tracer en regardant
les
registres. A la ligne 40DAFE, vous pouvez voir le serial pour la premiere fois dans la pile.
.
Remarque1: pour loloko, le bon serial est
C460066B, mais il y a aussi un autre sérial valide que l'on peut
voir dans les registres 50272164. Pour un
nom, il y a donc deux serials possibles.
Remarque2: si vous voulez savoir
ou winzip
stocke vos informations d'enregistrement (nom et serial) mettez
un
breakpoint sur la fonction RegSetValueExA --> le nom est d'abord
stocké dans la base de registre, puis
le serial number. Pour
acceder à vos informations d'enregistrement, clic sur l'icone demarrer de Windows, allez
dans
executer et tapez regedit (vous vous trouvez alors dans la base de registre)
Dans
HKEY_Current_User\Software\Nico Mak Computing\Winzip\WinIni et dans
HKEY_LOCAL_MACHINE\Software\Nico Mak
Computing\Winzip\WinIni vous retrouvez votre nom et serial
De la
même
façon, Pour un utilisateur non enregistré, on a
la date d'installation, la derniere date d'utilisation et le
nb de
jours d'utilisation
dans: HKEY_Current_User\Software\Nico Mak Computing\Winzip\rrs
.
3) faire un selfkeygen avec la message box
On va se compliquer un peu la tache. Ce qu'on veut, c'est modifier Winzip
pour que dans la procédure
d'enregistrement, au lieu de nous dire que le code est est incorrect quand
on saisi n'importe quoi,
il nous donne le bon sérial. Quand le serial est mauvais le programme
saute en 40D361. On va expliquer
un peu ce qui se passe alors:
le programme execute d'abord un sous programme (call 40D624) puis il
transmet comme paramétre l'index
de la data string "Incomplete or incorect information" (le push 28Edu
tutorial 3). Il execute ensuite un
sous programme (call 46FE95) qui recupere l'adresse de la
string data et la met dans eax.
C'est un troisieme call ( le call 45B054) qui va afficher le message d'erreur.
Pour afficher la boite de dialogue, le call 45AFDD a besoin ici de 4
arguments: l'index de la string, le texte à afficher,
un deuxième argument, un troisième argument --> on se rend compte que le prog veut 4 arguments et pas
3 comme affiché quand on regarde la pile juste avant l'execution du call.
Ce qu'on va faire, c'est simplement changer l'adresse du texte a
afficher.
A la ligne 40DAFE on avait regardé
la pile, et on avait notre serial valide
"C460066B".
Par contre il y a un problème, winzip efface le contenu du vrai sérial à
la fin de la routine de verification.
Il faut donc se debrouiller pour stocker ce serial dans une adresse
memoire vide avant que winzip l'efface.
A la ligne 40DAFE ou on
voit le serial, on va rediriger le code vers un bout de code a nous qui
va se charger de
sauver le serial valide dans une adresse memoire sure.
Il nous faut donc une zonne vide pour ecrire notre bout de code
--> on choisi l'adresse 4C21A0 pour ecrire notre bout de code. Il
nous faut aussi une zonne memoire vide pour
stocker le serial valide --> on choisi l'adresse 4EDD00 pour stocker le serial
A la ligne 40DAFE (la ou on voit notre serial dans la pile pour la premiere fois), on a le bout de code suivant:
l'instruction d'aprés LEA EAX, DWORD [ebp-340] met l'adresse qui contient le serial dans eax.
on va remplacer le CALL par un JMP "notre code" (jmp 4C21A0)
A l'adresse 4C21A0, on ecrit notre bout de code pour stocker le serial valide en 4EDD00
C'est pas fini, il faut remplacer l'adresse qui pointe vers le
message "Incomplete or Incorret Information" par notre adresse
4EDD00
qui pointe vers le serial valide. On va ecraser le call 46FE95 et le
push eax pour mettre notre push 4EDD00:
Remarque: avec la modif ollydbg se rend bien compte qu'il y a 4 arguments (clic droit , analysis, analysis code)