Cours de Crack #2  - par Frog's Print - Juillet 1997
-SUJET
   : -Introduction au Cracking -2e Partie-            -Désassembler un fichier pour le craquer            -Exemple de schéma de protection classique.            -EXEMPLE : AX-Album v2.0 Win 95 (et TOUS les autres softs d'Axialis) -OUTILS  : W32Dasm85, une cervelle et deux gouttes de SoftIce 3.01


1/ INTRODUCTION 2/ EXECUTION DU CRACK / EXEMPLE DE PROTECTION FREQUENTE 3/ CONCLUSION



1/ INTRODUCTION Ce deuxième cours va vous présenter (et craquer :-) un type de protection que l'on retrouve dans tous les programmes d'Axialis. Si j'ai choisi cet exemple c'est tout simplement parceque ce schéma de protection est, et de loin, un des plus ridicules que j'ai craqué. Son intérêt réside dans le fait que les petits Crackers que vous êtes peut-être passeront de longues heures a le décortiquer pour finalement réussir a le craquer (mal) alors que quelques minutes suffisent pour ça ET pour bien comprendre l'INUTILITE d'une telle protection (et c'est ça le plus important: comprendre pour apprendre :-). Les programmes d'Axialis sont des monstruosités (de 1Mo à 2Mo) mal écrites et dont l'intérêt reste a prouver (s'il l'est un jour :-). De plus, ayant une antipathie plus que profonde pour le Minitel, ces "TelWares" m'offrent une excellente occasion pour m'acharner sur eux. Merci beaucoup Axialis! 2/ EXECUTION DU CRACK Nous allons prendre pour exemple AX-Album v2.0 Win95 (axalbm32.exe, 1.361,408 Ko). Comme je vous l'ai dit plus haut cet exemple s'applique à tous les programmes d'Axialis. Vous trouverez ce programme sur de nombreux CD-Rom et à: http://www.axialis.fr (si vous allez sur le site d'Axialis, soyez patient car il est aussi lent et désespérant que leurs programmes :-). Tout d'abord on lance AX-Album pour voir ce qui se passe. Un panneau nous demande le mot de passe et notre nom. On tape n'importe quoi et on obtient le message:  "Le numéro de série que vous avez saisi est incorrect...." On recommence mais cette fois on n'entre pas de mot de passe ni de nom:  "Vous devez impérativement saisir un nom d'utilisateur...." On note ces messages, les différentes boites de dialogues ou nagscreens bref toutes les infos nécessaires pour commencer le crack (comme je vous l'ai déjà expliqué dans mon cours #1). Et puis maintenant on désassemble AX-Album avec W32Dasm85 (ou une autre version de W32Dasm :=). Comme d'habitude, on appuie sur le boutton 'String Datas References' pour essayer de retrouver les chaines de caractères, les titres ou messages que nous avons noté. On les trouvent sans problèmes dans la liste que nous donne W32Dasm. Cliquez sur 'Le numéro de série que vous avez saisi est incorrect' et vous atterrissez à l'adresse '00434EBF': * Possible Reference to String Resource ID=55055: "Le numéro de série que vous avez                                                     saisi est incorrect. Veuill" :00434EBF 680FD70000              push 0000D70F :00434EC4 8D8D68FCFFFF            lea ecx, [ebp+FFFFFC68] :00434ECA E85F9C0500              call 0048EB2E :00434ECF 6A10                    push 00000010 :00434ED1 6A00                    push 00000000 :00434ED3 8D8D68FCFFFF            lea ecx, [ebp+FFFFFC68] :00434ED9 E8BEC5FCFF              call 0040149C :00434EDE 50                      push eax :00434EDF 8B4DA4                  mov ecx, [ebp-5C] :00434EE2 E8DC350600              call 004984C3 * Possible Reference to String Resource ID=55091: "Version TELWARE                                                     non débloquée." :00434EE7 6833D70000              push 0000D733 :00434EEC B9585F4B00              mov ecx, 004B5F58 :00434EF1 E8389C0500              call 0048EB2E :00434EF6 C705845E4B0001000000    mov dword ptr [004B5E84], 00000001       ;< **ICI!** :00434F00 C645FC06                mov [ebp-04], 06 :00434F04 E8B4010000              call 004350BD :00434F09 C645FC01                mov [ebp-04], 01 :00434F0D E8C3010000              call 004350D5 :00434F12 C645FC00                mov [ebp-04], 00 :00434F16 E8F6010000              call 00435111 :00434F1B C745FCFFFFFFFF          mov [ebp-04], FFFFFFFF :00434F22 E8F3010000              call 0043511A :00434F27 E901020000              jmp 0043512D :00434F2C E988000000              jmp 00434FB9                            ;< Le programme saute                                                                           ; jusqu'a la fin de                                                                           ; la procédure si le                                                                           ; code est mauvais. * Referenced by a (U)nconditional or (C)onditional Jump at Address:       ;< sinon: :00434EAA(C) :00434F31 8D8D5CFCFFFF            lea ecx, [ebp+FFFFFC5C] :00434F37 E8F27E0500              call 0048CE2E :00434F3C C645FC09                mov [ebp-04], 09 * Possible Reference to String Resource ID=55090: "Le numéro de série est correct !                                                    Vous disposez maintenant d" :00434F40 6832D70000              push 0000D732 :00434F45 8D8D5CFCFFFF            lea ecx, [ebp+FFFFFC5C] :00434F4B E8DE9B0500              call 0048EB2E :00434F50 6A40                    push 00000040 :00434F52 6A00                    push 00000000 :00434F54 8D8D5CFCFFFF            lea ecx, [ebp+FFFFFC5C] :00434F5A E83DC5FCFF              call 0040149C :00434F5F 50                      push eax :00434F60 8B4DA4                  mov ecx, [ebp-5C] :00434F63 E85B350600              call 004984C3 :00434F68 8D4DA8                  lea ecx, [ebp-58] :00434F6B E82CC5FCFF              call 0040149C :00434F70 50                      push eax * Possible StringData Ref from Data Obj ->"Nom" :00434F71 6884D84C00              push 004CD884 * Possible StringData Ref from Data Obj ->"licence" :00434F76 6888D84C00              push 004CD888 :00434F7B E894CAFCFF              call 00401A14 :00434F80 8BC8                    mov ecx, eax :00434F82 E833700600              call 0049BFBA :00434F87 8D4DB4                  lea ecx, [ebp-4C] :00434F8A E80DC5FCFF              call 0040149C :00434F8F 50                      push eax * Possible StringData Ref from Data Obj ->"SerieWIN32" :00434F90 6890D84C00              push 004CD890 * Possible StringData Ref from Data Obj ->"licence" :00434F95 689CD84C00              push 004CD89C :00434F9A E875CAFCFF              call 00401A14 :00434F9F 8BC8                    mov ecx, eax :00434FA1 E814700600              call 0049BFBA :00434FA6 C705845E4B0000000000    mov dword ptr [004B5E84], 00000000          ;< **ICI!** :00434FB0 C645FC06                mov [ebp-04], 06 :00434FB4 E8F8000000              call 004350B1 .... .... .... .... Tout est là! Vous vous souvenez de mon crack de ComSpeed? Ici, c'est identique (et classique). Exemple de protection classique Voici comment fonctionnent 90% des schémas de protections: Le programme va définir tout au début une valeur booléenne vrai/faux (True/False) qui sera stockée dans une zone de mémoire appelée 'pointeur' (Pointer), représenté par un octet (byte), un mot (word) ou double-mot (dword) du type:  - mov | byte   ptr [(registre +) adresse], Valeur_Booléenne        | word        | dword Ici dans AX-Album nous avons:    - mov dword ptr [004B5E84], | 00000000                              | 00000001 En règle générale, la valeur '0' sera souvent utilisée pour 'Vrai' et '1' pour 'Faux' (c'est le compilateur qui décidera de cela au dépens du programmeur:-) mais il peut y avoir des exceptions (InfoSpy...). Lorsque le programme voudra savoir s'il est 'Enregistré' ou non, il n'aura qu'a faire une comparaison du type:  - cmp | byte   ptr [(registre +) adresse], Valeur_Booléenne_VRAI        | word        | dword Cette expression est toujours suivie d'un saut conditionnel (jne, jnz, je, jz...). Voici un petit exemple: (* Au départ, le programme se définit    comme 'Non Enregistré'                       *)     Mov dword ptr[reg+adr],00000001 (* Il lit dans le fichier *.ini si 'Enregistré' *)     Call Verifie_Si_Enregistre (* Vérifie si 'Vrai'                            *)     Cmp dword ptr[reg+adr],00000000 (* Si 'Enregistré' :                            *)     je Début_Du_Programme (* Si 'Non Enregistré':                         *)     Call NagScreen                                                        ...... Note: Si le programme se définit tout d'abord comme 'Non-Enregistré', c'est tout simplement parcequ'une valeur boléenne est toujours initialisée comme étant fausse (FALSE) au début du progamme.
Pour craquer le plus facilement du monde ce type de protection, il suffit de remplacer le

