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.