Primeras impresiones
El crackme es el típico de usuario y número de serie. Si no introduces un nombre te salta un messagebox indicándotelo y si introduces cualquier información sale un mensaje de error.
Si dejamos solamente el serial en blanco nos sale un mensaje de error muy interesante diciéndonos que introduzcamos un número entre 1 y 2^32. Por lo tanto ya sabemos que nuestro serial está entre 1 y 4294967296.
PEiD no arroja resultados pero una primera impresión con Ollydbg hace creer que está programado en ensamblador y que no está comprimido.
Al ataque con Ollydbg
Cargamos el crackme en Ollydbg y hacemos click derecho Search for > Names
Vemos dos referencias interesantes como son:
- &USER32.GetDlgItemInt
- &USER32.GetDlgItemTextA
Ponemos sendos breakpoints y damos al play.
Vemos que para en USER32.GetDlgItemTextAy que retorna al offset 4010E7
Vamos a 4010E7 y vemos que pasa.
Hace un Test eax,eax por si hemos introducido algún nombre y si no es así nos muestra la nag.
Continuamos con la ejecución y para en el siguiente breakpoint, esta vez el referente a USER32.GetDlgItemInt, vamos al offset 401108 a ver que nos espera.
Se puede ver claramente que carga en EAX nuestro número de serie en hexa, lo compara con ESI que vale 0 y si son iguales nag de error y si no continua a 401120 donde guarda en la pila nuestro nombre y serial y llama al offset 401000.
Veamos que hay en el offset 401000.
Aquí vemos una primera parte con un bucle en el que interviene nuestro nombre y donde obtendremos el “HashName” y posteriormente una operaciones aritméticas en las que finalmente modifica el valor de EAX. Tengamos en cuenta que la comprobación final es un Test eax,eax o lo que es lo mismo, comprueba si EAX = 0 y si es 0 salta al mensaje de error como vemos en la imagen siguiente.
En resumen:
- Obtenemos el HashName.
- Realizamos unas operaciones a ese HashName (LOCAL.1) y al serial introducido (ARG.2).
- Si EAX <> 0 entonces serial correcto.
Sacando el “HashName”
Veamos un ejemplo de obtención del hashname para el usuario “abc”. El bucle se repetirá tantas veces como letras tenga el nombre.
Entendiendo la comprobación del serial
En resumen:
- Necesitamos que EAX <> 0.
- Necesitamos que (HashName XOR Serial) = 0 ya que:
a. La negación de 0 es 0 –>NEG(0) = 0
b. La resta con acarreo de 0 – 0 = 0 –>SBB 0,0 = 0
Hay que tener en cuenta que la resta con acarreo (SBB) de cualquier número, dará como resultado en EAX = FFFFFFFF, que al incrementar en 1 quedará en 0.
Por lo tanto si cumplimos las condiciones anteriormente expuestas, al incrementar EAX con INC EAX, este quedará en 1 haciendo nuestro serial válido.
Generando el serial válido
Las operaciones que se realizan sobre nuestro serial son NOT, SUB y XOR. Por suerte para nosotros son reversibles quedando nuestro serial así:
Serial válido = [NOT(HashName) + 0xBADC0DE5] XOR 0x1337C0DE
Para el nombre “abc” sería:
[(NOT(734111798) + 3134983653)] XOR 322420958 = 2620237168
Keygen en ensamblador
Como no es propósito de este manual enseñar a hacer un keygen desde 0, muestro el código importante y adjunto los links del código fuente. Si quieres ver como se hace un keygen básico en ASM desde cero mira el tutorial del Keygen para el KeygenMe#01 de eBuC.
Enlaces
Crackme + Keygen en ASM + WinASM studio 5.1.5 [31MB]