'Mov dword ptr[reg+adr],00000001' par 'Mov dword ptr[reg+adr],00000000'.



Et AX-Album dans tout ça?

Et bien, les crétins qui l'ont programmé ne sont même pas arrivés a écrire un schéma de

protection aussi simple que cet exemple, ils ont fait pire!



Voici donc la routine qui vérifie si AX-Album est enregistré ou non, et vérifie si le mot de

passe entré au clavier est correct et vous envoie les différents NagScreens. 

Cette routine commence à l'offset :00434C2D et se termine à :004350B0 (nous en avons déjà vu

une petite partie plus haut). Je vous ai ajouté les commentaires à droite du listing (que 

vous pourrez vérifier en la traçant avec SoftIce 3.01) et nous verrons juste après 

son inutilité dont je vous ai parlé au début de ce cours:






























* Referenced by a (U)nconditional or (C)onditional Jump at Address: |:00402414(U) :00434C2D 55                      push ebp                          ; < Début de la routine :00434C2E 8BEC                    mov ebp, esp :00434C30 6AFF                    push FFFFFFFF :00434C32 6823514300              push 00435123 :00434C37 64A100000000            mov eax, fs:[00000000] :00434C3D 50                      push eax :00434C3E 64892500000000          mov fs:[00000000], esp :00434C45 81ECBC030000            sub esp, 000003BC :00434C4B 53                      push ebx :00434C4C 56                      push esi :00434C4D 57                      push edi :00434C4E E8C1CDFCFF              call 00401A14 :00434C53 8B401C                  mov eax, [eax+1C] :00434C56 8945A4                  mov [ebp-5C], eax :00434C59 8D4DA8                  lea ecx, [ebp-58] :00434C5C E8CD810500              call 0048CE2E :00434C61 C745FC00000000          mov [ebp-04], 00000000 :00434C68 8D4DB4                  lea ecx, [ebp-4C] :00434C6B E8BE810500              call 0048CE2E :00434C70 C645FC01                mov [ebp-04], 01 :00434C74 C705845E4B0001000000    mov dword ptr [004B5E84], 00000001  ; < Pointeur initialisé :00434C7E 684CD84C00              push 004CD84C                       ; < sur 'FALSE' au départ (* Le Programme initialise les données qu'il va rechercher: le numéro de série *) (* et le Nom de l'utilisateur                                                  *)
* Possible StringData Ref from Data Obj ->"Nom"

