Intro

Hoy nos enfrentamos a un crackme realizado en Delphi con un algoritmo bastante sencillo. Está empacado con UPX pero aquí no vamos a explicar como desempacarlo ya que UPX es un reductor de tamaño más que un empacador, incluso con el propio empacador podemos desempacarlo.

Nota: Si queréis ver el proceso completo de desempacado ver el siguiente video (http://youtu.be/c4CNY902SAE).

El algoritmo

Abrimos Olly y vamos a las string references, localizamos los mensajes de error y éxito y pulsamos sobre cualquiera.

stringref

Encima de los mensajes tenemos la rutina de comprobación del serial. En la primera imagen vemos que comprueba que no dejemos ningún campo vacío y a continuación se mete de lleno con el serial.

checkcamposenblanco

checkserial

Analicemos la rutina del serial.

00454882       |> /8B15 4C6C4500          /MOV EDX,DWORD PTR DS:[456C4C]      ; Concatena name + ECloZion + pronom   <---
00454888       |. |8B0D 506C4500          |MOV ECX,DWORD PTR DS:[456C50]
0045488E       |. |0FB6540A FF            |MOVZX EDX,BYTE PTR DS:[EDX+ECX-1]  ; Coje el dígito que toque
00454893       |. |8916                   |MOV DWORD PTR DS:[ESI],EDX         ; Mueve EDX a TEMP (inicialmente vale FFFFFFFF)
00454895       |. |833E 5F                |CMP DWORD PTR DS:[ESI],5F
00454898       |. |75 06                  |JNZ SHORT ECloZion.004548A0
0045489A       |. |C706 20000000          |MOV DWORD PTR DS:[ESI],20
004548A0       |> |8B17                   |MOV EDX,DWORD PTR DS:[EDI]
004548A2       |. |3116                   |XOR DWORD PTR DS:[ESI],EDX         ;  TEMP = TEMP xor digito
004548A4       |. |8136 CE9A5614          |XOR DWORD PTR DS:[ESI],14569ACE    ;  TEMP = TEMP xor 14569ACE
004548AA       |. |8B16                   |MOV EDX,DWORD PTR DS:[ESI]
004548AC       |. |8917                   |MOV DWORD PTR DS:[EDI],EDX
004548AE       |. |FF05 506C4500          |INC DWORD PTR DS:[456C50]
004548B4       |. |48                     |DEC EAX                            ; EAX = longitud del concatenado = contador del bucle.
004548B5       |.^\75 CB                  \JNZ SHORT ECloZion.00454882        ; Bucle --->
004548B7       |>  8137 F0BD6434          XOR DWORD PTR DS:[EDI],3464BDF0     ; TEMP 0 TEMP xor 3464BDF0

 

Ejemplo:

Nom: deurus
Prenom: any

d  e  u  r  u  s  E  C  l  o  Z  i  o  n  a  n  y
64 65 75 72 75 73 45 43 6C 6F 5A 69 6F 6E 61 6E 79

FFFFFFFF xor 64 = FFFFFF9B xor 14569ACE = EBA96555
EBA96555 xor 65 = EBA96530 xor 14569ACE = FFFFFFFE
FFFFFFFE xor 75 = FFFFFF8B xor 14569ACE = EBA96545
EBA96545 xor 72 = EBA96537 xor 14569ACE = FFFFFFF9
FFFFFFF9 xor 75 = FFFFFF8C xor 14569ACE = EBA96542
EBA96542 xor 73 = EBA96531 xor 14569ACE = FFFFFFFF
FFFFFFFF xor 45 = FFFFFFBA xor 14569ACE = EBA96574
EBA96574 xor 43 = EBA96537 xor 14569ACE = FFFFFFF9
FFFFFFF9 xor 6C = FFFFFF95 xor 14569ACE = EBA9655B
EBA9655B xor 6F = EBA96534 xor 14569ACE = FFFFFFFA
FFFFFFFA xor 5A = FFFFFFA0 xor 14569ACE = EBA9656E
EBA9656E xor 69 = EBA96507 xor 14569ACE = FFFFFFC9
FFFFFFC9 xor 6F = FFFFFFA6 xor 14569ACE = EBA96568
EBA96568 xor 6E = EBA96506 xor 14569ACE = FFFFFFC8
FFFFFFC8 xor 61 = FFFFFFA9 xor 14569ACE = EBA96567
EBA96567 xor 6E = EBA96509 xor 14569ACE = FFFFFFC7
FFFFFFC7 xor 79 = FFFFFFBE xor 14569ACE = EBA96570
--------------------------------------------------
Resultado = EBA96570
EBA96570 xor 3464BDF0 = DFCDD880 = 3754809472 --> nuestra serial

 KeyGen en C++

            char Nombre[20];
            GetWindowText(hwndEdit1, Nombre, 20);
            char prenom[20];
            GetWindowText(hwndEdit2, prenom, 20);
            char Serial[20];
            char concatenado[48];
            wsprintf(concatenado,"%sECloZion%s",Nombre,prenom);
            int len = strlen(concatenado);
            unsigned int suma = 0xFFFFFFFF;
                for(int i = 0; i < len; i = i + 1)
                {
                        suma = suma ^ concatenado[i];
                        suma = suma ^ 0x14569ACE;
                }
            suma = suma ^ 0x3464BDF0;
            wsprintf(Serial,"%u",suma);
            SetWindowText(hwndEdit3, TEXT(Serial));

 Links


Intro Antes que nada, es importante saber que un archivo ELF en Linux es equivalente a un archivo EXE en
Introducción Esta vez se trata de un crackme realizado en VC++ 5.0/6.0 y en sus entrañas utiliza RSA-24. En este
Introducción Recién rescatados del inframundo que es mi disco duro, os traigo un paquete de seis crackmes facilones para vuestro
Estamos ante un ELF un poco más interesante que los vistos anteriormente. Básicamente porque es divertido y fácil encontrar la