KeyGenMe for Newbies :: Progressive KeygenMe #1

Bonjour à tous!

Pour mon premier post sur Re-Xe, je vous propose un petit tuto qui vise surtout les débutants en RE.
Il s’agit ici d’exploiter un simple petit KeyGenMe, en l’analysant puis en codant rapidement un petit KeyGen.

Vous pouvez trouver le KeygenMe ici : https://www.re-xe.com//uploads/2011/04/progressive_keygenme_1.zip

Si on l’execute, on aperçoit une simple fenêtre, avec deux champs de texte: un pour le nom et un pour le serial, ainsi que deux boutons.
Essayons de rentrer des infos au hasard.

Pour ma part, j’ai testé avec ‘ryscrow’ comme nom, et ‘123456789’ en serial. Appuyez sur Check, et normalement (sauf si vous avez une chance d’enfer et que vous avez réussi à trouver le serial correspondant au hasard du premier coup) la réponse ne tarde pas à tomber, avec une fenêtre qui s’ouvre indiquant: « Et non… Retente ta chance ».

Le but va donc être de trouver un serial correspondant au nom entré, et de réussir à trouver la routine pour le générer à partir de n’importe quel nom.

La première chose à vérifier, c’est que l’executable n’est pas packé ni crypté. Pour celà, un simple outil comme PEiD suffit.
On lance PEiD, on ajoute l’executable à tester, et PEiD nous informe que rien n’a été trouvé. (ce qui est normal pour un KeyGenMe destiné aux débutants…)

On va donc ici utiliser OllyDBG pour reverser notre programme.
Une fois lancé, OllyDBG nous place directement sur le point d’entrée du programme, à l’adresse 0x0401000.