:00434C83 6850D84C00              push 004CD850



* Possible StringData Ref from Data Obj ->"licence"

:00434C88 6854D84C00              push 004CD854

:00434C8D 8D8544FCFFFF            lea eax, [ebp+FFFFFC44]

:00434C93 50                      push eax

:00434C94 E87BCDFCFF              call 00401A14

:00434C99 8BC8                    mov ecx, eax

:00434C9B E84C3B0700              call 004A87EC

:00434CA0 C645FC02                mov [ebp-04], 02

:00434CA4 50                      push eax

:00434CA5 8D4DA8                  lea ecx, [ebp-58]

:00434CA8 E861830500              call 0048D00E

:00434CAD C645FC01                mov [ebp-04], 01

:00434CB1 E84F040000              call 00435105

:00434CB6 685CD84C00              push 004CD85C



* Possible StringData Ref from Data Obj ->"SerieWIN32"

:00434CBB 6860D84C00              push 004CD860



* Possible StringData Ref from Data Obj ->"licence"

:00434CC0 686CD84C00              push 004CD86C

:00434CC5 8D8538FCFFFF            lea eax, [ebp+FFFFFC38]

:00434CCB 50                      push eax

:00434CCC E843CDFCFF              call 00401A14

:00434CD1 8BC8                    mov ecx, eax

:00434CD3 E8143B0700              call 004A87EC

:00434CD8 C645FC03                mov [ebp-04], 03

:00434CDC 50                      push eax

:00434CDD 8D4DB4                  lea ecx, [ebp-4C]

:00434CE0 E829830500              call 0048D00E

:00434CE5 C645FC01                mov [ebp-04], 01

:00434CE9 E80B040000              call 004350F9

:00434CEE 8D4DB4                  lea ecx, [ebp-4C]

:00434CF1 E8A6C7FCFF              call 0040149C

:00434CF6 50                      push eax

:00434CF7 8D45C0                  lea eax, [ebp-40]

:00434CFA 50                      push eax

:00434CFB E868220400              call 00476F68

:00434D00 83C408                  add esp, 00000008

