KEYGEN du Crackme 1.0 de FredBug

 

Outils: SoftIce, OllyDbg
Date: 24 / 05 / 2002

 FerdBug nous dit qu il faut patcher et trouver / keygener le crackme. C’est ce que nous allons faire.

1 ) Patch du crackme
2 ) Keygen du crackme

PATCH DU CRACKME

Avant de commencer, il faut le dumper car il est compressé avec UPX je crois. Ceci fait, on l ouvre avec OllyDbg. Mais la on se retrouve dans le thread de Kernel32. Nous on veut être dans celui de l executable. On va allez a l entry point en faisant CTRL+G et on entre imagebase + entrypoint = 400000 + 130B. C’est bon, on est bien dans l exe. Ensuite,  clic droit puis search / All reference text string :

Cliquez sur “Rentrez votre nom”, on arrive ici :

:00401067 C704247C804000            mov dword ptr [esp], 0040807C
:0040106E E8EA010000                    call 0040125D                                   
:00401073 8D4598                            lea eax, dword ptr [ebp-68]
:00401076 50                                      push eax
:00401077 E897010000                     call 00401213                                     => Call Prenant votre nom et le nombre de caracteres
:0040107C 6864804000                    push 00408064
:00401081 E8D7010000                    call 0040125D                                    => Call du serial
:00401086 8D45FC                           lea eax, dword ptr [ebp-04]
:00401089 50                                     push eax

* Possible StringData Ref from Data Obj ->"%d"

:0040108A 6860804000                    push 00408060
:0040108F E868010000                     call 004011FC
:00401094 FF75FC                            push [ebp-04]
:00401097 8D4598                            lea eax, dword ptr [ebp-68]
:0040109A 50                                    push eax
:0040109B E823000000                    call 004010C3                                   
=> Routine du serial
:004010A0 83C41C                           add esp, 0000001C
:004010A3 85C0                                test eax, eax
:004010A5 7407                                je 004010AE
:004010A7 6848804000                    push 00408048                                  
=> ASCII “ Ouah trop fort”
:004010AC EB05                               jmp 004010B3
:004010AE 6830804000                    push 00408030                                  
=> ASCII “Encore un effort”

Vous l’avez compris, pour patcher le crackme, il faut inverser le saut en 4010A5, ce qui affichera « Ouah trop fort » à la place de « Encore un effort ».

KEYGEN DU CRACKME

Pour ce faire, on entre dans le call a l adresse 40109B. Vous tracez un peu le code jusqu ici :

Le nom doit etre compris entre 4 et 10 caracteres :

:004010DF 83F804                            cmp eax, 00000004                            => eax contient le nombre de caracteres du nom et est comparé a 4
:004010E2 59                                     pop ecx                                              
:004010E3 7E51                                 jle 00401136                                      => si inferieur ou egal a 4 saute
:004010E5 83F80A                            cmp eax, 0000000A                           => compare eax a 10 en decimal
:004010E8 7F4C                                jg 00401136                                       => si superieur saute

…..

Ensuite, la routine suivante s occupe des deux premiers caracteres :

:004010EC 0FBE0C30                      movsx ecx, byte ptr [eax+esi]              => prend l ascii du caracteres en cours
:004010F0 69C9F0000000                imul ecx, 000000F0                            => multiplie l ascii précédent par F0
:004010F6 81C13F2A0000               add ecx, 00002A3F                            => lui ajoute 2A3F
:004010FC 81F149596900                xor ecx, 00695949                              => le xor par 695949
:00401102 03F9                                 add edi, ecx                                        => met le tout dans edi ( on l appelle buffer1 )
:00401104 40                                     inc eax                                                => passe au caractere suivant
:00401105 83F802                             cmp eax, 00000002                            => compare si les deux premiers caracteres sont passes
:00401108 7CE2                                jl 004010EC                                       => si non on saute au debut

Ensuite la routine suivante s’occupe du 3eme et 4eme caractere du nom :

:00401148 0FBE0432                        movsx eax, byte ptr [edx+esi]              => prend l ascii du caractere en cours ( au depart edx est egal a 2 )
:0040114C 0FAFC0                          imul eax, eax                                       => le multiplie par lui meme
:0040114F 83F00A                            xor eax, 0000000A                             => le xor par A
:00401152 83C009                            add eax, 00000009                             => lui ajoute 9
:00401155 3523010000                     xor eax, 00000123                              => le xor par 123
:0040115A 0524100000                    add eax, 00001024                             => lui ajoute 1024
:0040115F 8D0440                            lea eax, dword ptr [eax+2*eax]           => charge l adresse de eax+2*eax dans eax
:00401162 C1E002                            shl eax, 02                                           => decalage a gauche
:00401165 0101                                 add dword ptr [ecx], eax                     => met le tout a l adresse pointee par ecx ( on l appelle buffer2 )
:00401167 42                                     inc edx                                                => passe au caractere suivant
:00401168 83FA04                            cmp edx, 00000004                            => le 3eme et 4eme caracteres sont passes ?
:0040116B 7CDB                               jl 00401148                                        => si non on saute au debut

