.:HoMe:.     .:CrackMe:.     .:My ProGGie:.     .:BuGs & ExpLoiTs:.     .:TOoLs:.     .:VaRiE:.

> CraCk Me n.1 Di Bad Sector:SoLuTiOn <
Realizzato da NoRpiUs

ToOLz uTiLiZzATi:
- Debugger ( Olly Dbg )

SpiEgaZiOnE:
Questo crack me e' stato scritto da Bad Sector e a me e' piaciuto perche' ha una routine un po' diversa dal solito... ma andiamo ad analizzarla. Scopo: creare un keygen. Apriamo ollydbg e mettiamo un bpx sulle 2 GetDlgItemTextA e runniamo. Mettiamo i soliti dati a caso e il debugger poppa:

CALL    <JMP.&USER32.GetDlgItemTextA>              ; prende il nome
CMP     EAX,0                                                             ; confronta se e' 0
JE          Crackme1.004011EF                                      ; se lo e' esce
CMP     EAX,4                                                             ; ora confronta se il nome e' lungo 4 char
JB         Crackme1.004011EF                                       ; e se lo e' esce ancora
XOR     ECX,ECX                                                        ; azzera ecx
XOR     EBX,EBX                                                        ; azzera ebx
XOR     ESI,ESI                                                            ; azzera esi

Ok fin qua nulla di particolare, fa solo una validazione del nome, quindi da qui capiamo che il nostro user deve essere per forza maggiore di 4 char. Ora inizia la prima routine di crittazione:

MOV      DWORD PTR SS:[EBP-4],EAX              ; mette in ss[ebp-4] la lunghezza del nome
MOVSX EAX,BYTE PTR DS:[ECX+4020F3]       ; mette in eax la ECXesima lettera del nome
CMP      EAX,20                                                     ; la confronta con 20h (uno spazio vuoto)
JE           SHORT Crackme1.0040117B                  ; se e' uno spazio, esce
IMUL     EAX,EAX,4                                              ; moltiplica eax per 4
ADD      EBX,EAX                                                  ; somma eax a ebx
MOV     ESI,EBX                                                    ; mette ebx in esi
INC       ECX                                                           ; passa alla lettera successiva del nome
CMP     ECX,DWORD PTR SS:[EBP-4]                ; confronta ecx con la lunghezza del nome
JNZ       SHORT Crackme1.00401168                    ; se non sono uguali torna a inizio ciclo

Qua il nostro bel crack me non fa altro che fare dei piccoli calcoli con il nome. Non lasciatevi prendere dal panico dal primo mov, non e' nulla di particolare, mette solo in ss alla posizione [ebp-4] la lunghezza del nome che alla fine di ogni ciclo andra' a confrontare con ecx (che e' un contatore) ... quindi quello che fa non e' altro che fare i calcoli aumentando ad ogni ciclo ecx finche' non raggiunge la lunghezza dell' user. Scriviamoci il keygen fino a questo punto:

#include <stdio.h>
#include <string.h>

main() {

  int lun, i, eax, esi = 0;
  char *nome;

  printf("Scrivi un nome: ");
  scanf("%s",nome);

  lun = strlen(nome);
  for ( i = 0; i < lun; i++) 
  {
      eax = nome[i];
      eax *= 4;
      esi += eax;
   }
}


Ecco, alla fine avremo il nostro valore in ebx che sara' uguale al valore che ci sara' in esi (visto che a ogni ciclo ce un mov esi, ebx quindi viene ad ogni ciclo riscritto il valore di esi, ma a noi quello che interessa e' il valore alla fine di tutti i cicli naturalmente). Passiamo al secondo ciclo:

CMP       ESI,0                                                    ; confronta esi con 0
JE            SHORT Crackme1.004011EF              ; se lo e' esce
MOV      EBX,654789                                         ; mette 654789h in ebx
Iniziociclo:
MOVSX EAX,BYTE PTR DS:[ECX+4020F2]    ; mette in eax la lettera ECXesima del nome
DEC        EBX                                                      ; decrementa ebx
IMUL      EAX,EBX,2                                          ; moltiplica ebx per 2 e il risultato va in eax
ADD        EBX,EAX                                             ; somma eax a ebx
DEC        EBX                                                      ; decrementa ebx
DEC        ECX                                                      ; decrementa ecx
JNZ         Iniziociclo                                    ; se il flag Zero e' a 0 torna a inizio ciclo

Secondo ciclo di crittazione, solo che questa volta lo fa al "contrario": parte dall'ultima lettera del nome e fa dei calcoli e dopo passa alla precedente, questo perche' ecx ha il valore del ciclo di prima, ovvero e' uguale alla lunghezza del nome e a ogni ciclo viene decrementato. Il keygen dovrebbe venire cosi' fino a questo punto:

#include <stdio.h>
#include <string.h>

main() {

  int lun, i, eax, esi = 0;
  unsigned long ebx = 6637449;
  char *nome;

  printf("Scrivi un nome: ");
  scanf("%s",nome);

  lun = strlen(nome);
  for ( i = 0; i < lun; i++) 
  {
      eax = nome[i];  
      eax *= 4;
      esi += eax;
  }

  for ( i = 0; i < lun; i++) 
  {
      ebx--;
      ebx += ebx * 2;
      ebx--;
  } 
}

In realta' il movsx subito dopo l'inizio del ciclo non serve a nulla per il seriale, per cui a noi serve solo ebx. Come ultima parte ce un piccolo passaggio:

PUSH       ESI                                          ; pusha esi (primo for)
PUSH       EBX                                        ; pusha ebx (secondo for)
PUSH       Crackme1.004020C7              ; pusha la stringa "BS-%lX-%lu"
PUSH       Crackme1.004021BB              ; qua chissa' che cazzo pushi 
CALL       <JMP.&USER32.wsprintfA>   ; e richiama lo sprintf

In questo passaggio viene data la forma finale al serial, ovvero:
BS-<EBX>-<ESI> , ebx in esadecimale (%lX) e esi in decimale (%lu).
Infatti lo sprintf (comando che e' usato anche in c) non fa altro che prendere una stringa e sbattergli dentro dei valori in determinate posizioni. Perfetto ora siamo arrivati alla fine, scriviamoci il keygen finale:

#include <stdio.h>        // per lo scanf e printf
#include <string.h>       // per l' strlen
#include <stdlib.h>          // per l'exit(1)

main() {

  int lun, i, eax, esi = 0;
  unsigned long ebx = 6637449;
  char *nome;

  printf("Scrivi un nome: ");
  scanf("%s",nome);

  lun = strlen(nome);
  if (lun < 4)
  {
       printf("Nome troppo corto, minimo 4 caratteri");  
       exit(1);
  }

  for ( i = 0; i < lun; i++) 
  {
       eax = nome[i];
       eax *= 4;
       esi += eax;
  }

  for ( i = 0; i < lun; i++) 
  {
       ebx--;
       ebx += ebx * 2;
       ebx--;
  } 

  printf("Il seriale e': BS-");
  printf("%X-",ebx);               // %X stampa il numero in esadecimale e maiuscolo
  printf("%d",esi);
}

Complimenti a Bad per questo bel crack me, mi e' davvero piaciuto. Ciao, alla prox.

 

Sito ottimizzato per:
Browser: I.E.
Risoluzione: 1024 x 768
.:ReVeRsiNg:.     .:CoNTaCt Me:.     .:LiNks:.     .:ThaNksTo:.     .:FuCkTo:.