En la lección de este mes, les traigo un amigable crackme, que según el autor ( y con razón) es un tutorial, si lo desensamblamos, así que les pegaré el código y eso es todo… jeje , era broma, lo iremos descubriendo de a poco, y aprenderemos juntos.
Nos encontramos con una protección que no habíamos analizado aun, esta proteccion, es parecida a las utilizadas en los keymes, donde necesitamos un fichero clave para que el programa este registrado, este fichero clave contiene ciertas caracteristicas muy importantes que hacen, que se este registrado o no.
Bueno, este crackme no es un keyme, pero al principio actua como un keyme, nada mas que chequea un par de cosillas distintas, que ya veremos.
Reglas de Juego
Cuando ejecutamos el Crackme , tenemos en la pantalla principal de este, dos botones, y a la izquierda de estos, dos labels, que dicen Shareware y Unregistered.
Miremos en el boton About/Rules, donde nos dice, que hay tres caminos para crackear el crackme, y luego como les comente al principio del articulo, si lo desensamblamos, este crackme, es un tutorial por si mismo, tenemos permitido usar desensamblador y parchear; y por ultimo dice que si somos mejores con SoftIce, lo hagamos con SoftIce, pero nosotros no usaremos SoftIce, usaremos Olly Debugger, asi que no lo desensamblaremos, ni lo parchearemos fisicamente, solo en memoria.
Un poco de teoría
Desensamblemos el crackme, y veremos la pantalla principal de debugger, con el codigo ensamblador mostrandonos como es nuestra victima, debo decirles, que es un poco enradada, pero no nos asusteis, esta todo controlado…
Comenzamos en la dirección 401000, con un recibimiento poco comun en los crackmes (lo he visto en algunos programas y juegos comerciales, y bastantes nuevos), nada mas ni nada menos que un “Hi Reverser”,
¿ pero quien es el reverser aquí ?, SI! Nosotros, o eso creo….
Luego otro PUSH ( que lo que hace es cargar con una direccion de memoria la cual apuna al string, el string propiamente dicho) que nos dice “Here Starts the test for the Versión” (Aquí empieza el chequeo por la versión).
Nueve instrucciones mas abajo encontramos otro texto que es PUSHeado a la memoria diciendo: “Here end the test for the Versión” (Aquí termina el chequeo por la verision).
Con razon el creador dijo que esto era un tutorial, miren, si nos marca el sector donde hace el chequeo para decirnos si esta registrado o no el programa, nosotros debemos conseguir que en esos dos labels que hay al ejecutarlo en la pantalla principal diga que esta registrado.
Bien, veamos que podemos hacer aquí tenemos lo siguiente:

En la direccion 0040100B , la instrucción MOV [DWORD DS:40300C],1 y en la direccion 00401015 , la instrucción MOV [DWORD DS:403008],1 ; analicemos para que sirven y porque las nombro de entre todas las demas, ¿ ustedes piensan que tienen coronita ? pues no, no la tienen, o de algun modo si…
Los dos MOV’s mueven un 1 en decimal, a dos direcciones de memoria diferentes…. Anotemos la direccion 403008.
Más abajo en la dirección 00401021 , tenemos la instruccion LEA EAX,[DWORD DS:403010], que carga el valor que esta en la zona de memoria 403010 a EAX, y luego la instrucción de la direccion 00401029 que nos dice:

CMP EAX,X-LOCK~1.00403012

Luego viene nuestro push querido indicandonos el fin del programa, un pop eax, y un salto JE, que nos lleva a la direccion 401040….
Algo muy notorio
Muy bien, ¿que es lo notorio?, ese salto a 401040 nos lleva a continuar el flujo del programa normalmente, ¿pero que sucede si este salto no se realiza?, veamos:
00401036 MOV [DWORD DS:403008],0
¿Pero que sucede aquí?, en 403008, la que yo les dije que recordaran , pone un 0!!!, ¿porque? Sigamos mirando y deduzcamos si ese 0 es necesario para estar registrados o no…