Ensuite la routine suivante s’occupe du 5eme, 6eme et 7eme caractere du nom :

:00401190 0FBE043E                        movsx eax, byte ptr [esi+edi]               => prend l ascii du caracteres en cours( au depart esi est egal à 4 )
:00401194 83C033                            add eax, 00000033                             => lui ajoute 33
:00401197 6A03                                push 00000003                                   => met 3 sur la pile
:00401199 5B                                     pop ebx                                              => ebx prend le chiffre 3 de la pile
:0040119A 8D04C0                           lea eax, dword ptr [eax+8*eax]           => charge l adresse dans eax  
:0040119D 99                                    cdq                                                     => ? ( si quelqu un veut me le dire ce serait cool )  
:0040119E F7FB                                idiv ebx                                               => division signee
:004011A0 3589070000                    xor eax, 00000789                              => le xor par 789
:004011A5 83C032                            add eax, 00000032                             => lui ajoute 32
:004011A8 8D04C0                           lea eax, dword ptr [eax+8*eax]           => charge l adresse dans eax  
:004011AB D1E0                               shl eax, 1                                             => decalage a gauche
:004011AD 3576980000                    xor eax, 00009876                              => le xor par 9876
:004011B2 0101                                 add dword ptr [ecx], eax                     => met le tout a l adresse pointee par ecx ( buffer3 )
004011B4 46                                      inc esi                                                  => passe au caractere suivant
:004011B5 83FE07                            cmp esi, 00000007                             => les caracteres sont passes ?
:004011B8 7CD6                               jl 00401190                                        => si non retour au debut

La derniere routine s occupe des derniers caracteres :

:004011D7 0FBE0402                       movsx eax, byte ptr [edx+eax]             => prend l ascii du caracteres en cours( au depart esi est egal à 7 )
:004011DB 8D048544010000          lea eax, dword ptr [4*eax+00000144] => charge l adresse dans eax
:004011E2 83F038                             xor eax, 00000038                              => le xor par 38
:004011E5 83C05D                           add eax, 0000005D                            = lui ajoute 5D
:004011E8 83F005                             xor eax, 00000005                              => le xor par 5
:004011EB 8D0440                            lea eax, dword ptr [eax+2*eax]           => charge l adresse dans eax  
:004011EE C1E002                            shl eax, 02                                           => decalage a gauche
:004011F1 0101                                 add dword ptr [ecx], eax                     => met le tout dans ecx( buffer4 )
:004011F3 42                                     inc edx                                                => passe au caracteres suivants
:004011F4 83FA0A                           cmp edx, 0000000A                           => compare edx a A ( 10 en decimal )
:004011F7 7EDA                               jle 004011D3                                      => si inferieur ou egal on saute au debut de la routine

 Pour cette routine, il faut que j éclaircisses un point. Vous avez remarquer que la routine prend l ascii de tout les caracteres, c’est a dire 10 meme si le nom en fait moins. Prenons un exemple. J entre comme nom DalKiT, qui est composé de 6 caracteres. Au depart, apres l appui sur « Entrer » pour valider le nom, il y a une routine que je vais expliquer. Tout d’abord il y a une chaine hexadecimale constante : 00 00 65 00 58 A5 F7 BF 00 00 65.
L hexa des lettres de dalkit serait : 64 61 6C 6B 69 74 avec 64 correspondant a « d », 61 a « a », etc… .
Ensuite le nom remplace le debut de la chaine constante par lui meme.
Donc 00 00 65 00 58 A5 F7 BF 00 00 65 devient
         64 61 6C 6B 69 74 F7 BF 00 00 65

En fait ce n est pas complique mais g eu du mal a comprendre pourquoi mes serials marchaient pour des noms egales a 10 caracteres et pas moins.

Bon tracer le code pour arriver ici :

:0040111C 8B45FC                           mov eax, dword ptr [ebp-04]              => ebp-04 contient buffer4
:0040111F 8B4DF8                           mov ecx, dword ptr [ebp-08]              => ebp-08 contient buffer3
:00401122 03C8                                add ecx, eax                                        => ecx = buffer3 + buffer4
:00401124 83C410                            add esp, 00000010
:00401127 034DF4                            add ecx, dword ptr [ebp-0C]              => ecx = ecx + buffer2
:0040112A 33C0                                xor eax, eax
:0040112C 03CF                               add ecx, edi                                        => ecx = ecx + buffer1
:0040112E 394D0C                           cmp dword ptr [ebp+0C], ecx             => compare le vrai serial ( ecx ) au serial entre

Pour resumer le serial correspondant est egal a buffer1 + buffer2 + buffer3 + buffer4

Voilà, le keygen est terminé. Si vous avez des questions, mailez moi ( dalkit@hotmail.com )

Je remercie FredBug d’avoir codé ce crackme, N-GeN et tous le autres que j ai oublié.

DalKiT