:00434D03 6874D84C00              push 004CD874

:00434D08 8D45A8                  lea eax, [ebp-58]

:00434D0B 50                      push eax

:00434D0C E8F9D1FCFF              call 00401F0A          ; < Regarde s'il y a un mot de passe et

                                                         ; < le Nom de l'utilisateur

                                                         ; < dans le fichier *.INI

:00434D11 85C0                    test eax, eax          ; < Oui/Non??

:00434D13 0F8514000000            jne 00434D2D           ; < Si 'Non', appeler 1er NagScreen

:00434D19 8D45C0                  lea eax, [ebp-40]      ; < Si 'Oui', continue...

:00434D1C 50                      push eax

:00434D1D E8D8CDFCFF              call 00401AFA          ; < Création du mot de Passe en fonction

                                                         ; < du Nom de l'utilisateur trouvé.

:00434D22 83C404                  add esp, 00000004

:00434D25 85C0                    test eax, eax          ; < Vérifie le Mot de passe du fichier

                                                         ; < *.INI avec le vrai

:00434D27 0F8516030000            jne 00435043           ; < Si OK, on sort de la routine...



* Referenced by a (U)nconditional or (C)onditional Jump at Address:

|:00434D13(C)

:00434D2D 837D0800                cmp [ebp+08], 00000000 ; < Sinon appel du 1er NagScreen.

:00434D31 0F843A000000            je 00434D71

:00434D37 6A00                    push 00000000

:00434D39 8D8D14FDFFFF            lea ecx, [ebp+FFFFFD14]

:00434D3F E87AD7FCFF              call 004024BE

:00434D44 C645FC04                mov [ebp-04], 04

:00434D48 68785E4B00              push 004B5E78

:00434D4D 8D8DA8FDFFFF            lea ecx, [ebp+FFFFFDA8]

:00434D53 E8B6820500              call 0048D00E

:00434D58 8D8D14FDFFFF            lea ecx, [ebp+FFFFFD14]

:00434D5E E8FD430500              call 00489160

:00434D63 C645FC01                mov [ebp-04], 01

:00434D67 E881030000              call 004350ED

:00434D6C E925000000              jmp 00434D96



* Referenced by a (U)nconditional or (C)onditional Jump at Address:

|:00434D31(C)

:00434D71 6A00                    push 00000000

:00434D73 8D8D80FCFFFF            lea ecx, [ebp+FFFFFC80]

:00434D79 E809D2FCFF              call 00401F87

:00434D7E C645FC05                mov [ebp-04], 05

:00434D82 8D8D80FCFFFF            lea ecx, [ebp+FFFFFC80]

:00434D88 E8D3430500              call 00489160            ; < 1er NagScreen

:00434D8D C645FC01                mov [ebp-04], 01

:00434D91 E84B030000              call 004350E1



* Referenced by a (U)nconditional or (C)onditional Jump at Address:

|:00434D6C(U)

:00434D96 6A00                    push 00000000

:00434D98 8D8DB8FDFFFF            lea ecx, [ebp+FFFFFDB8]

:00434D9E E833D3FCFF              call 004020D6

:00434DA3 C645FC06                mov [ebp-04], 06



* Referenced by a (U)nconditional or (C)onditional Jump at Address:

|:00434E6C(U)

:00434DA7 8D8DB8FDFFFF            lea ecx, [ebp+FFFFFDB8]

:00434DAD E8AE430500              call 00489160              ; < 2ème NagScreen 'Entrez votre

                                                             ; < Mot de passe'...

:00434DB2 8985B4FDFFFF            mov [ebp+FFFFFDB4], eax

:00434DB8 8D458C                  lea eax, [ebp-74]

:00434DBB 50                      push eax

:00434DBC 8D4DA8                  lea ecx, [ebp-58]

:00434DBF E84A820500              call 0048D00E

:00434DC4 8D4598                  lea eax, [ebp-68]

:00434DC7 50                      push eax

:00434DC8 8D4DB4                  lea ecx, [ebp-4C]

:00434DCB E83E820500              call 0048D00E

:00434DD0 83BDB4FDFFFF01          cmp dword ptr [ebp+FFFFFDB4], 00000001

:00434DD7 0F8423000000            je 00434E00

:00434DDD C645FC01                mov [ebp-04], 01

:00434DE1 E8EF020000              call 004350D5

:00434DE6 C645FC00                mov [ebp-04], 00

:00434DEA E822030000              call 00435111

:00434DEF C745FCFFFFFFFF          mov [ebp-04], FFFFFFFF

:00434DF6 E81F030000              call 0043511A

