Buenas .:UND3R:.,
la verdad es que no se qué quieres que te explique.
La primera parte del crackme es obvia: con el crc32 del nombre y el serial introducido (en base 4) hago un xor y el resultado es un dword que es el usado para descifrar el procedimiento que muestra el mensaje de chico bueno. Así que lo único que necesitamos hacer es encontrar esta dword.
Una forma de hacerlo es encontrarla por fuerza bruta, por ejemplo con este código:
.386
.model flat,stdcall
option casemap :none
include \masm32\include\windows.inc
include \masm32\include\user32.inc
include \masm32\include\kernel32.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib
.data
cte db 084h, 08Eh, 056h, 02Bh, 0E3h, 040h, 0D4h, 0A8h, 0BEh, 077h, 0DBh, 0A2h, 0A4h, 060h, 0D4h, 0A1h
db 0F1h, 066h, 0C8h, 0A1h, 0B2h, 06Eh, 0DFh, 0B2h, 0FFh, 008h, 0B0h, 0CDh, 0DBh, 044h, 0D2h, 0AFh
db 0A3h, 064h, 09Ah, 0B0h, 0A3h, 06Ah, 0DDh, 0B2h, 0B0h, 068h, 0DBh, 0E0h, 0B4h, 069h, 09Ah, 0ABh
db 0B4h, 07Ch, 0DDh, 0A5h, 0BFh, 02Bh, 0BAh, 0AAh, 0D1h, 06Dh, 0D6h, 0F0h, 091h, 005h, 0D2h, 018h
db 0C3h, 045h, 0BAh, 03Fh, 0A4h, 00Dh, 052h, 0DCh, 0D1h, 005h, 0BAh, 009h, 013h, 001h, 0BAh
CRCPOLY dd 0EDB8831Fh
dwCRC32 dd 3C048143h
szHex db "%X",0
szTitulo db "Brute", 0
.data?
CRCTaboa db 1024 dup (?)
funcion_encriptada db 80 dup (?)
dwNumMaxico dd ?
szNumMaxico db 9 dup (?)
.code
start:
call taboa_crc32
@bucle_bruto:
mov edx, dwNumMaxico
mov esi, offset cte
mov edi, offset funcion_encriptada
xor ecx, ecx
@@:
mov eax, [esi]
mov [edi], eax
add esi, 4
add edi, 4
inc ecx
cmp ecx, 19
jb @B
mov ax, word ptr [esi]
mov word ptr [edi], ax
mov al, byte ptr [esi + 2]
mov byte ptr [edi + 2], al
mov esi, offset funcion_encriptada
mov ecx, 20
@@:
xor [esi], edx
add esi, 4
loop @B
push offset funcion_encriptada
push 79
call crc32
cmp eax, dwCRC32
jz @correcto
inc dwNumMaxico
jmp @bucle_bruto
@correcto:
push dwNumMaxico
push offset szHex
push offset szNumMaxico
call wsprintf
add esp, 12
push MB_OK
push offset szTitulo
push offset szNumMaxico
push 0
call MessageBox
push 0
call ExitProcess
taboa_crc32 proc
push ebx
mov edi, CRCPOLY
inc edi
xor ebx, ebx
mov ecx, offset CRCTaboa
taboa_bucle:
movzx eax, bx
add eax, eax
mov dx, 0fff7h
taboa_salto:
test al, 01h
jz taboa_salto_1
shr eax, 01h
xor eax, edi
jmp taboa_salto_2
taboa_salto_1:
shr eax, 01h
taboa_salto_2:
inc dx
jnz taboa_salto
mov [ecx], eax
inc ebx
add ecx, 04h
cmp bx, 0100h
jnz taboa_bucle
pop ebx
ret
taboa_crc32 endp
crc32 proc len:DWORD, lpBuffer
mov ebx, lpBuffer
mov esi, len
mov edi, 0FFFFFFFFh
crc32_bucle:
mov edx, edi
mov eax, [ebx]
and eax, 0FFh
xor al, dl
mov eax, [eax * 4 + offset CRCTaboa]
shr edx, 08h
xor eax, edx
mov edi, eax
inc ebx
dec esi
jnz crc32_bucle
crc32_salir:
not edi
mov eax, edi
ret
crc32 endp
end start
y una vez encontrada ya podemos hacer un keygen fácilmente.
De todos modos yo no lo haría así, y aunque creo que el código de arriba no tardará ni media hora en encontrar la palabra mágica, seguramente la intentaría intuir:
Estudiando el resto del programa suponemos que las tres primeras instrucciones serán:
004012D3 /$ 55 PUSH EBP
004012D4 |. 8BEC MOV EBP,ESP
así que si hacemos el xor de desencriptación de estos tres valores con los de la función encritpada nos escontramos con que los tres primeros bytes del dword mágico serían 0xD105BA?? y ahora podríamos hacer un brutalizador aún más rápido, con sólo 256 posibilidades. De esta forma me lo solucionaron en otro foro.
Y es que sí, el procedimiento empieza con "Push EBP y Mov EBP, ESP". ¿Por qué? Porque cuando programé el código quería que fuese solucionable sin fuerza bruta y el compilador MASM cuando llamo a un procedimiento al que le envío parámetros comienza con esas instrucciones para controlar la pila.
Así que le envío un parámetro del que realmente podría prescindir pero necesario para poder solucionarlo sin fuerza bruta, ya que, además de empezar con esas instrucciones, acabará con
0040131E |. C9 LEAVE
0040131F \. C2 0400 RETN 4
y aquí si que conozco 4 bytes seguidos para poder encontrar la clave mágica sin tener que crear nada.
Bueno, tendríamos que fijarnos que hay un RETN 4, porque precisamente sólo le envié un parámetro dword al procedimiento. Si vemos el regreso del procedimiento que calcula el CRC32 vemos que acaba con un RETN 8 porque se le envían 2 parámetros (inicio de memoria y longitud).
0xC9C20400 xor 091301BA = 0xC0D105BA
que está desordenado porque tenemos 79 bytes a cifrar/descifrar, así que 79 mod 4 = 3. Corremos los tres bytes y obtenemos el dword bueno.
@.:UND3R:. si no es esto lo que querías que te explicase por favor vuelve a preguntarme.
Saludos.