Intro

Hoy tenemos un crackme realizado en ensamblador y sin empacar. Consiste en el típico serial asociado a un nombre sin mucha complicación excepto en lo que a la utilización de memoria se refiere. Como veremos más adelante si no tenemos cuidado se solapan en memoria el nombre y el serial y como siempre evitaremos eso.

El algoritmo

Abrimos el crackme con Olly y buscamos las string references, pinchamos sobre cualquiera y encima encontramos el código que no interesa.

stringref

Subimos hasta las funciones que recojen el nombre y serial (GetDlgItemTexA) y nos fijamos que guarda el nombre a partir de la dirección de memoria 403014 y el serial a partir de 40301A. Además el nombre debe tener por lo menos tres caracteres.

getdlgitemaymemoria

compserial

El algoritmo consiste en lo siguiente, recorre el nombre y comprueba si el dígito se corresponde con 5A(Z), 7A(z) y 39(9). Si coincide los deja como está y si no les suma 1 al valor ascii. A continuación concatena después de cada conversión de dígito el caracter 61(a) aumentándole en 1 para cada nuevo dígito del nombre.

Ejemplo:

Nombre: ZZZZZ
Serial: ZaZbZcZdZe

Nombre: zzzzz
Serial: zazbzczdze

Nombre: 99999
Serial: 9a9b9c9d9e

Como veréis a continuación, para el nombre «deuru» el serial correcto sería «eafbvcsdve«. Simplemente a los caracteres del nombre les suma 1, d es e, e es f, u es v, etc, y los concatena con digito+a+digito+b+digito+c…

Nombre: deuru
Serial: eafbvcsdve

Bucle se repite tantos veces como dígitos tenga el nombre

d  e  u  r  u
64 65 75 72 75

e  a  f  b  v  c  s  d  v  e
65 61 66 62 76 63 73 64 76 65

DUMP
----
00403010  00 00 00 00 64 65 75 72 75 00 65 61 66 62 76 63  ....deuru.eafbvc
00403020  73 64 76 65 00 05 00 00 00 00 00 00 00 00 00 00  sdve...........

 La asignación de memoria

El problema viene cuando elegimos un nombre >5 caracteres, ya que, éste se solapa con la memoria del serial (recordemos 40301A y siguientes) haciendo que sea una chapuza. En la siguiente imagen queda claro. No se si es un error o es intencionado, pero nos conviene no utilizar nombres mayores de 5 dígitos para que nuestro keygen sea lo más limpio posible.

ejemplodump2

El KeyGen

Está realizado en C++ y como véis el nombre debe tener entre 3 y 5 dígitos para que todo vaya bien.

char Nombre[10];
GetWindowText(hwndEdit1, Nombre, 10);
SetWindowText(hwndEdit2, "");
string serial = "";
int len = strlen(Nombre);
char consecutivo[5] = {'a','b','c','d','e'};
if (len <=5 && len >=3){
    for(int i = 0; i <= len; i++)
    {
         if (Nombre[i] == 0x5A || Nombre[i] == 0x7A || Nombre[i] == 0x39)
         {
             serial+=Nombre[i];
             serial+=consecutivo[i];
         }else{
             serial+=Nombre[i]+1;
             serial+=consecutivo[i];
         }
     }
     serial = serial.substr(0, len*2);
     LPCTSTR Sfinal = serial.c_str();
     SetWindowText(hwndEdit2, Sfinal);
}else{
MessageBox(NULL,"Nombre demasiado largo/corto","Info",MB_OK | MB_ICONINFORMATION);
}

 Links


Habitualmente suelo descargar shareware por diversión para evaluar de que manera protegen los programadores su software. Cada vez es más
Introducción Herramientas disponibles CrkViz-1 (Serial a la vista) CrkViz-2 (Parcheando rutina aleatoria) CrkViz-3 (Nag+Keygen) CrkViz-4 (Límite de ejecuciones+Keygen) CrkViz-5 (Serial
Intro Hoy tenemos aquí un crackme del año 2000 empacado y con un algoritmo aunque no muy complicado largo de
El reto Se nos proporciona la imagen anterior y se nos invita a resolver la ecuación para el menor entero