Mas adelante en el programa , carga la ventana principal, en la direccion 401077 chequea , por si se ha clickeado un boton, y si es asi, pregunta cual de ellos, etc, etc. Esta rutina es comun en todos los programas, ya que es la rutina principal que chequea por cada opcion, o boton , si fue presionado o no, y en caso afirmativo se deriva el flujo del programa a la direccion correspondiente a la accion solicitada por el usuario.
Lo bueno comienza en la direccion 0040109D, donde nos encontramos el push identico, al primero que vimos en la apertura del programa desensamblado, y unas lineas de codigo mas abajo el otro push que nos indica que finaliza la seccion de registro, tal cual en el principio.
¿ Se acuerdan de los mirror checks que yo les habia explicado en articulos anteriores ?, bien, aquí lo tienen, la proteccion se repite en dos zonas de memoria distintas, o sea, que si nosotros parcheamos solamente la primera, o encontramos la segunda y parcheamos solamente esta, la otra seguira actuando normalmente y no nos dejara el programa registrado, por supuesto todo esto depende de cómo el programa este implementado, porque en nuestro caso, con modificar el segundo chequeo , nuestro crackme ya esta completamente funcional.
Fijense que en la direccion 0040109D vuelve a hacer lo mismo que antes.
Carga en EAX, lo que contiene la direccion 403010 y lo compara con lo que hay en la direccion 403012, si no llegan a ser iguales en la direccion 004010AD salta a la direccion 004010B9, pero la instrucción MOV [DWORD DS:40300C],0 de la linea anterior no es ejecutada, si se produce el salto, pero miren atentamente moveria un 0 decimal a la direccion 40300C, es otra zona!, es un doble chequeo, pero chequea dos zonas distintas de memoria, miremos mas,
miremos mas…..

En la direccion 004010A2 tenemos un LEA EAX,[DWORD DS:403010], 403010 tiene un 31 en hexa (1 en decimal), lo que al compararlo en 4010A8 con el valor de 00403012 que contiene un 30 en decimal (0 en decimal), hara que no salte y entonces el mov de la direccion 004010AF pondra a 40300C en 0 y no estaremos registrados.
A partir de la direccion de memoria 4010E6 hasta 4010EE tenemos lo siguiente:
MOV EAX,[DWORD DS:403008] ; mueve lo que contiene 403008 a EAX
CMP EAX,1 ; lo compara con 1
JNZ SHORT X-LOCK~1.00401105 ; y luego si no es igual salta a 401105
Mas abajo miremos, las strings cargadas…
004010F6 |. 50 PUSH EAX ; /Text => “Fullversion”
00401115 |. 50 PUSH EAX ; /Text => “Registered”
Necesitamos que estas strings se carguen, para que nuestro crackme funcione correctamente!!!, pero como podemos hacerlo??? Bien, el salto de la direccion 4010EE no nos lleva a poder ejecutar esas strings, por lo menos la de Fullversion no, pero sin embargo salta a una direccion anterior a la de la string “Registered”, salta a 401105, y “Registered”, esta en 401115, o sea que algo debe haber en el medio.. >: \
Perfecto, en la dirección 401105 tenemos lo mismo que en la direccion 4010E6 nada mas que el MOV EAX,[DWORD DS:403008] , cambia por MOV EAX,[DWORD DS:40300C] , aquí sucede lo mismo que antes, si no se cumple la misma condicion, o sea en la direccion 40300C no esta el valor 1 decimal, tampoco carga la string “Registered”, y nuestro programa no estaria ni completo (Fullversion) ni registrado (Registered).

Alternativas de Cracking:
Hay muchas alternativas, para hacer que nuestro pequeño funcione, podemos modificar los saltos de las direcciones 401034 y 4010EE, entonces como los valores de las direccion 403008 y 40300C seran 0 saltara, y nos hara registrar, simplemente cambiar los JNZ por JZ y listo, o sino por JMP y estos se transformaran en saltos INcondicionales, o sea, no importa si son iguales o no los valores, el salto se realiza igual.
Otra alternativa mas “elite”, y menos sucia que cambiar saltos y forzar el flujo del programa, es modificar la instrucción LEA de la direccion 00401021 , donde mueve lo que contiene 403010 a EAX, como lo que contiene 403010 es un 1 en decimal, siempre no saltara y nos pondra en 403008 el valor 0 con lo que no estaremos registrados nunca, entonces ¿por cual valor podemos moficar el operando de la instrucción LEA? Por una direccion de memoria como por ejemplo 403012, que contiene 0, entonces cuando llegue al CMP EAX, 403012, simplemente comparara el valor que contiene 403012 con el que contiene 403012, ¿resultado?, se produce el salto, y asi nuestro soldadito atrapado en 403008 (el 1), seguira vivo y no sera machacado….
Otra alternativa seria cambiar el CMP EAX,403012 por 403010, ya que, sera lo mismo, nada mas que en 403010 hay un 1 y no un 0 decimal como en 403012.
Luego en 004010A2 podemos modificar la instrucción LEA , por 403012, o inclusive podemos hacer un MOV EAX,0 y seria suficiente porque 403012 contiene un 0 decimal, y debemos hacer que el salto se produzca, y como el salto se produce cuando son iguales, pues ya lo tenemos
Tambien podemos modificar el CMP, como en la zona de chequeo anterior o el salto JNZ.
Triunfadores:
Hemos triunfado de nuevo, como podemos ver, nos aparece una ventanita, diciendonos, que hemos craqueado exitosamente el crakme, y que esperemos el segundo que sera mas difícil de crackear, ¿lo sera? Quizas si…. Quizas no….
¡Hasta la próxima!
convert this post to pdf.