:00434DFB E92D030000              jmp 0043512D



* Referenced by a (U)nconditional or (C)onditional Jump at Address:

|:00434DD7(C)

:00434E00 6878D84C00              push 004CD878

:00434E05 8D45B4                  lea eax, [ebp-4C]

:00434E08 50                      push eax

:00434E09 E8D8C2FCFF              call 004010E6

:00434E0E 85C0                    test eax, eax           ; < Vérifie si un Numéro de Série

                                                          ; < a été entré par l'utilisateur

:00434E10 0F845B000000            je 00434E71             ; < Jmp si 'Non'...

:00434E16 687CD84C00              push 004CD87C           ; < ...continue si 'Oui'.

:00434E1B 8D45A8                  lea eax, [ebp-58]

:00434E1E 50                      push eax

:00434E1F E8E6D0FCFF              call 00401F0A

:00434E24 85C0                    test eax, eax           ; < Vérifie si le Nom de l'Utilisateur

                                                          ; < a été entré au clavier

:00434E26 0F8445000000            je 00434E71             ; < Si 'Oui', jmp 00434E71...

:00434E2C 8D8D74FCFFFF            lea ecx, [ebp+FFFFFC74] ; < Si 'Non', on continue...

:00434E32 E8F77F0500              call 0048CE2E           ; < ...

:00434E37 C645FC07                mov [ebp-04], 07        ; < ... et on le signal:



* Possible Reference to String Resource ID=55056: "Vous devez impérativement saisir un nom 

                                                   d'utilisateur. Veuil"

:00434E3B 6810D70000              push 0000D710

:00434E40 8D8D74FCFFFF            lea ecx, [ebp+FFFFFC74]

:00434E46 E8E39C0500              call 0048EB2E

:00434E4B 6A10                    push 00000010

:00434E4D 6A00                    push 00000000

:00434E4F 8D8D74FCFFFF            lea ecx, [ebp+FFFFFC74]

:00434E55 E842C6FCFF              call 0040149C

:00434E5A 50                      push eax

:00434E5B 8B4DA4                  mov ecx, [ebp-5C]

:00434E5E E860360600              call 004984C3

:00434E63 C645FC06                mov [ebp-04], 06

:00434E67 E85D020000              call 004350C9

:00434E6C E936FFFFFF              jmp 00434DA7             ; Bye-bye...



* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:

|:00434E10(C), :00434E26(C)

:00434E71 6880D84C00              push 004CD880

:00434E76 8D45B4                  lea eax, [ebp-4C]

:00434E79 50                      push eax

:00434E7A E867C2FCFF              call 004010E6

:00434E7F 85C0                    test eax, eax

:00434E81 0F8437010000            je 00434FBE

:00434E87 8D4DB4                  lea ecx, [ebp-4C]

:00434E8A E80DC6FCFF              call 0040149C

:00434E8F 50                      push eax

:00434E90 8D45C0                  lea eax, [ebp-40]

:00434E93 50                      push eax

:00434E94 E8CF200400              call 00476F68

:00434E99 83C408                  add esp, 00000008

:00434E9C 8D45C0                  lea eax, [ebp-40]

:00434E9F 50                      push eax               ; < No de Série entré par l'utilisateur

:00434EA0 E855CCFCFF              call 00401AFA          ; < Création du 'Vrai' No de Série

:00434EA5 83C404                  add esp, 00000004

:00434EA8 85C0                    test eax, eax          ; < Comparaison des 2 :

:00434EAA 0F8581000000            jne 00434F31           ; < Jmp si 'OK'...

:00434EB0 8D8D68FCFFFF            lea ecx, [ebp+FFFFFC68]; < ...sinon on continue...

:00434EB6 E8737F0500              call 0048CE2E          ; < ...

:00434EBB C645FC08                mov [ebp-04], 08       ; < ...et on le signal:



* Possible Reference to String Resource ID=55055: "Le numéro de série que vous avez saisi 

                                                   est incorrect."

:00434EBF 680FD70000              push 0000D70F

:00434EC4 8D8D68FCFFFF            lea ecx, [ebp+FFFFFC68]

:00434ECA E85F9C0500              call 0048EB2E

:00434ECF 6A10                    push 00000010

:00434ED1 6A00                    push 00000000

:00434ED3 8D8D68FCFFFF            lea ecx, [ebp+FFFFFC68]

:00434ED9 E8BEC5FCFF              call 0040149C

:00434EDE 50                      push eax

:00434EDF 8B4DA4                  mov ecx, [ebp-5C]