Dans ce cas précis, le code désassemblé est suffisament clair pour qu’on puisse se passer de debug.
Les choses intéressantes commencent lors de l’appel à la fonction GetDlgItemTextA.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
0040106B   |.  83F8 05              CMP EAX,5
0040106E   |.  72 7E                JB SHORT 004010EE
00401070   |.  83F8 14              CMP EAX,14
00401073   |.  0F87 8C000000        JA 00401105
00401079   |.  89C1                 MOV ECX,EAX
0040107B   |.  8D35 00204000        LEA ESI,[402000]
00401081   |.  31DB                 XOR EBX,EBX
00401083   |>  0FB606               /MOVZX EAX,BYTE PTR [ESI]
00401086   |.  01C3                 |ADD EBX,EAX
00401088   |.  46                   |INC ESI
00401089   |.^ E2 F8                \LOOPD SHORT 00401083
0040108B   |.  53                   PUSH EBX                     ; /<%i>
0040108C   |.  68 63204000          PUSH 00402063                ; |Format = "%i"
00401091   |.  68 42204000          PUSH 00402042                ; |s = progress.00402042
00401096   |.  FF15 C2304000        CALL [<&USER32.wsprintfA>]   ; \wsprintfA
0040109C   |.  6A 20                PUSH 20                      ; /Count = 20 (32.)
0040109E   |.  68 21204000          PUSH 00402021                ; |Buffer = progress.00402021
004010A3   |.  6A 66                PUSH 66                      ; |ControlID = 66 (102.)
004010A5   |.  FF75 08              PUSH DWORD PTR [EBP+8]       ; |hWnd
004010A8   |.  FF15 BE304000        CALL [<&USER32.GetDlgItemTex>; \GetDlgItemTextA
004010AE   |.  68 21204000          PUSH 00402021                ; /String2 = ""
004010B3   |.  68 42204000          PUSH 00402042                ; |String1 = ""
004010B8   |.  FF15 6A304000        CALL [<&KERNEL32.lstrcmp>]   ; \lstrcmpA
004010BE   |.  75 17                JNZ SHORT 004010D7
004010C0   |.  6A 00                PUSH 0                       ; /Style = MB_OK|MB_APPLMODAL
004010C2   |.  68 66204000          PUSH 00402066                ; |Title = "Progressive KeygenMe #1"
004010C7   |.  68 7E204000          PUSH 0040207E                ; |Text = "Bravooo !!!",LF,CR,"Maintenant code un keygen et si t'es",LF,CR,"motiv",E9," un tutorial est le bienvenu."
004010CC   |.  FF75 08              PUSH DWORD PTR [EBP+8]       ; |hOwner
004010CF   |.  FF15 C6304000        CALL [<&USER32.MessageBoxA>] ; \MessageBoxA
004010D5   |.  EB 67                JMP SHORT 0040113E
004010D7   |>  6A 00                PUSH 0                       ; /Style = MB_OK|MB_APPLMODAL
004010D9   |.  68 66204000          PUSH 00402066                ; |Title = "Progressive KeygenMe #1"
004010DE   |.  68 D5204000          PUSH 004020D5                ; |Text = "Et non...",LF,CR,"Retente ta chance"
004010E3   |.  FF75 08              PUSH DWORD PTR [EBP+8]       ; |hOwner
004010E6   |.  FF15 C6304000        CALL [<&USER32.MessageBoxA>] ; \MessageBoxA
004010EC   |.  EB 50                JMP SHORT 0040113E
004010EE   |>  6A 00                PUSH 0                       ; /Style = MB_OK|MB_APPLMODAL
004010F0   |.  68 66204000          PUSH 00402066                ; |Title = "Progressive KeygenMe #1"
004010F5   |.  68 21214000          PUSH 00402121                ; |Text = "Le nom doit faire au moins 5 caract",E8,"res"
004010FA   |.  FF75 08              PUSH DWORD PTR [EBP+8]       ; |hOwner
004010FD   |.  FF15 C6304000        CALL [<&USER32.MessageBoxA>] ; \MessageBoxA
00401103   |.  EB 39                JMP SHORT 0040113E
00401105   |>  6A 00                PUSH 0                       ; /Style = MB_OK|MB_APPLMODAL
00401107   |.  68 66204000          PUSH 00402066                ; |Title = "Progressive KeygenMe #1"
0040110C   |.  68 F2204000          PUSH 004020F2                ; |Text = "Le nom ne doit pas faire plus de 20 caract",E8,"res"
00401111   |.  FF75 08              PUSH DWORD PTR [EBP+8]       ; |hOwner
00401114   |.  FF15 C6304000        CALL [<&USER32.MessageBoxA>] ; \MessageBoxA
0040111A   |.  EB 22                JMP SHORT 0040113E
0040111C   |>  6A 40                PUSH 40                      ; /Style = MB_OK|MB_ICONASTERISK|MB_APPLMODAL
0040111E   |.  68 49214000          PUSH 00402149                ; |Title = "About"
00401123   |.  68 4F214000          PUSH 0040214F                ; |Text = "Progressive KeygenMe #1",LF,CR,"",AF,"",AF,"",AF,"",AF,"",AF,"",AF,"",AF,"",AF,"",AF,"",AF,"",AF,"",AF,"",AF,"",AF,"",AF,"",AF,"",AF,"",AF,"",AF,"",AF,>
00401128   |.  FF75 08              PUSH DWORD PTR [EBP+8]       ; |hOwner
0040112B   |.  FF15 C6304000        CALL [<&USER32.MessageBoxA>] ; \MessageBoxA

En analysant un peu, on se rend compte que le gros de l’algorithme de génération du serial tient en 11 lignes de code:

1
2
3
4
5
6
7
8
9
10
11
0040106B   |.  83F8 05              CMP EAX,5
0040106E   |.  72 7E                JB SHORT 004010EE
00401070   |.  83F8 14              CMP EAX,14
00401073   |.  0F87 8C000000        JA 00401105
00401079   |.  89C1                 MOV ECX,EAX
0040107B   |.  8D35 00204000        LEA ESI,[402000]
00401081   |.  31DB                 XOR EBX,EBX
00401083   |>  0FB606               /MOVZX EAX,BYTE PTR [ESI]
00401086   |.  01C3                 |ADD EBX,EAX
00401088   |.  46                   |INC ESI
00401089   |.^ E2 F8                \LOOPD SHORT 00401083

Les 4 premières lignes contrôlent le nombre de caractères du « Name », nombre stocké dans le registre EAX.
Si EAX < 5 (donc 5 en décimal), on saute vers l’instruction qui affiche un message d’erreur. Si EAX > 14 (donc 20 en décimal), on saute vers l’instruction qui affiche un autre message d’erreur.

La 5ème instruction place le contenue du registre EAX dans ECX.

La 6ème place dans ESI un pointeur vers l’adresse où est stocké « Name » (402000)

La 7ème instruction remet à 0 le registre EBX.

Les 4 dernières instructions forment une boucle qui pourrait se traduire ligne par ligne par:

Placer l'octet vers lequel pointe ESI dans EAX (implicitement: Tant que celà est possible, la boucle se termine à la fin de la chaine de caractères.)
     EBX = EBX + EAX // Ajouter à EBX la valeur de EBX
     Incrémenter i
Retourner au début

La suite du code se contente de comparer la valeur obtenue par traitement du Name avec le sérial donné, et de nous rediriger en fonction du résultat de cette comparaison.

Donc après réflexion, l’algo n’est pas si compliqué que ça: il se contente d’additioner les valeurs décimales de chaque caractères du « Name ».

Voici un petit KeyGen que j’ai codé en C:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <stdio.h>
#include <stdlib.h>

int main()
{
char name[20];
printf("Name: ");
scanf("%s", name);

int somme = 0;
int i = 0;

while(name[i] != '\0')
{
somme = somme + name[i];
i++;
}

printf("Le Serial est: %d", somme);
system("PAUSE");
return 0;
}

Et voici l’utilisation :



Et donc :



Et voilà, cet article est fini 😀 J’espère qu’il vous aura aidé.

Si vous avez la moindre question, n’hésitez pas à poster des commentaires !

Ce contenu a été publié dans Keygen. Vous pouvez le mettre en favoris avec ce permalien.

2 réponses à KeyGenMe for Newbies :: Progressive KeygenMe #1

  1. Xylitol dit :

    Yo nigga
    les valeurs décimales de chaque caractères du « Name ». // loop -> addition de chaque chars du nom en hex !

    le décimal que tu parle de c’est %i
    i: signed decimal integer. This value is equivalent to d.
    (le output du serial et en décimal)
    pour résumé: les calcules sont en hex mais le output et en dec

    allez un keygen en assembleur car le c en console ça sucks:
    tapz.asm:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    .486
    .model  flat, stdcall
    option  casemap :none   ; case sensitive

    include windows.inc

    uselib  MACRO   libname
        include     libname.inc
        includelib  libname.lib
    ENDM

    uselib  user32
    uselib  kernel32

    DlgProc     PROTO :DWORD,:DWORD,:DWORD,:DWORD

    IDC_OK          equ 1003
    IDC_IDCANCEL    equ 1004

    .data
    szFormat db "%i",0

    szSizeMin   db "Le nom doit faire au moins 5 caractères",0
    szSizeMax   db "Le nom ne doit pas faire plus de 20 caractères",0
    szCap       db "Progressive KeygenMe #1 KEYGEN",0

    .data?
    hInstance       dd      ?   ;dd can be written as dword

    szName db 256 dup(?)
    szCode db 256 dup(?)
    .code
    start:
        invoke  GetModuleHandle, NULL
        mov hInstance, eax
        invoke  DialogBoxParam, hInstance, 101, 0, ADDR DlgProc, 0
        invoke  ExitProcess, eax
    ; -----------------------------------------------------------------------
    DlgProc proc    hWin    :DWORD,
            uMsg    :DWORD,
            wParam  :DWORD,
            lParam  :DWORD

        .if uMsg == WM_COMMAND
            .if wParam == IDC_OK
    ; -----------------------------------------------------------------------
    ;           TODO
    ; -----------------------------------------------------------------------

            invoke GetDlgItemText,hWin,1001,addr szName,sizeof szName
            CMP EAX,5
            JB @MinSize
            CMP EAX,014h
            JA @MaxSize
            MOV ECX,EAX
            LEA ESI,offset szName
            XOR EBX,EBX

    @progress_00401083:

            MOVZX EAX,BYTE PTR DS:[ESI]
            ADD EBX,EAX
            INC ESI
            LOOPD @progress_00401083
            PUSH EBX
            PUSH offset szFormat               ; ASCII "%i"
            PUSH offset szCode
            CALL wsprintf
           
            invoke SetDlgItemText,hWin,1002,addr szCode
            ret
           
    @MinSize:
    invoke MessageBox,hWin,addr szSizeMin,addr szCap,MB_ICONEXCLAMATION
    RET
    @MaxSize:
    invoke MessageBox,hWin,addr szSizeMax,addr szCap,MB_ICONEXCLAMATION
    RET

            .elseif wParam == IDC_IDCANCEL
                invoke EndDialog,hWin,0
            .endif
        .elseif uMsg == WM_CLOSE
            invoke  EndDialog,hWin,0
        .endif

        xor eax,eax
        ret
    DlgProc endp

    end start

    tapz.rc:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    ;This Resource Script was generated by WinAsm Studio.

    #define IDC_OK 1003
    #define IDC_CANCEL 1004

    101 DIALOGEX 0,0,169,44
    CAPTION "Base"
    FONT 8,"Tahoma"
    STYLE 0x80c80880
    EXSTYLE 0x00000000
    BEGIN
        CONTROL "OK",IDC_OK,"Button",0x00000001,110,5,50,14,0x00000000
        CONTROL "Cancel",IDC_CANCEL,"Button",0x00000000,110,23,50,14,0x00000000
        CONTROL "",1001,"Edit",0x00000080,7,7,90,12,0x00000200
        CONTROL "",1002,"Edit",0x00000080,7,24,90,12,0x00000200
    END

    see ya!

  2. Xylitol dit :

    J’ai oublié un truc: joyeux noël

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

*

Protected by WP Anti Spam

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.