SUJET |
Crack
d'ANIMAGIC GIF v 1.22a |
TYPE DE PROTECTION |
Time Limit (30 jours) avec Boite d'enregistrement (Nom,
Serial). |
OUTILS UTILISES |
Wdasm93, Hiew 6.16 |
Ce
tutorial s’adresse principalement au newbies car la protection ici est un le
type meme de la protection de base.
1/ MUMUSE AVEC LE PROG
La premiere chose à faire avant
tout est de lancer le prog et de toucher un peu a tout afin de relever des
points succeptibles de nous aider. C'est parti !!On lance le prog et PAf un nag Screen : "You
have used this evaluation version for 1 days. Certain feature will expire after
30 days." On le note.
On clique sur continue, on vas faire un tour dans le menu Help / About Et
ki c'est ke revoilou, la meme fenetre qu'au demmarage, rien de plus.
Un peu en dessous dans le menu on voit , Register now,
Register form et Enter name and password, Et si on allait entrer un
nom et un password au pif ?
avec un peu de chance (beaucoup) ca peux marcher...... Eh bin NON ca marche pas
(si jamais ca marche , appellez de suite votre copine ....) Mais une
jolie MessageBox apparait et nous dit trés fierement : "Registration
failed: Invalid Password" mmm, tres interressant.
Voila sinon toutes les autres fonction ont l'air de marcher, on ferme le prog.
J'ai pris une assez bonne
habitude (je trouve) qui consiste a regardé vite fait ce que nous disent les
auteurs à propos de l’enregistrement, on y decouvre souvent
quelles sont les limitations
cela nous evite ainsi de chercher et peux déjà nous faire une idée sur le type
de protection.
2/ DESASSEMBLAGE
A l’aide de Wdasm on desassemble
le prog et on va jeter un œil aux Datas Strings References, on voit pas mal references
tres interressantes et entre
Autres "Registration
failed: Invalid Password" : LE message que nous balancait la MessageBox.
On double-click dessus et wdasm nous envoi directement à l'adresse
referée par cette chaine de charactere. Par reflexe je double-click une seconde
fois afin de voir si il n'a pas d'autres references pour cette chaine mais
Je n’en trouve qu’une seule et
elle se situe ici :
* Referenced by a (U)nconditional
or (C)onditional Jump at Address:
|:00422A4F(C) ß---------------------------------------------------------------------------------------------- Adresse du jump qui envoi ici
|
:00422AC1 8B06 mov
eax, dword ptr [esi]
:00422AC3 6A00 push 00000000
:00422AC5 6A00 push
00000000
* Possible StringData Ref from
Data Obj ->"Registration failed: Invalid Password" ß------ Notre
Message
|
:00422AC7 687F954700 push
0047957F
:00422ACC FF700C push [eax+0C]
:00422ACF FF7068 push [eax+68]
:00422AD2 E887080300 call
0045335E
:00422AD7 83C414 add esp, 00000014
:00422ADA 84DB test bl, bl
:00422ADC 7420 je 00422AFE
:00422ADE 56 push esi
:00422ADF 8DB514FDFFFF lea
esi, dword ptr [ebp+FFFFFD14]
:00422AE5 BFF54E4800 mov
edi, 00484EF5
:00422AEA B984000000 mov
ecx, 00000084
:00422AEF F3 repz
:00422AF0 A5 movsd
:00422AF1 5E pop esi
:00422AF2 56 push esi
:00422AF3 E807C8FFFF call
0041F2FF
:00422AF8 59 pop ecx
:00422AF9 A205514800 mov
byte ptr [00485105], al
On remonte legerement le listing
a partir de "Registration failed: Invalid Password" , et on
voit que cette procedure est appele par un saut : « * Referenced by a
(U)nconditional or (C)onditional Jump at Address : 0422A4F « , Bon on va allez voir
ca de plus près, On fait un GoTo code location a l’adresse noté :
:00422A1B 68F54E4800 push
00484EF5
:00422A20 E861FEFFFF call
00422886
:00422A25 59 pop ecx
:00422A26 68F54F4800 push
00484FF5
:00422A2B E856FEFFFF call
00422886
:00422A30 59 pop ecx
:00422A31 68F5504800 push
004850F5
:00422A36 E84BFEFFFF call
00422886
:00422A3B 59 pop
ecx
:00422A3C 56 push esi
:00422A3D E8BDC8FFFF call 0041F2FF ß-----------------------------------Appelle
la routine de verif du name / serial
:00422A42 59 pop
ecx
:00422A43 A205514800 mov byte
ptr [00485105], al ß------------------met dans une
adresse memoire , une valeur contenue dans AI
:00422A48 803D0551480000 cmp byte ptr
[00485105], 00 ß------------------Compare si le
contenu de l’adresse memoire = 0
:00422A4F 7470 je
00422AC1 ß-----------------------(On
arrive ici), saute si la valeur
contenue dans l’adresse memoire est differente de AI
:00422A51 C6050851480000 mov
byte ptr [00485108], 00 et nous envoie vers
« Registration failed «
:00422A58 68944D4800 push
00484D94
:00422A5D 68F54E4800 push
00484EF5
Petit rappel:
En programmation, la valeur
de retour d'une fonction est placé dans le registre EAX, en assembleur une
fonction est appelé par un Call.
Que Fait le prog ici:
Il fait un call vers une
routine qui semble etre une fonction qui va verifier notre nom et le serial que
nous avons entré.
En retour de ce call eax contiendra une valeur differente selon que notre
serial est valide ou pas.
Et on peux voir ici que AI
est testé pour une comparaison (ce qui confirme que EAX a été initialisé en
retour de ce call)
Ensuite il place le contenu
dans AI à l’adresse memoire [00485105] qui designe ici l’adresse d’une variable qui va servir
à etre testé pour controler notre authentification, exactement comme le fait
le cmp byte ptr [00485105], 00
Ensuite il y a un saut
conditionnel qui se branche sur PAS BON si 00485105 = 0
Donc si on à bien compris , 00485105 = 0 -> NOT
REGISTERED et si 00485105 <> 0 -> REGISTERED
La on a plusieurs solutions, on
pourrait nopper ce saut pour ne jamais y aller, ou alors inverser le saut
conditionnel afin que si notre serial est bidon le prog ne nous envoi pas dans
la routine « invalid Password « , Ce qu’on va faire :
On remplace donc a l’adresse
:00422A4F le 74 par 75 , on save sous
un autre nom le prog afin de garder intact l’original (c mieux si jamais y
avait un probleme ou alors pour generer des patchs une fois le crack realisé) ,
et pis on va tester ,
On s’enregistre et cool
le prog nous dit « thanks for
register …… » on va faire un tour dans about
mais la le prog nous ressort qu’on utilise la version demo et que certaines
fonctions seront desactivées apres la periode d’essai de 30 jours L
Cela veut dire que le prog teste
a d’autres endroit la validité de notre serial, On va effectuer une recherche
sur l’adresse memoire dont s’est servi le prog pour effectuer le test que nous
avons trouvé, Wdasm nous retourne 21 adresses ou est elle est réferencée dont
17 qui sont des operations de comparaisons (CMP)
et 4 ou se sont des
operations d’initialisation (MOV). Ce qui est interressant c’est les MOV car se
sont les endroit l’adresse memoire sera
modifiée et si on peux y mettre la bonne valeur alors tout les tests de
comparaison seront valides pis ca evite de modifié 17 sauts ce ki serait un peu
chiant a faire…
Voici la routine retourné pour
la recherche de 00485105
:0041F173 53 push
ebx
:0041F174 E886010000 call
0041F2FF ß---------------------------------call la procedure de verification
:0041F179 59 pop
ecx
:0041F17A A205514800
mov byte ptr [00485105], al
ß-------------ICI Initialise notre variable avec AI
:0041F17F 53 push ebx
:0041F180 E807030000 call 0041F48C
:0041F185 59 pop ecx
:0041F186 A30C514800 mov dword ptr [0048510C], eax
:0041F18B 803D0551480000
cmp byte ptr [00485105], 00
ß-------------- Si notre variable est differente de 0
:0041F192 7509
jne 0041F19D ß-----------------------------
Saute vers Registered
:0041F194 833D0C5148001E
cmp dword ptr
[0048510C], 0000001E ß--- Tient une comparaison avec
1E = 30 en decimal
:0041F19B 7E04
jle 0041F1A1 ß----------------------------------
branchement si inferieur ou egal
Si on regarde bien on voit
que si notre variable contient 0
Le branchement ne se fera pas
(ce qui confirme notre premiere constatation) et que tout de suite apres le
prog va controler une autre variable avec 30 en decimal , ca ressemble fort au
contrôle du Time-Limit.
Mais si on arrivait à detourner
le test juste avant, le Time-Limit ne sera jamais controlé.
On voit aussi un call avant la
comparaison c’est le meme que celui que nous avons rencontrer la premiere fois.
Et toutes les autres references
qui contiennent mov byte ptr [00485105], al
sont toutes precedées par ce call, qui est en fait une fonction du
prog qui sert
à verifier notre pseudo et le
code que nous avons entré. Et a chaque fois c’est avec AL que notre variable
est comparé, cela signifie qu’en retour du Call,
AL contient 00 si notre pseudo
et pass ne sont pas valides.
On va meme pas ce prendre la
tete a analyser ce call, on va tout simplement à l’interieur de celui ci mettre
par nous meme le contenu de AL à 1 et zapper toute la suite en faisant un
retour prematuré , ainsi en retour du call notre variable sera elle aussi
initialisé avec 01 ce qui nous permettra de passer avec mention
tout les tests qui la compare a
00.
Attention ,à present il faut que
l’on re-inverse le saut que l’on avait modifié pour que celui ci ne nous
balance pas dans les choux.
3/ PATCHING
Mais comment écrire ca ?
Rien de plus simple….
On va se servir de Hiew qui
facilite beaucoup la tache pour ecrire en assembleur. (J’ai longtemps ignoré
cet outils a cause de son interface peu attrayante, mais j’ai fini par le
tester et maintenant je ne lache plus , il est tout simplement genial et
indispensable)
On va y aller doucement pour
ceux ki comme moi evitait ce prog :
- Bon bah on lance le prog deja
(logique)
- Ensuite on va dans le repertoire
ou se situe notre prog, (la souris ne fonctionne pas sous ce genre de prog , on
se sert des fleches du clavier et
on « clique » avec ENTER)
- F4 pour modifier l’affichage
puis on choisi Decode pour lire l’asm et l’hexa
- F5 pour GoTo puis on entre l’adresse precedé d’un point
(tres important) -> . 0041F2FF (adresse premiere instruction du call)
- On est pres a ecrire .
- Le curseur est placé à la
bonne adresse on fait F3 pour éditer
- On fait F2 pour passer en mode
Assembleur
- une fenetre apparaît et
affiche le code asm, On efface tout
- et on tape mov al,01 suivi de
ENTER
- la on voit que la modif a eu
lieu et ke le new code est devenu jaune.
- Hiew poite automatiquement sur
l’adresse suivante donc on a plus qu’à ajouter un RET pour quitter ce Call.
- nos modif terminé on fait
echap pour sortir du mode ASM et on
fait F9 pour Valider ces nouvelles
valeurs et sortir du mode EDIT
- Le prog a ete patché, on
Quitte avec F10
On Relance le prog ainsi
patché et nous voilà registered , on avance
notre horloge pour tester , no Probleme le prog ne bronche pas.
On test un peu tout pour voir si
on a rien oublié, voilà, y a juste un detail ki m’embete : ca a pas viré
du menu Register now etc …..
A ce niveau le soft est
fonctionnel à 100% mais on va
virer co-meme virer ces merdes du menu pour faire plus clean :
Dans Wdasm on cherche les
References Menu Items
Et on trouve ceux ki nous interressent on ,clique sur « register
form » et on arrive ici :
* Referenced by a (U)nconditional
or (C)onditional Jump at Address:
|:0041FB56(C) ß-----------------------------------------------------------------------------------------------
Adresse qui appelle cette routine
|
:0041FB87 803D0551480000 cmp byte ptr
[00485105], 00
:0041FB8E 746E je
0041FBFE
* Possible StringData Ref from
Data Obj ->"Distributor"
|
:0041FB90 6854934700 push 00479354
:0041FB95 68F54E4800 push 00484EF5
* Reference To:
KERNEL32.lstrcmpA, Ord:0000h
|
:0041FB9A E8FE070500 Call 0047039D
:0041FB9F 85C0 test eax, eax
:0041FBA1 755B jne 0041FBFE
:0041FBA3 66C78510FFFFFF0800 mov word ptr [ebp+FFFFFF10], 0008
:0041FBAC 6A00 push
00000000
:0041FBAE 8B13 mov edx, dword ptr [ebx]
:0041FBB0 8B4A14 mov ecx, dword ptr [edx+14]
:0041FBB3 FF710C push [ecx+0C]
:0041FBB6 8D45F4 lea eax, dword ptr [ebp-0C]
:0041FBB9 50 push eax
:0041FBBA E8C5970200 call
00449384
:0041FBBF 83C40C add esp, 0000000C
:0041FBC2 6A00 push 00000000
* Possible Ref to Menu: ANIMAGIC,
Item: "Register form"
|
* Possible Reference to String
Resource ID=00803: "Displays the registration form - can be sent by
fax"
|
:0041FBC4 6823030000 push 00000323 ß-------------------------------------- ON arrive la
:0041FBC9 FF75F8 push [ebp-08]
* Reference To: USER32.RemoveMenu, Ord:0000h ß-------------------------------------
Tres interressant une API pour effacé des elements dans un menu
|
:0041FBCC E8540A0500 Call
00470625
:0041FBD1 85C0 test eax, eax
:0041FBD3 0F95C2 setne dl
:0041FBD6 83E201 and edx,
00000001
:0041FBD9 6A00 push 00000000
* Possible Ref to Menu: ANIMAGIC,
Item: "Register now"
<------------------------------- 2 eme Item a virer
|
* Possible Reference to String
Resource ID=00805: "Starts your internet browser, goes to the download and
onlin"
|
:0041FBDB 6825030000 push 00000325
:0041FBE0 FF75F8 push [ebp-08]
* Reference To: USER32.RemoveMenu, Ord:0000h ß-------------------------------------------
Meme chose , lui aussi il va passer a
la casserole
On regarde a Quelle adresse est
appellé cette routine , on on va voir ca de plus pres :
:0041FAE0 55
push ebp
:0041FAE1 8BEC
mov ebp, esp
:0041FAE3 81C4F4FDFFFF add
esp, FFFFFDF4
:0041FAE9 53
push ebx
:0041FAEA 56
push esi
:0041FAEB 57
push edi
:0041FAEC 8B5D08
mov ebx, dword ptr
[ebp+08]
:0041FAEF B8C1754700
mov eax, 004775C1
:0041FAF4 E8DF740400
call 00466FD8
:0041FAF9 803DA075470000
cmp byte ptr [004775A0], 00
:0041FB00 0F8449020000
je 0041FD4F
:0041FB06 C605A075470000
mov byte ptr [004775A0], 00
:0041FB0D 803DF44E480000
cmp byte ptr [00484EF4], 00
:0041FB14 7411 je 0041FB27 ß-----------------------------
Saute vers la routine qui efface les items du menu
Bah on va tout simplement forcer
le saut en remplacant :
7411 par EB11
(je) par (jmp)
Et voilà , plus de ces vilain
Items.
Notes :
- On aurait pu rechercher dans
les Imports pour trouver les references au RemoveMenu, qui nous auraient mener
au meme endroit.