:00434EE2 E8DC350600              call 004984C3



* Possible Reference to String Resource ID=55091: "Version TELWARE non débloquée."

:00434EE7 6833D70000              push 0000D733

:00434EEC B9585F4B00              mov ecx, 004B5F58

:00434EF1 E8389C0500              call 0048EB2E

:00434EF6 C705845E4B0001000000    mov dword ptr [004B5E84], 00000001 ; < 'Non-Enregistré'

:00434F00 C645FC06                mov [ebp-04], 06

:00434F04 E8B4010000              call 004350BD

:00434F09 C645FC01                mov [ebp-04], 01

:00434F0D E8C3010000              call 004350D5

:00434F12 C645FC00                mov [ebp-04], 00

:00434F16 E8F6010000              call 00435111

:00434F1B C745FCFFFFFFFF          mov [ebp-04], FFFFFFFF

:00434F22 E8F3010000              call 0043511A

:00434F27 E901020000              jmp 0043512D

:00434F2C E988000000              jmp 00434FB9                      ; < Bye-Bye...



* Referenced by a (U)nconditional or (C)onditional Jump at Address:

|:00434EAA(C)



:00434F31 8D8D5CFCFFFF            lea ecx, [ebp+FFFFFC5C]

:00434F37 E8F27E0500              call 0048CE2E

:00434F3C C645FC09                mov [ebp-04], 09



* Possible Reference to String Resource ID=55090: "Le numéro de série est correct !

                                                   Vous disposez maintenant d"

:00434F40 6832D70000              push 0000D732

:00434F45 8D8D5CFCFFFF            lea ecx, [ebp+FFFFFC5C]

:00434F4B E8DE9B0500              call 0048EB2E

:00434F50 6A40                    push 00000040

:00434F52 6A00                    push 00000000

:00434F54 8D8D5CFCFFFF            lea ecx, [ebp+FFFFFC5C]

:00434F5A E83DC5FCFF              call 0040149C

:00434F5F 50                      push eax

:00434F60 8B4DA4                  mov ecx, [ebp-5C]

:00434F63 E85B350600              call 004984C3

:00434F68 8D4DA8                  lea ecx, [ebp-58]

:00434F6B E82CC5FCFF              call 0040149C

