Intro
Hoy tenemos un crackme realizado en Visual C++ 6. Es el típico serial asociado a un nombre.
El algoritmo
Localizamos con Olly la rutina de comprobación del serial y empezamos a analizar. Vemos una serie de Calls que lo único que hacen es comprobar el tamaño de nuestro nombre y serial y si es <5 dígitos nos tira afuera.
Una vez pasada la traba anterior procede con un bucle para el nombre y otro para el serial. Yo he metido deurus y 123456. El bucle del nombre hace xor al los dígitos ascii con un valor incremental a partir de 1. Reconvierte el valor resultante en su caracter correspondiente y lo almacena.
00401576 |. B9 01000000 MOV ECX,1 ; ECX = 1 0040157B |. 33D2 XOR EDX,EDX 0040157D |. 8B45 E4 MOV EAX,[LOCAL.7] ; EAX = Nombre 00401580 |> 8A18 /MOV BL,BYTE PTR DS:[EAX] ; BL = digito que toque <-- 00401582 |. 32D9 |XOR BL,CL ; digito XOR ECX 00401584 |. 8818 |MOV BYTE PTR DS:[EAX],BL ; sustituye el digito nombre por el resultante del xor 00401586 |. 41 |INC ECX ; ECX++ 00401587 |. 40 |INC EAX ; Siguiente digito 00401588 |. 8038 00 |CMP BYTE PTR DS:[EAX],0 0040158B |.^ 75 F3 \JNZ SHORT crackme3.00401580 ; Bucle -->
Ejemplo:
d e u r u s 64 65 75 72 75 73 (d)64 xor 1 = 65(e) (e)65 xor 2 = 67(g) (u)75 xor 3 = 76(v) (r)72 xor 4 = 76(v) (u)75 xor 5 = 70(p) (s)73 xor 6 = 75(u) Nombre: deurus Resultado: egvvpu
Hace lo mismo con el serial pero con el valor incremental a partir de 0xA (10).
00401593 |. B9 0A000000 MOV ECX,0A ; ECX = A 00401598 |. 33D2 XOR EDX,EDX 0040159A |. 8B45 F0 MOV EAX,[LOCAL.4] ; EAX = Serial 0040159D |> 8A18 /MOV BL,BYTE PTR DS:[EAX] ; BL = digito que toque <-- 0040159F |. 32D9 |XOR BL,CL ; BL XOR CL 004015A1 |. 8818 |MOV BYTE PTR DS:[EAX],BL ; sustituye el digito serial por el resultante del xor 004015A3 |. 41 |INC ECX ; ECX++ 004015A4 |. 40 |INC EAX ; Siguiente digito 004015A5 |. 8038 00 |CMP BYTE PTR DS:[EAX],0 004015A8 |.^ 75 F3 \JNZ SHORT crackme3.0040159D ; Bucle -->
Ejemplo:
1 2 3 4 5 6 31 32 33 34 35 35 (1)31 xor A = 3B(;) (2)32 xor B = 39(9) (3)33 xor C = 3F(?) (4)34 xor D = 39(9) (5)35 xor E = 3B(;) (6)36 xor F = 39(9) Serial: 123456 Resultado: ;9?9;9
A continuación compara «egvvpu» con «;9?9;9» byte a byte.
KeyGen
El KeyGen quedaría así
for(int i = 0; i <= strlen(Nombre); i = i + 1) { Serial[i] = (Nombre[i]^(i+1))^(0xA + i); }