4. Créer le keygen

Nous allons maintenant coder un keygen en assembleur. Vous pouvez accéder au keygen complet en cliquant sur ce lien KEYGEN. Le vrai problème de ce keygenme réside dans le code du keygen. En effet, le serial dépend de 3 bytes situés dans le binaire d'origine variables à chaque lancement ! Notre keygen doit donc tout d'abord se charger de récupérer ces 3 octets. Nous allons donc commencer le travail en scannant les processus actifs à la recherche du module "esoquynthe.exe". une fois le binaire trouvé, nous allons ouvrir le processus correspondant et nous allons subtiliser les 3 fameux bytes. Il ne nous restera plus qu'à utiliser la TABLE DE VERIFICATION pour récupérer la bonne séquence à cliquer.

Récupérer le handle de esoquynthe

Nous allons donc commencer par scanner les processus actifs à la recherche de notre module en utilisant une technique très répendue : CreateToolhelp32Snapshot

Les datas :

    lpNumberOfBytesWritten  DWORD   0
    Nom_Module              BYTE    "esoquynthe.exe",0 
    hProcessSnap            DWORD   0
    hModuleSnap             DWORD   0
    pProcessEntry           PROCESSENTRY32 <>
    pModuleEntry            MODULEENTRY32 <>
    titre                   BYTE    "information :",0
    texte                   BYTE    "Le crackme esoquynthe n'est pas lancé !",0

Le code :

  push 0
  push TH32CS_SNAPPROCESS
  call CreateToolhelp32Snapshot                     ; Snapshot of processes
  mov hProcessSnap, eax

  mov pProcessEntry.dwSize, SIZEOF PROCESSENTRY32
  push offset pProcessEntry
  push hProcessSnap
  call Process32First                               ; Get first process

Test_Process:
  cmp eax, 0
  jnz Scan_Process
  jmp sortie

Scan_Process:

  push pProcessEntry.th32ProcessID
  push TH32CS_SNAPMODULE
  call CreateToolhelp32Snapshot                     ; Snapshot of modules in the current process
  mov hModuleSnap, eax


  mov pModuleEntry.dwSize, SIZEOF MODULEENTRY32
  push offset pModuleEntry
  push hModuleSnap
  call Module32First                                ; Get first Module

Test_Module:
  cmp eax, 1
  jnz Next_Process 
  
  push offset pModuleEntry.szModule
  push offset Nom_Module
  call lstrcmpiA                                    
  test eax, eax
  jnz NextModule
  jmp LIRE_PROCESS

NextModule:
  push offset pModuleEntry
  push hModuleSnap
 call Module32Next
  jmp Test_Module

Next_Process:
  push hModuleSnap
  call CloseHandle
  push offset pProcessEntry
  push hProcessSnap
  call Process32Next
  jmp Test_Process

sortie:
  push 0
  push offset titre
  push offset texte
  push 0
  call MessageBoxA
  jmp fin
; ************************************ Détermine le code !

LIRE_PROCESS:

Récupération des 3 octets

Nous allons alors ouvrir le processus et récupérer les 3 bytes.

LIRE_PROCESS:

  push pProcessEntry.th32ProcessID
  push 0
  push PROCESS_VM_READ
  call OpenProcess


  push lpNumberOfBytesWritten
  push 4
  push offset CHAINE
  push 405103h
  push eax
  call ReadProcessMemory

Générer la séquence de touches

Nous pouvons alors tranquillement générer la bonne séquence de touches en utilisant une table comme la TABLE DE VERIFICATION.

Les Datas :

    FORMAT_     BYTE    "%.8x",0
    
   
    CHAINE      DWORD   0
    CODE        DWORD   0
                DWORD   0
    CODE_ascii  BYTE    0 DUP(10)
    TABLE       BYTE    04h,03h,02h,01h,00h
                BYTE    01h,00h,04h,03h,02h
                BYTE    02h,01h,00h,04h,03h
                BYTE    03h,02h,01h,00h,04h

Le code :

  mov esi, offset CHAINE
  mov edi, offset CODE
  mov ecx, 1

Scan:
    mov eax, 0
    cmp byte ptr [esi], 0
    jne @F
    add eax, 0
    jmp suite
@@:
    cmp byte ptr [esi], 1
    jne @F
    add eax, 5
    jmp suite
@@:
    cmp byte ptr [esi], 2
    jne @F
    add eax, 0Ah
    jmp suite
@@:
    cmp byte ptr [esi], 2Bh
    jne suite
    add eax, 0Fh
suite:
    cmp byte ptr [edi+ecx-1], 0
    jne @F
    add eax, 0
    jmp boucle
@@:
    cmp byte ptr [edi+ecx-1], 1
    jne @F
    add eax, 1
    jmp boucle
@@:
    cmp byte ptr [edi+ecx-1], 2
    jne @F
    add eax, 2
    jmp boucle
@@:
    cmp byte ptr [edi+ecx-1], 3h
    jne @F
    add eax, 3
    jmp boucle
@@:
    cmp byte ptr [edi+ecx-1], 4h
    jne boucle
    add eax, 4
boucle:
    mov ebx, offset TABLE		------------------ Récupérer la valeur dans TABLE
    add ebx, eax
    movzx eax, byte ptr [ebx]
    mov byte ptr [edi+ecx], al
    inc ecx
    inc esi
    cmp ecx, 4
    jne Scan

    mov esi, CODE
    push esi
    push offset FORMAT_
    push offset CODE_ascii
    call wsprintfA
    add esp, 0Ch

    mov esi, offset CODE_ascii
    add esi, 7
    push esi
    push SERIAL1
    push hWin
    call SetDlgItemTextA -------------------------------- Premier bouton

    dec esi
    mov word ptr [esi], 0
    dec esi
    push esi
    push SERIAL2
    push hWin
    call SetDlgItemTextA ---------------------------------- Second bouton

    dec esi
    mov word ptr [esi], 0
    dec esi
    push esi
    push SERIAL3
    push hWin
    call SetDlgItemTextA ---------------------------------- troisième bouton

    dec esi
    mov word ptr [esi], 0
    dec esi
    push esi
    push SERIAL4
    push hWin
    call SetDlgItemTextA ---------------------------------- Quatrième bouton

Vous pouvez constater qu'à aucun moment je n'utilise les valeurs poussées sur la pile dans le binaire d'origine. Seule la TABLE est importante, le reste n'est que du décor.

Page suivante

Valid XHTML 1.0 Strict

Valid CSS!