:00434F70 50                      push eax
(* Le programme va écrire les infos sur l'enregistrement dans le fichier *.INI...etc *)
* Possible StringData Ref from Data Obj ->"Nom"

:00434F71 6884D84C00              push 004CD884

* Possible StringData Ref from Data Obj ->"licence"

:00434F76 6888D84C00              push 004CD888

:00434F7B E894CAFCFF              call 00401A14

:00434F80 8BC8                    mov ecx, eax

:00434F82 E833700600              call 0049BFBA

:00434F87 8D4DB4                  lea ecx, [ebp-4C]

:00434F8A E80DC5FCFF              call 0040149C

:00434F8F 50                      push eax                            ; < No de Série



* Possible StringData Ref from Data Obj ->"SerieWIN32"

:00434F90 6890D84C00              push 004CD890

* Possible StringData Ref from Data Obj ->"licence"

:00434F95 689CD84C00              push 004CD89C

:00434F9A E875CAFCFF              call 00401A14

:00434F9F 8BC8                    mov ecx, eax

:00434FA1 E814700600              call 0049BFBA

:00434FA6 C705845E4B0000000000    mov dword ptr [004B5E84], 00000000 ; < 'Enregistré'

:00434FB0 C645FC06                mov [ebp-04], 06

:00434FB4 E8F8000000              call 004350B1



* Referenced by a (U)nconditional or (C)onditional Jump at Address:

|:00434F2C(U)

:00434FB9 E97C000000              jmp 0043503A           ; < On sort de la routine, "Merci

                                                         ; < gentil utilisateur d'avoir

                                                         ; < enregistré ce programme

                                                         ; < de merde".
(* Pour ceux qui auraient oublié d'entrer un No de Série, Axialis a aussi pensé a eux: *)
* Referenced by a (U)nconditional or (C)onditional Jump at Address:

|:00434E81(C)

:00434FBE 8D8D50FCFFFF            lea ecx, [ebp+FFFFFC50]

:00434FC4 E8657E0500              call 0048CE2E

:00434FC9 C645FC0A                mov [ebp-04], 0A

* Possible Reference to String Resource ID=55089: "Aucun numéro de série saisi.

                                                   Vous disposez toujours d'une ve"

:00434FCD 6831D70000              push 0000D731

:00434FD2 8D8D50FCFFFF            lea ecx, [ebp+FFFFFC50]

:00434FD8 E8519B0500              call 0048EB2E

:00434FDD 6A40                    push 00000040

:00434FDF 6A00                    push 00000000

:00434FE1 8D8D50FCFFFF            lea ecx, [ebp+FFFFFC50]

:00434FE7 E8B0C4FCFF              call 0040149C

:00434FEC 50                      push eax

:00434FED 8B4DA4                  mov ecx, [ebp-5C]

:00434FF0 E8CE340600              call 004984C3



* Possible Reference to String Resource ID=55091: "Version TELWARE non débloquée."

:00434FF5 6833D70000              push 0000D733

:00434FFA B9585F4B00              mov ecx, 004B5F58

:00434FFF E82A9B0500              call 0048EB2E

:00435004 C705845E4B0001000000    mov dword ptr [004B5E84], 00000001  ;< 'NON-Enregistré'

:0043500E C645FC06                mov [ebp-04], 06

:00435012 E88E000000              call 004350A5

:00435017 C645FC01                mov [ebp-04], 01

:0043501B E8B5000000              call 004350D5

:00435020 C645FC00                mov [ebp-04], 00

:00435024 E8E8000000              call 00435111

:00435029 C745FCFFFFFFFF          mov [ebp-04], FFFFFFFF

:00435030 E8E5000000              call 0043511A

:00435035 E9F3000000              jmp 0043512D                        ;< Bye-bye Méchant_Garçon

 

* Referenced by a (U)nconditional or (C)onditional Jump at Address:

|:00434FB9(U)

:0043503A C645FC01                mov [ebp-04], 01

:0043503E E892000000              call 004350D5



* Referenced by a (U)nconditional or (C)onditional Jump at Address:

|:00434D27(C)

:00435043 C645C600                mov [ebp-3A], 00

:00435047 8D45A8                  lea eax, [ebp-58]

:0043504A 50                      push eax

:0043504B B9585F4B00              mov ecx, 004B5F58

:00435050 E8B97F0500              call 0048D00E



* Possible StringData Ref from Data Obj ->" ("

:00435055 68A4D84C00              push 004CD8A4

:0043505A B9585F4B00              mov ecx, 004B5F58

:0043505F E866830500              call 0048D3CA

:00435064 8D45C0                  lea eax, [ebp-40]

:00435067 50                      push eax

:00435068 B9585F4B00              mov ecx, 004B5F58

:0043506D E858830500              call 0048D3CA



* Possible StringData Ref from Data Obj ->")"

:00435072 68A8D84C00              push 004CD8A8

:00435077 B9585F4B00              mov ecx, 004B5F58

:0043507C E849830500              call 0048D3CA

:00435081 C705845E4B0000000000    mov dword ptr [004B5E84], 00000000  ;< 'Enregistré'

:0043508B C645FC00                mov [ebp-04], 00

:0043508F E87D000000              call 00435111

:00435094 C745FCFFFFFFFF          mov [ebp-04], FFFFFFFF

:0043509B E87A000000              call 0043511A

:004350A0 E988000000              jmp 0043512D



* Referenced by a CALL at Address:

|:00435012   

:004350A5 8D8D50FCFFFF            lea ecx, [ebp+FFFFFC50]



:004350AB E8067E0500              call 0048CEB6

:004350B0 C3                      ret                                ; < Fin de la routine






























Voila, vous venez de parcourir l'intégralité de cette routine. Et maintenant, comment craquer ça?
-On pourrait rechercher le mot de passe tout simplement?

Oui, il suffirait sous SoftIce de mettre un BPX 00434B06 puis de taper 'd [EBP-14]' pour

voir apparaitre le bon mot de passe mais ça on s'en tape pas mal puisqu'on est là pour

apprendre et comprendre les protections!!



-On pourrait peut-être craquer en tranformant quelques 'jnz' en 'jmp' ou 'jz' vers la routine

de vérification du mot de passe dans le fichier *INI?

Bof, pas terrible, patcher un 'jnz' précédé par un 'Test Eax,Eax' c'est de l'amateurisme.

A la rigueur si vraiment vous voulez craquer là, alors montrez que vous êtes un 'High Cracker'

et que l'Assembleur est votre langue natale:

Virez le 'Test Eax,Eax' et remplacez-le par un 'Xor Eax,Eax'(méthode la PLUS rapide pour

remettre un registre a zéro), ça fait plus Pro.
-On pourrait peut-être rechercher dans le programme le 'cmp dword ptr [004B5E84],00000000' qui

nous envoie sur cette routine si le résultat n'est pas bon?

Bof, on l'a déjà fait dans le premier cours, et puis on ne le trouverais pas ici (on touverais

un 'mov eax,[004B5E84]' par contre!).
Non, réfléchissez bien une minute à cette routine:
Elle est appellée dès que le programme commence:

-Elle vérifie s'il existe un fichier *.INI

-Elle vérifie s'il y a votre mot de passe à l'interieur de celui-ci

-Elle regarde si ce mot de passe est bon

-Si c'est le cas, elle décide que le programme est enregistré

-Si ce n'est pas le cas, elle vous envoie un NagScreen

-Elle vérifie le mot de passe entré au clavier

-S'il est bon, elle décide que le programme est enregistré

-S'il n'est pas bon, décide que le programme n'est pas enregistré



Elle est appellée lorsque vous voulez sauvegarder un fichier:

-Elle vérifie s'il existe un fichier *.INI

...

...

et recommence toute les mêmes vérifications....

...

...



On voit aussi qu'elle est TOUJOURS exécutée puisque c'est un Saut INCONDITIONNEL qui l'appel

(cf le début de la routine:-):

 * Referenced by a (U)nconditional or (C)onditional Jump at Address:

 |:00402414(U)
En fait on s'aperçoit tout simplement que, en dehors de cette routine, il n'y a aucune

autre vérification sur l'enregistrement de l'utilisateur.

Alors pourquoi ne pas la supprimer tout simplement? Et oui, on peut la patcher comme ça:
Nous avions:



:00434C2D 55        push ebp                     ; < Début de la routine

:00434C2E 8BEC      mov ebp, esp
On le change en:
:00434C2D C3        ret                          ; < Bonjour....et au-revoir!

:00434C2E 8BEC      mov ebp, esp
En craquant de cette manière, AX-Album ne rentrera JAMAIS dans cette routine et donc 

ne saura JAMAIS ce que signifient les mots 'Mot de Passe', 'Enregistré', 'Non-Enregistré' 

ou bien 'TelWare'!

Etonnant non? Je vous avais bien dit que cette protection était inutile.

En plus vous aurez gagné quelques précieuses secondes en évitant a votre programme de rentrer

dans cette routine pour y effectuer toute ces vérifications et calculs. Les programmes

d'Axialis sont suffisamment lents...
3/ CONCLUSION
Un programme d'1, 2 ou même 10Mo, connu ou non, n'a pas toujours forcément un schéma de

protection plus compliqué ou plus dur à trouver et/ou craquer qu'un simple utilitaire de

quelques Ko. Ne soyez jamais impressionné par ces facteurs! Les programmeurs comme ceux

de chez Axialis n'ont aucune connaissance de l'Assembleur, mais le Cracker, lui, si. Et

c'est bien là toute la différence. On peut écrire en pur Assembleur des programmes de 5 ou

10Ko avec une protection des plus dures a craquer, mais jusqu'a présent, jamais personne

n'a réussi a écrire des monstruosité de plusieurs mégas dans ce langage.

Si vous programmez, essayez d'écrire des petites protections en utilisant des langages

de programmation actuels (tous ceux destinés à Win95 et qui ne nécéssitent que très peu

de connaissance en programmation informatique car ce sont les plus utilisés pour les

softs que vous voulez craquer:-) puis deboggez votre programme sous SoftIce, et analysez

la manière dont votre programme aura été traduit en langage machine par le compilateur.

De cette manière vous comprendrez et progresserez beaucoup plus vite (et serez bien meilleurs)

que si vous passez vos journées a ne rechercher que les mots de passe sans vous soucier

du schéma de protection.
Le boulot du Cracker ne consiste pas uniquement a patcher un 'jnz' ou autre, il consiste aussi

a modifier le programme demo ou shareware, a le rendre plus performant, plus esthétique et

plus adapté à ses besoins, de telle sorte qu'à la fin, la version craquée est meilleure que

la version commerciale (beaucoup de programmeurs en tirent une leçon et vont même jusqu'a

modifier leur programme de la même manière que la version craquée!:-). Il existe encore

quelques rares vieux Crackers qui n'hésitent pas à prendre un programme ou une DLL et a en

modifier une trentaine (voir beaucoup plus) de lignes de code Assembleur. Vous aurez peut

être un jour l'occasion d'en croiser un par hasard sur le Net...
Voila, mijotez bien tout ça et, en attendant la suite, faites vous la main en craquant

TOUS les autres Softs d'Axialis de la même manière!
Frog's Print - Juillet 1997
(http://www.ThePentagon.com/Frog_s_Print)