Intro:
Picaview est non seulement un petit programme bien sympathyque, mais il est aussi un très bon exemple pour commencer à voir de quelle manière peut-on faire croire à un prog qu'il est enregistrer en détournant des instructions d'assembleur ;)
Bien sur, pour bien comprendre ce tut, mieux vaux avoir quelques bases asm, mais de toute façon, j'expliquerais le plus simplement possible à quoi sert chaque instruction cible.
Ah oui, je vais vous expliquez ma demarche, alors si ça vous parait un peut bordelique, c'est un peut normal...
Présentation:
Pour cracké Picaview, vous aurez besoin de: Windasm 8.9, de Hiew 6.x et d'un cerveau asser bien reveillé ;)
Avant tout, demarrons le programme en lui faisant lire une image via le bouton de droite de la souris. On peut voir que c'est bien beau, sauf un "Enregistrer Picaview" qui gache tout le spectacle... Allons y pour voir ce qu'il s'y passe. Ok, il faut entrer un nom et un numéro de deblocage, jusque là, c'est classique. Maintenant entrer un truc bidon dans chaque cellules et cliquez sur Ok. Si le prog vous dis "Merci de vous être enregistrer" ou quelque chose du genre, vous avez une veine pas possible. Par contre, si il vous dis "Votre nom est votre code d'enregistrement ne correspondent pas.", alors c'est là que nous allons intervenir, héhé...
Nous avons fait le tour du code de deverouillage. Maintenant, allons voir dans l'option "A propos de Picaview..." pour voir aussi ce qu'il s'y passe. Houlala! Comme c'est moche, un "***COPIE D'EVALUATION NON ENREGISTREE ***" affiché en gros. Dans cette boîte de dialogue, il y à aussi trois options. Une pour s'enregistrer maintenant, une pour activer le rappel plus tard (pour fermer la boîte quoi), et une pour avoir plus d'info. Au milieu, un compteur vous indique le nombre d'utilisations faite, et le nombre de jours restants...
Bon, en tant que cracker, ou si vous avez déjà un peut cracké, on serait tenter de se dire qu'un simple saut conditionnel est present, et qu'il suffit de le mettre en inconditionnel pour faire gober au prog qu'il est enregistrer. Ok, je vous le dis tout de suite c'est le cas, mais cette fois-ci, il va falloir s'y prendre d'une façon differente et c'est ce que nous allons voir...
Launch!
Ici je vais utiliser la méthodes du dead-listing qui consiste à désassembler le programme pour avoir acces a ses instructions. Cette méthode n'est plus très en vogue ces dernier temps à causes des protections de désassemblage qui sont de plus en plus courentes mais elle constitue un bon départ pour les débutants. Ansi ils peuvent avoir une vue d'ensemble sur un programme pour analyser contrètement son fonctionnement. Assez le blabla, passont à des choses plus sérieuses.
Maintenant que nous avons vu le type de protection, allons dans le repertoire où à été installer Picaview. Quoi?! pas de fichier exe?! Pas de panique, si vous avez un minimum de connaissences dans le base de registre et en programmation windows, vous aurez deviner que Picaview fait parti integrante du systeme et qu'il est fort possible que sont contenue se trouve dans un fichier dll. donc, faite une copie de Picaveiw.dll et désassemblez la avec Windasm, comme ca vous n'aurez pas besoin de redesassembler le prog' à chaque fois que vous ferez une modif' ;)
[Interlude...]
J'ai reçus quelques mails à propos d'un problème d'affichage sous Windasm: les String data étaient illisibles car les charactères étants trop espacés. Pour remédier à ce problème, choisissez la fonte "Courrier" en taille 10.
[Fin de l'interlude....]
Une fois desassembler, cherchez le message d'erreur "Voter nom est votre code d'enregistrement ne correspondent pas.". Hm... il y en à au moin 10, de plus quand on regarde à la suite aucain Possible String Data de remerciement style "Merci de vous être enregistrer...." n'apparait. Bizzard tout ça, de plus, il serait trop bourrin et trop incertain de tous les modifiés. Cherchons un autre moyen...
Ouvrons une ptite bière, mettons nous à l'aise, et refléchissons...
Si l'on va dans l'Option "A propos...", on peut voir qu'un petit compteur y est present. Nous sommes alors en droit de nous dire que le prog va chercher la chaine de charactère correspondant au nombres d'utilisations dans la base de registre de windows. Donc, aller sous Windasm puis dans les Stringd Data. regardez un peut ce qu'il y à vers la fin. Là, on voit un jolie "Usage Count", ca peut être interressant, car justement, un compteur d'utilisation est present dans la boite d'enregistrement =)
Double-cliquez dessus pour voir où il se trouve. Recliquez encore une fois, et oui il y en à deux, alors lequel choisir? Choisisson le premier dans un premier temps car le deuxième comporte trop peut de sauts et d' appellettes de sous routine (je, jne, jz, jmp, call...) alors que le premeir en à pleins. Nous avons donc plus de chance de trouver le bon endroit.
:10011DB0 83EC0C sub esp, 0000000C :10011DB3 8D442400 lea eax, dword ptr [esp] :10011DB7 56 push esi :10011DB8 8BF1 mov esi, ecx :10011DBA 50 push eax :10011DBB 6819000200 push 00020019 :10011DC0 8B4E10 mov ecx, dword ptr [esi+10] :10011DC3 6A00 push 00000000 :10011DC5 51 push ecx :10011DC6 6802000080 push 80000002 * Reference To: ADVAPI32.RegOpenKeyExA, Ord:0172h | :10011DCB FF1508600910 Call dword ptr [10096008] :10011DD1 85C0 test eax, eax :10011DD3 7536 jne 10011E0B :10011DD5 8D542408 lea edx, dword ptr [esp+08] :10011DD9 8D86FC000000 lea eax, dword ptr [esi+000000FC] :10011DDF 52 push edx :10011DE0 8B542408 mov edx, dword ptr [esp+08] :10011DE4 8D4C2410 lea ecx, dword ptr [esp+10] :10011DE8 50 push eax :10011DE9 51 push ecx :10011DEA 6A00 push 00000000 * Possible StringData Ref from Data Obj ->"UsageCount" | :10011DEC 68B8AA0A10 push 100AAAB8 :10011DF1 52 push edx
Au dessus, on peut voir que Picaveiw ouvre bien à le base de registre windows pour afficher le compteur de nombres d'utilisations comme nous le montre le RegOpenKeyExA suivit de "UsageCount". On peut voir aussi un saut conditionnel, un jne 10011E0B. Executez ce saut en appuyant sur la touche Jump To. Vala, il atterit juste après le RegCloseKey et ne va pas pouvoir lire combien de fois nous avons executer le programme car il ne serat pas passer par RegQueryValue pour lire la chaîne de charactere correspondante. Par curiosité (mieux vaux être curieux quand on craque), remplaçons ce saut par un saut inconditionnel, qui quoiqu'il se passe, serat effectuer. Ouvrez donc le fichier Picaview.dll avec votre editeur héxa prefere, lancez une recherche sur 24088D4C2410 par exmple juste histoire de tomber juste à coté de ce saut. Ensuite, remplacez 7536 par EB36. Executez le prog', allez dans "A propos..." et là, on peux voir que le compteur à été mis à 1. Bon aller, maintenant que nous avons vu ce que nous voulions voir, on remet le 75 à la place du EB.
Conclusion, nous sommes peut être sur la bone voie, car les fenêtre d' "A propos..." affichent casiment toujours le nom de la personne enregistrée, et comme nous ne sommes pas enregistrés (pas encore ;), le prog passe surement par le même endroit car si l'on regarde un peut en haut et en bas de ce "UsageCount", le prog' sniff un peut trop la base de registre windows avec des RegOpenKey et autre... Mais peut être aussi que nous sommes sur la mauvaise voie. Nous allons voir ça ensemble...
Continuons donc notre petit chemin à travers le listing. Et reprenons le à partir de là où à sauter le jne 10011DD3, c'est à dire à la ligne 10011E0B. Là, on peut voir un je et un jne qui se suivent. Je ne vais pas trop entrer dans les details mais si l'on execute ses deux saut on remarque qu'il atterissent au même endroit.
* Referenced by a (U)nconditional or (C)onditional Jump at Address: |:10011DD3(C) | :10011E0B 8B8604010000 mov eax, dword ptr [esi+00000104] :10011E11 85C0 test eax, eax :10011E13 7417 je 10011E2C <= Ici :10011E15 8B4C2414 mov ecx, dword ptr [esp+14] :10011E19 51 push ecx :10011E1A 8BCE mov ecx, esi :10011E1C E8DF140000 call 10013300 :10011E21 85C0 test eax, eax :10011E23 7507 jne 10011E2C <= Et ici :10011E25 5E pop esi :10011E26 83C40C add esp, 0000000C :10011E29 C20400 ret 0004 * Referenced by a (U)nconditional or (C)onditional Jump at Addresses: |:10011E13(C), :10011E23(C) | :10011E2C 8BCE mov ecx, esi :10011E2E E84D180000 call 10013680 <= Joli ca call * Possible Reference to String Resource ID=00001: "Affiche les images." | :10011E33 B801000000 mov eax, 00000001 :10011E38 5E pop esi :10011E39 83C40C add esp, 0000000C :10011E3C C20400 ret 0004
Le premier "passe au dessus" d'un call, allons voir ce qu'il y à dedans... Bof ' pas terrible mais restons y et decendons un peut. Oh! Mais quue voit on? Une belle partie pleine d'acces à la base de registre windows et de jolies String Data tels que "Name" ou "SerialNumber". Interressant tout ça, mais comme nous ne sommes pas encore sur de l'endroit que nous devons modifier, nous allons en rester là et sortir de ce call en cliquant sur Ret.
Le deuxième saut quand à lui, ne saute que par dessus un pop esi comme instruction capable d'influencer le programme. Mais nous ne savons pas trop ce qu'il va influencer, alors pour l'instant on en reste là et on observe la suite du listing...
A la suite, on peut voir un Call 10013680. aller hop! On entre dedans par simple curiosité. Oh! Comme c'est étrange, regardez où l'on atteri!
* Referenced by a CALL at Address: |:10011E2E <= Le seul | :10013680 81EC20010000 sub esp, 00000120 :10013686 53 push ebx :10013687 56 push esi :10013688 8BF1 mov esi, ecx :1001368A 57 push edi :1001368B 8B464C mov eax, dword ptr [esi+4C] :1001368E 85C0 test eax, eax :10013690 0F8E66010000 jle 100137FC :10013696 8B4E10 mov ecx, dword ptr [esi+10] :10013699 8D442410 lea eax, dword ptr [esp+10] :1001369D 50 push eax :1001369E 6819000200 push 00020019 :100136A3 6A00 push 00000000 :100136A5 51 push ecx :100136A6 6802000080 push 80000002 * Reference To: ADVAPI32.RegOpenKeyExA, Ord:0172h | :100136AB FF1508600910 Call dword ptr [10096008] :100136B1 85C0 test eax, eax :100136B3 0F8543010000 jne 100137FC :100136B9 8A15283B0B10 mov dl, byte ptr [100B3B28] * Possible Reference to String Resource ID=00009: "A propos de PicaView" | :100136BF B909000000 mov ecx, 00000009 :100136C4 8D7C2439 lea edi, dword ptr [esp+39] :100136C8 88542438 mov byte ptr [esp+38], dl :100136CC F3 repz :100136CD AB stosd :100136CE 66AB stosw :100136D0 AA stosb
Vous avez vu? C'est peut être ce call que Picaview va appeller pour analiser le nom et le code d'enregistrement. Pourquoi? Tous simplement parceque comme nous l'indique Windasm, c'est le seul call qui appel cette partie du listing bien qu'il en ai plusieurs de même type. Nous allons voir pourquoi c'est cette partie qui pourrait nous interresser...
Si vous descendez verez un RegQueryValueExA qui va lire les chaines de charatecteres pour "Name" et "SerialNumber" afin de determiner si ces donées sont bonnes ou mauvaises. On peut voir aussi un peut plus bas un magnifique "Enregistrer Picaview....". Donc, rappellez vous bien, notre but est de faire croire au prog' qu'il est enregistrer, pas de lui faire dire que le mot de passe est bon.
La seule partie la plus interressente est le call 10013680 où nous etions . Revenons-y car comme on peut le constater, aucun saut conditionnel est présent. Un peut plus bas un jne 10011E6A est present, et comme c'est un court pour débutants, je ne vais pas trop entrer dans les details pour l'instant pour vous preciser la definition des instrutions pop qu'il saute et simplement vous dire qu'elles servent à vider differents registres de la pile :)
A la suite, on peut voir un call 10011E72, et comme d' abitude, allons voir ce qu'il cache. Bof', pas terrible...
Bon, maintenant sortons de ce call car ce n'est apparement pas l'endroit tant rechercher. On peut voir un jne 10011F20, en l'executant, on peut voir qu'il atteri à un endroit où si l'on regarde un peut plus bas, on remarque grâce aux String Data et autres qu' encore pas mal de processus de verification du mot de passe sont présent, mais apparement ce n'est que pour lire le code et le mot de passe et les fare condordés. Donc on s'en fou et on reviens sur le jne 10011F20. On voit un call 10013AD0 on entre dedans, et bof', ya pas grand chose de flagrant et aucun String Data n'est present pour prendre des points de repères. Un "Afficher les images." est présent, en ressortant de ce call, un peut voir que le même String est marquer en dessous, hm... interressant...
Ensuite, on peut voir au dessus et en dessous du même call 10013AD0 un jne 10011F20 et un je 10011EAD qui sautent au dessus de trois instructions pop (pop edi, pop esi, pop ebp). Et là, STOP!! Vous allez voir pourquoi.
Et oui, ceux (ou celles) qui connaissent l'astuce, auront remarqués pendant ce tout petit trajet que quelques lignes sont très importantes. Les voilà:
* Referenced by a CALL at Address: |:100063A9 | :10011DB0 83EC0C sub esp, 0000000C :10011DB3 8D442400 lea eax, dword ptr [esp] :10011DB7 56 push esi :10011DB8 8BF1 mov esi, ecx :10011DBA 50 push eax :10011DBB 6819000200 push 00020019 :10011DC0 8B4E10 mov ecx, dword ptr [esi+10] :10011DC3 6A00 push 00000000 :10011DC5 51 push ecx :10011DC6 6802000080 push 80000002 * Reference To: ADVAPI32.RegOpenKeyExA, Ord:0172h | :10011DCB FF1508600910 Call dword ptr [10096008] :10011DD1 85C0 test eax, eax :10011DD3 7536 jne 10011E0B <= Bien sympat :10011DD5 8D542408 lea edx, dword ptr [esp+08] :10011DD9 8D86FC000000 lea eax, dword ptr [esi+000000FC] :10011DDF 52 push edx :10011DE0 8B542408 mov edx, dword ptr [esp+08] :10011DE4 8D4C2410 lea ecx, dword ptr [esp+10] :10011DE8 50 push eax :10011DE9 51 push ecx :10011DEA 6A00 push 00000000 * Possible StringData Ref from Data Obj ->"UsageCount" <= Compteur du nombres d'utilisations | :10011DEC 68B8AA0A10 push 100AAAB8 :10011DF1 52 push edx
[....]
* Referenced by a CALL at Addresses: |:10012051 , :10012E41 | :10011E40 83EC24 sub esp, 00000024 :10011E43 53 push ebx :10011E44 55 push ebp :10011E45 56 push esi :10011E46 8B742434 mov esi, dword ptr [esp+34] :10011E4A 57 push edi :10011E4B 8BF9 mov edi, ecx :10011E4D 56 push esi :10011E4E 897C2414 mov dword ptr [esp+14], edi :10011E52 E8391C0000 call 10013A90 :10011E57 83C404 add esp, 00000004 :10011E5A 85C0 test eax, eax :10011E5C 750C jne 10011E6A <= C'est très beau ca! * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:10011EB4(C) | :10011E5E 5F pop edi :10011E5F 5E pop esi :10011E60 5D pop ebp :10011E61 33C0 xor eax, eax :10011E63 5B pop ebx :10011E64 83C424 add esp, 00000024 :10011E67 C20C00 ret 000C
Dans ces passages, ont peut voir que l'instruction push est justement utiliser pour les registres edi, esi et ebp qui vont servir à mettre une valeur en mémoire pour être manipulés par la suite (nom d'enregistrement, code, ...). Et si vous avez bien tout suivi, vous comprendrez mieux que les pop edi, pop esi et pop ebp sur lequel nous sommes atteris sont important puisque même si le prog vois un code faux dans la base de registre, il va le considérrer comme bon. Pourquoi? Car une fois les registres de test vidés (à part eax qui dois toujours être là puisqu'il joue le rôle d'un accumulateur), le prog va sauter par dessus la procedure qui gere les parametres de non enregitrement. De cette façon, Picaview va empreinter la bonne voie pour qu'il soit enregistrer en permanence.
Bon, en gros c'est ca pour pas trop entrer dans les details. Si vous avez mal compris ce passage, relisez-le bien, il est très important.
Alors certains diront "Ok, mais il y avait deja tous ces pop juste en dessous du jne 10011EAD.". Je leurs dirais que je suis tout a fait d'accord, mais si l'on fait en sorte de remplacer ces saut pour qu'ils ne soient jamais effectuer (750F par 7500 ou 9090 et 0F859A000000 par 0F8500000000 ou 909090909090) et que les pop soient pris en compte, Window$ va afficher un beau message d'erreur sur l'état de la pile de registre, puisque les registres auronts deja étés vider. Ils vont alors se vider une fois de plus, mais vider quoi??? Picaview va donc planter en beauter au lieu d'afficher le message de rappel d'enregistrement...
Et c'est là que nous allons voir comment résoudre ce probème en utilisant l'ultime outil pour modifier un programme en asm...
Hiew !
Alors nous, tout ce que l'on veux c'est faire gober au prog' qu'il est enregistrer, et pour mieux suivre, je vous mets la partie du listing la plus importante :
* Referenced by a CALL at Addresses: |:10012051 , :10012E41 | :10011E40 83EC24 sub esp, 00000024 :10011E43 53 push ebx :10011E44 55 push ebp :10011E45 56 push esi :10011E46 8B742434 mov esi, dword ptr [esp+34] :10011E4A 57 push edi :10011E4B 8BF9 mov edi, ecx :10011E4D 56 push esi :10011E4E 897C2414 mov dword ptr [esp+14], edi :10011E52 E8391C0000 call 10013A90 :10011E57 83C404 add esp, 00000004 :10011E5A 85C0 test eax, eax :10011E5C 750C jne 10011E6A <= LE saut * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:10011EB4(C) | :10011E5E 5F pop edi :10011E5F 5E pop esi :10011E60 5D pop ebp :10011E61 33C0 xor eax, eax :10011E63 5B pop ebx :10011E64 83C424 add esp, 00000024 :10011E67 C20C00 ret 000C * Referenced by a (U)nconditional or (C)onditional Jump at Address: |:10011E5C(C) | :10011E6A 8D442414 lea eax, dword ptr [esp+14] * Possible Reference to String Resource ID=00001: "Affiche les images." | :10011E6E 6A01 push 00000001 :10011E70 50 push eax :10011E71 56 push esi :10011E72 E8591F0000 call 10013DD0 :10011E77 8B4720 mov eax, dword ptr [edi+20] :10011E7A 83C40C add esp, 0000000C :10011E7D 80382D cmp byte ptr [eax], 2D :10011E80 0F859A000000 jne 10011F20 :10011E86 8B4C2440 mov ecx, dword ptr [esp+40] :10011E8A 8B5C243C mov ebx, dword ptr [esp+3C] :10011E8E 51 push ecx :10011E8F 53 push ebx :10011E90 56 push esi :10011E91 50 push eax :10011E92 E8391C0000 call 10013AD0 :10011E97 83C410 add esp, 00000010 :10011E9A 85C0 test eax, eax :10011E9C 740F je 10011EAD :10011E9E 5F pop edi <= La cible :10011E9F 5E pop esi < :10011EA0 5D pop ebp < * Possible Reference to String Resource ID=00001: "Affiche les images." | :10011EA1 B801000000 mov eax, 00000001 :10011EA6 5B pop ebx :10011EA7 83C424 add esp, 00000024 :10011EAA C20C00 ret 000C
Donc, nous voulons que le prog passe par ces pop histoire de le carotte un max ;) Là, deux solutions s'offrent à nous:
1/ Celle du cracker limite bourrin qui va nopper le jne et le je, c'est à dire remplacer avec son editeur héxadécimal, le 0F859A000000 par des 909090909090 et le 740F par des 9090. Pas très jolie tout ca...Et en plus comme nous l'avons vu plus haut, ca fait planter le prog.
2/ Celle du cracker qui connais asser bien ce type de protection pour faire gober ce qu'il veux au prog'. De plus, il ne faudra alors modifier que deux octets, et au lieu de 8 sois quatre fois moin, ca l' fait non?
Perso, je prefere la deuxième solution qui est bien plus classe. Pour ce faire, on regarde un peut plus haut dans le listing histoire de chercher un ptit saut inconditionnel ou non bien placé de façon à le bidouiller pour qu'il parte directement sur les pop (dans le prochain numero, nous verons comment faire pour fabriquer son propre saut =).
On monte donc un peut dans le listing, et là on vois le beau jne 10011E6A (750C) qui ne se trouve pas bien loingt, et qui pourrait bien sauter toute cette marmaille pour atterir directement aux fameux pop edi, pop esi et pop ebp signalés sur le listing ci-dessus. Mais comment faire?
C'est là que vous avez besoin d'executer Hiew et d'ouvrir le fichier Picaview.dll avec F9 puis d'appuyer deux fois sur Entrée pour voir le listing asm. Maintenant lancez avec F7 une recherche en héxadécimal sur le E8391C0000 correspondant au call 10013DD0 qui se trouve juste à coté du jne 10011E6A (750C). Une fois dessus, appuyer sur F3, puis sur F2 pour pouvoir faire les modifications asm, et là, remplacer jne 10011E6A par jmps 10011E9E (EB40) car cette longueure de saut va nous faire atterrir à l'endroit où tous les pop se trouvent, à partir de l'adresse 10011E9E. De cette manière, le prog serat toujours enregistrer puisque de cette façon, on saute par dessus la gestion de non-enregistrement bien proprement en se servant d'une faille du programme =)
Voilà, j'espere avoir été le plus clair possible pour ce tutorial. J'aurai bien voulu detailler plus, mais ca n'aurai fait que compliquer les choses :p
Aller, amusez vous bien!
NB: Si vous voulez mettre votre nom dans la cellulue d'enregistrement, ouvrez ce fichier reg avec Notepad, changer le nom puis enregistrer. Enfin, executez-le et répondez oui à la question ;)
_-_-_-_-_-_-_-_-_-_-_-_-_-_-tEChNO pHr3aCKs-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_
La pile: C'est un tableau de type LIFO (Last In First Out). Le registre de segment SS (Statck Segment) pointe sur le début de la pile tandis que le registre SP (Stack Pointe) indique le position du dernier élément placé sur cette pile. L'ordinateur à besoin de cette pile à chaque fois qu'une rupture se produit dans un programme (appel de sous routine, interruption, ...). Il sauve l' addresse avec laquelle il doit continuer le programme une fois cette rupture terminé. Voici un exemple très simplifié en assembleur 32bits :
.data ; Indique la zone de données txt db "Partagez votre savoir.",0 ; Ici le label txt "attend" ; d'être dans la pile .code ; Indique la zone de code push offset txt ; Ici on pousse txt dans la pile call MessageBoxA ; On appel la procedure d'affichage ; d'une boite de dialogue. ; La phrase de txt y serat afficher.
Les registres: Se sont des emplacement de mémoire situés à l'interieur du micropprocesseur. Ils sont au nombre de 14 et on peut les répartir en 4 catégories: - Les registres de segment (CS, DS, SS, ES) - Les regsitres de travail (AX, BX, CX, CX) - Les registrs d'offset (SI, DI, IP, BP, SP) - Le regsitre FLAG (indicateurs: CF, PF, AF, ZF, SF, OF) Mais comme nous sommes en 32 bits, alors par exemple: BP deviendra EBP et ainsi de suite..
-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-