Está en la página 1de 13

Tutorial n 34 by +NCR/CRC!

[ReVeRsEr]

Introduccin
Hola a todos!!!. Esta vez vamos a tratar de crear un crackme sencillo, del estilo Name/Keygen y su
correspondiente KeyGen, tambin sencillo.
Considero que es una prctica importante que cada uno, adems de crackear programas comerciales
o de otras personas, pueda llegar a desarrollar sus propias aplicaciones y las crackee para tener un
espectro ms grande del tema.
Yo he tenido das en que me bajaba cinco programas de la red y de los cinco, tres tenan una
proteccin similar. Por lo que en realidad no se aprenda mucho. Pero creo que de esta forma,
podemos crear cosas no tan comunes en los programas y ver de que manera los podemos tirar abajo,
je.
En esta primera ocasin y considerando que no soy ni siquiera un novato en la programacin,
vamos a crear un crackme bien sencillo y su correspondiente keygen. Si alguno quiere hacer algo
parecido, pero con un poco ms de complejidad que lo haga as aprendemos mucho ms....
Manos a la obra....
Las herramientas que vamos a utilizar ya son conocidas por todos nosotros, el que no las tenga que
las busque en el FTP de Ricardo o por la red.
Por supuesto, para la programacin vamos a utilizar a MASM como Compilador/Ensamblador, a
RadASM como entorno de programacin y a nuestro querido Olly para depurar el programa.

reversing_ar@yahoo.com.ar

http://www.joe-cracker.tk/ncr.htm

Tutorial n 34 by +NCR/CRC! [ReVeRsEr]

Este tut est orientado a la gente que est dando sus primeros pasos en ASM, creo la gente con la
que hablo siempre en la lista, los ms conocidos ya saben de sobra todo esto que voy a decir, as que
muchachos no se ran, je.
Ya todos conocemos, o deberamos conocer, la ventana principal del RadASM. El que no sepa nada
de esto, que se dirija a los tuts de programacin que estn en el FTP/http de Ricardo Narvaja y los
lea, son de los maestros de la programacin, je.
Primero que nada vamos a crear un proyecto nuevo en nuestro rad, para ello vamos a File New
Project. En la nueva ventana que nos aparece ponemos el nombre del proyecto y seleccionamos
Win32 App. Luego, le damos a siguiente y seleccionamos el Template que queremos, generalmente,
nosotros trabajamos con DialogApp.tpl, as que lo seleccionamos y damos al botn siguiente hasta
que nos aparezca el form principal. Ah colocaremos los controles que necesitaremos en el crackme.
Hacemos click en esta parte:

Y seleccionamos el archivo *.dlg, en este caso se llama KeyGenMe.dlg. Ah colocan los controles
que quieran, yo he colocado un GroupBox, dos edits, tres botones y un control para aadir el logo.
Lo fundamental son los dos edits y a menos un botn, se puede hacer sin botn pero es un poquito
ms complicado, por ahora hagmoslo as. Me queda de esta manera:

reversing_ar@yahoo.com.ar

http://www.joe-cracker.tk/ncr.htm

Tutorial n 34 by +NCR/CRC! [ReVeRsEr]


Ahora viene la parte ms divertida, je, la de agregar el cdigo. La idea que tom para este crackme
es bastante sencilla, en pocos minutos lo tens listo.
Lo que haremos ser, xorear cada uno de los caracteres del nombre con algn valor constante para
generar algn tipo de serial a partir de dicho nombre, luego xorear cada carcter del serial con otros
valor distinto al anterior y almacenarlo en una variable. Por ltimo, tomaremos el serial generado en
primer instancia y lo xorearemos con el mismo valor con el que xoreamos el serial que introduce el
usuario y lo compararemos, carcter a carcter, con este ltimo.
Por ejemplo:
Nuestro nombre es Cracker, y el serial que metemos es 012345. Tomaremos la C del nombre y lo
xorearemos con, por ejemplo, 30H y as sucesivamente con todos los caracteres del nombre:
C xor 30H = s
r xor 30H = B
a xor 30H = Q
c xor 30H = S
k xor 30H = [
e xor 30H = U
r xor 30H = B
As que el serial que generamos es sBQS[UB, para el nombre Cracker. Por supuesto que los
clculos que se realizan son a nivel bit, pero nosotros solo lo vemos con los valores ASCII de
cada carcter. Por ejemplo, cuando xorea C con 30H, en realidad est haciendo 43H xor 30H (el
30H es el valor ASCII del nmero 0).
Luego tomaremos el serial y haremos lo mismo, pero con otro valor:
0 xor 29H = 19h
1 xor 29H = 18h
2 xor 29H = 1Bh
3 xor 29H = 1Ah
4 xor 29H = 1Dh
5 xor 29H = 1Ch
He puesto los valores hexadecimales dado que genera caracteres raros como flechas de direccin y
otras cosas que las pueden ver con el Olly, y si lo copian al clipboard, vern esto:

Raro, no?.
En esto deben tener cuidado, es decir, cuando generan un serial deben tener bien en claro las
operaciones que realizan porque muchas veces, si no prestamos atencin, se llegan a generar cosas
muy raras. Por eso hay que poner lmites y hacer algunas comprobaciones. En fin, sigamos...
Ya tenemos el serial verdadero, generado a partir del nombre, y un nuevo serial generado a partir
del serial que introdujo el usuario. Ahora, xorearemos el serial vlido (con el mismo valor con el
que generamos el segundo serial) y lo compararemos con el otro serial.

reversing_ar@yahoo.com.ar

http://www.joe-cracker.tk/ncr.htm

Tutorial n 34 by +NCR/CRC! [ReVeRsEr]


Si xoreamos el serial vlido con 29h, obtenemos:
S xor 29h = Z (5Ah)
B xor 29h = k (6Bh)
Q xor 29h = x (78h)
S xor 29h = z (7Ah)
[ xor 29h = r (72h)
U xor 29h = | (7Ch)
B xor 29h =k (6Bh)
Si comparamos carcter a carcter con el segundo serial, vemos que no son iguales, por lo tanto no
hemos introducido un serial vlido, en cambio, si hubiramos metido este mismo serial hubiramos
obtenido el mismo serial, xoreado con 29h, que se genera con el segundo serial, se entiende ?, es un
poco lioso, je. Veamos:
Con el nombre Cracker, generamos el serial sBQS[UB. Con el serial invalido generamos el serial
(cuyos valores hexa son 19 18 1B 1A 1D 1C). Si a los dos seriales generados, los xoreamos con
29h, no dan el mismo resultado, en cambio:
Metemos como nombre Cracker y obtenemos sBQS[UB, al xorear este serial con 29h tenemos un
nuevo serial que es : Zkxzr|k. Bien hasta aqu, no?.
Bueno, supongamos que tenemos mucha suerte y metimos como serial sBQS[UB, justo el vlido
para el nombre que metimos, pues al xorearlo con 29h tendremos Zkxzr|k. Pues si comparamos este
serial con el anterior veremos que son iguales, por lo que ese ser el momento en que daremos el
mensaje de felicitaciones .
Como pueden ver, la operacin xor es una especie de encriptacin, una muy sencilla, pero que, bien
implementada, puede llegar a complicarnos un poco la vida, je.
Les agrego algo que dice Caos Reptante en su tut sobre ASM para ver si aclara las cosas:
XOR: El resultado es 1 si uno y slo uno de los dos operandos es 1, y 0 en cualquier otro caso
1 xor 1 = 0
1 xor 0 = 1
0 xor 1 = 1
0 xor 0 = 0
Ejemplo: 1011 xor 0110 = 1101
Bien, un amigo paraguayo nos dice esto:
XOR
O exclusivo lgico sobre bits: Esta instruccin realiza un XOR lgico de los operandos y almacena
el resultado en el operando de destino. Cada bit del byte o palabra resultante se pone en 1 solo si el
bit correspondiente de cada operando contiene valores opuestos.

reversing_ar@yahoo.com.ar

http://www.joe-cracker.tk/ncr.htm

Tutorial n 34 by +NCR/CRC! [ReVeRsEr]


Por ltimo, agrego algo de lo que dice el amigo BlackFenix sobre el tema:

a encriptacin de datos es una de las mejores tcnicas que podemos utilizar para proteger nuestras
aplicaciones de los eventuales crackers. La encriptacin XOR es uno de los mtodos ms sencillos que
existen, su rapidez y fcil implementacin la hacen ideal para los creadores de virus y para cualquiera que
desee implementar un sencillo mtodo de encriptacin.
La encriptacin XOR (exclusive OR) se basa en la propiedad lgica de dicha operacin.
Cojamos dos valores 25h y 63h en binario:
00100101 -> 25h
01100011 -> 63h
Segn el funcionamiento de la operacin lgica XOR, los bits del primer operando que sean iguales a los del
segundo, resultaran en 0 (false) y el resto de bits en 1 (true) por lo tanto si realizamos el XOR de 25h con
63h obtendremos:
01000110 -> 46h
Como podemos comprobar se cumple la lgica de esta instruccin. Si ahora cogemos este valor y volvemos
a realizar un XOR con 63h.
01000110 -> 46h
XOR
01100011 -> 63h
obtendremos
00100101 -> 25h
! El dato original !, Esta es la base de la encriptacin XOR, pongamos ahora un ejemplo genrico.
Si tenemos un dato A que deseamos encriptar y una llave de encriptacin B, efectuaremos una operacin
XOR tal que as:
A XOR B = C
donde C ser el valor encriptado. Si sustituimos las variables por datos:
25h XOR 63h = 46h
A = 25h
B = 63h
C = 46h
Posteriormente para recuperar el dato encriptado (A) haremos:
C XOR B = A
que usando los anteriores valores queda
46h XOR 63h = 25h
En este ejemplo se ha utilizado una llave (B) de 8 bits, el tamao de la llave puede ser ms grande 16,32 o
ms bits, si la llave es ms grande, mayor seguridad, ya que hay ms llaves posibles. Aqu tienes un
resumen de las posibles combinaciones posibles segn el tamao de la llave.
Para una llave de 8bits tenemos un total de 256 = 2^8 llaves diferentes
Para una llave de 16bits tenemos un total de 65535 2^16 = llaves diferentes
Para una llave de 32bits tenemos un total de 4294967295 = 2^32 llaves diferentes.
Para una llave de 64bits tenemos un total de 18446744073709551616 = 2^64 llaves diferentes.
Para una llave de 128 bits tenemos 3.4028236692093846346337460743177e+38 = 2^128 llaves diferentes.

reversing_ar@yahoo.com.ar

http://www.joe-cracker.tk/ncr.htm

Tutorial n 34 by +NCR/CRC! [ReVeRsEr]


Hay que tener en cuenta esto si vamos a implementar una proteccin que utilice encriptacin, ya que si se
intenta un ataque por fuerza bruta sobre nuestra encriptacin y nuestra llave es de 8 bits, el tiempo
necesario para conseguir una llave vlida ser muy inferior que si por el contrario nuestra llave es de 32bits
o superior. Todo esto no sirve de mucho si no se toman las medidas necesarias para ocultar la llave, para
que me entiendas, no sirve de nada tener una super-puerta de seguridad anti-robo y a prueba de bombas y
todo lo que tu quieras si nos dejamos la llave debajo del felpudo. Por lo tanto deberemos ocultar nuestra
preciada llave de cualquier ladrn :-). Un ltimo comentario, en la encriptacin XOR siempre podemos
encontrar la llave si tenemos los datos encriptados y los datos sin encriptar con un simple XOR de ambos
valores:
B = A xor C
46h = 25h XOR 63h
Para encriptar un bloque de datos en assembler de 32 bits haramos algo as:
....
....
mov esi,Original_Data_Ptr // carga puntero al buffer a encriptar
mov edi,Crypted_Data_Ptr // carga puntero al buffer donde guarda los datos
mov ecx,Data_Length // carga longitud del buffer a encriptar
or ecx,ecx // comprueba si es 0
jz @NoEncrypt // si es 0 no encripta
mov al,XORKey // carga la llave XOR en AL
@NextByte:
mov ah,byte ptr [esi] // lee byte a encriptar
xor ah,al // encripta
mov byte ptr [edi],ah // y guarda buffer destino
inc esi // pasa al siguiente byte del buffer
inc edi // pasa al siguiente byte del buffer
dec ecx // decrementa contador de bytes encriptados
jnz @NextByte // continua si an quedan ms
@NoEncrypt:
....
....
en 16 bits seri:
....
....
les si,Original_Data_Ptr
lds di,Crypted_Data_Ptr
mov cx,Data_Length
or cx,cx
jz @NoEncrypt
mov al,XORKey
@NextByte:
mov ah, byte ptr es:[si]
xor ah,al
mov byte ptr ds:[di],ah
inc si
inc di
dec cx
jnz @NextByte
@NoEncrypt:
....
....
La desencriptacin se realizara de la misma manera pero pasando en Original_Data_Ptr el buffer
encriptado y en Crypted_Data_Ptr el buffer donde desencriptar. Esta es una de las ventajas de la
encriptacin XOR, no hace falta escribir otra funcin que desencripte, ya que se puede utilizar la misma. Por

reversing_ar@yahoo.com.ar

http://www.joe-cracker.tk/ncr.htm

Tutorial n 34 by +NCR/CRC! [ReVeRsEr]


eso muchos virus utilizan este tipo de encriptacin: ocupa poco espacio, es rpida y sirve tanto para
encriptar como para desencriptar.

Bueno, una vez digerida esa info, vamos a tratar de pasar la primer idea del crackme a un lenguaje
de programacin como es ASM.
Primero pongo el cdigo con algunos comentarios y luego lo explico:
DlgProc proc hWin:HWND,uMsg:UINT,wParam:WPARAM,lParam:LPARAM
mov
eax,uMsg
.if eax==WM_INITDIALOG
invoke LoadIcon,hInstance,500
mov hIcon,eax
invoke SendMessage,hWin,WM_SETICON,NULL,hIcon
;###############################################################################
Todo eso es respecto del cono, si quieren miren el tut de Daniel (La Calavera) que explica bien
todo eso.
;###############################################################################
.elseif eax==WM_COMMAND
mov eax,wParam
.if eax==1005 ;Si presionamos About nos muestra un mensaje
invoke MessageBox,hWin,offset men,offset tit,MB_ICONINFORMATION
.elseif eax==1006 ;Si presionamos Salir, salimos del programa
invoke EndDialog,hWin,0
.elseif eax==1004 ;Si presionamos OK comienza a generarse el serial
invoke GetDlgItemText,hWin,1003,ADDR nombre,10 ;Tomamos el nombre
.if eax==6 ;Si tiene seis caracteres
invoke GetDlgItemText,hWin,1007,ADDR serial,10 ;Tomamos el serial
.if eax==6 ;Si tiene seis caracteres
call generar ;Realizamos los clculos
.endif ;Terminamos el clculo
.if flag==1 ;Si el flag vale 1, felicitaciones
invoke MessageBox,hWin,offset men2,offset tit2,MB_ICONINFORMATION
mov [flag],0 ;Limpiamos el flag
.endif
.endif
.elseif eax==1002 ; Si presionamos en la imagen nos da otro mensaje
invoke MessageBox,hWin,offset men3,offset tit3,MB_ICONINFORMATION
.endif
Bueno, los primeros MsgBox son los mensajes de agradecimiento y alguna que otra cosa ms, pero
nada que se relacione con el clculo del serial. Luego si viene lo que importa:
.elseif eax==1004 ;Si presionamos OK comienza a generarse el serial
invoke GetDlgItemText,hWin,1003,ADDR nombre,10 ;Tomamos el nombre
.if eax==6 ;Si tiene seis caracteres
invoke GetDlgItemText,hWin,1007,ADDR serial,10 ;Tomamos el serial
.if eax==6 ;Si tiene seis caracteres
call generar ;Realizamos los clculos
.endif ;Terminamos el clculo
reversing_ar@yahoo.com.ar

http://www.joe-cracker.tk/ncr.htm

Tutorial n 34 by +NCR/CRC! [ReVeRsEr]


.if flag==1 ;Si el flag vale 1, felicitaciones
invoke MessageBox,hWin,offset men2,offset tit2,MB_ICONINFORMATION
mov [flag],0 ;Limpiamos el flag
.endif
.endif
En esa parte, si presionamos el botn cuyo ID es 1004, tomaremos en primera instancia, el nombre
que esta en el edit con la funcin GetDlgItemText y lo almacenaremnos en una variable llamada
nombre. Luego, yo decid que si el nombre tena seis caracteres segua haciendo las dems cosas,
sino, no hace nada. Si el nombre tiene seis caracteres, tomamos el serial que esta en el edit cuyo ID
es 1007 y lo guardamos en la variable serial. Ahora, volvemos a verificar si el serial tiene 6
caracteres, en caso afirmativo, llamaremos a la funcin encargada de generar el serial, sino chao!!!.
Si hemos metido el nombre y el serial con seis caracteres, pasaremos a esta parte:
DlgProc endp
generar:
xor eax,eax ;Limpiamos los registros
xor ebx,ebx
xor edx,edx
bucle: ;Inicia el bucle
.if ebx==6 ;Si EBX es igual a seis, salta al segundo bucle, sino...
jmp bucle2
.endif
mov al,byte ptr ds:[nombre+ebx] ;Mueve el primer carcter del nombre
.if al>=41H && al<=5AH ;Es una letra mayscula?
inc edx ;Inccrementa EDX
.elseif ;Si no es una letra mayscula....
.if al>=61H && al<=7AH ;Es una letra minscula?
inc edx ;Incrementa EDX
.endif
.endif
inc ebx ;Inccrementa EBX para tomar el segundo caracter
jmp bucle ;Vuelve a repetir el bucle
bucle2: ;Inicio del segundo bucle
.if edx==6 ;Si EDX se ha incrementado seis veces, lo ejecuta, sino chao!!!
xor eax,eax ;Limpiamos los registros que vamos a utilizar
xor ebx,ebx
xor ecx,ecx
sBucle: ;Inicio del bucle
.if ebx==6 ;Si EBX es igual a seis, salta al tercer bucle, sino...
jmp bucle3
.endif
mov al,byte ptr ds:[nombre+ebx] ;Toma el primer carcter del nombre
xor al,30H ;Lo xorea con 30H
xor al,29H ;Luego lo vuelve a xorear con 29H
mov byte ptr ds:[key+ebx],al ;Mueve el carcter xoreado a la variable key+ebx
inc ebx ;Incrementa EBX para tomar el siguiente caracter
jmp sBucle ;Vuelve a ejecutar el bucle

reversing_ar@yahoo.com.ar

http://www.joe-cracker.tk/ncr.htm

Tutorial n 34 by +NCR/CRC! [ReVeRsEr]


bucle3: ;Inicia un nuevo bucle
xor eax,eax ;Volvemos a limpiar los registros
xor ebx,ebx
xor ecx,ecx
sBucle3: ;Ahora comienza realmente el bucle, je
.if eax==6 ;Si EAX es igual a seis, saltamos al cuarto bucle, sino...
jmp bucle4
.endif
mov bl,byte ptr ds:[serial+eax] ;Movemos el primer carcter del serial
xor bl,29H ;Lo xoreamos con 29H
mov byte ptr ds:[key2+eax],bl ;Lo guardamos en una segunda variable Key2
inc eax ;Incrementamos el contador para tomar el siguiente caracter
jmp sBucle3 ;Volvemos a ejecutar el bucle
bucle4: ;Inicia el bucle 4
xor eax,eax ;Por cuarta vez, volvemos a limpiar los registros
xor ebx,ebx
xor ecx,ecx
xor edx,edx
sBucle4:
.if ecx==6 ;Si el contador ha llegado a seis...
jmp final ;Saltamos al final, sino...
.endif
mov al,byte ptr ds:[key+ecx] ;Movemos a AL el primer carcter del serial vlido
mov bl,byte ptr ds:[key2+ecx] ;Movemos a BL el primer carcter del serial invlido
.if al==bl ;Los comparamos, si son iguales...
inc edx ;Incrementamos EDX
.endif
inc ecx ;Incrementamos la variable de control para tomar los siguientes caracteres
jmp sBucle4 ;Volvemos a ejecutar el bucle
final: ;El final...
.if edx==6 ;Si EDX se ha incrementado seis veces...
mov [flag],1 ;Movemos un 1 a la variable flag, sino....
.endif ;Chao!!!
.endif
ret
end start
Yo siempre declaro las funciones debajo del DlgProc endp, pero podramos haberlo puesto debajo
de la segunda llamada a GetDlgItemText, sin poner la llamada, por supuesto.
Bien, vamos a tratar de explicar lo que hemos hecho.
Primeramente, nos fijamos si los caracteres que contiene el nombre que se ha introducido son letras
maysculas o minsculas, en cualquiera de los casos, incrementamos un contador secundario
(EDX). Una vez que hemos tomado todos los caracteres del nombre y hemos realizado las
comparaciones, el contador que controla el bucle abra llegado a tener la misma cantidad de
caracteres del nombre, por lo que el salto luego de la comparacin se ejecutar y pasaremos a la
segunda parte.

reversing_ar@yahoo.com.ar

http://www.joe-cracker.tk/ncr.htm

Tutorial n 34 by +NCR/CRC! [ReVeRsEr]


En esta segunda parte, primero nos fijamos si EDX, del bucle anterior, ha llegado a seis, si es as,
quiere decir que todos los caracteres han sido letras maysculas, minsculas o una mezcla de las
dos. Aclaro que yo en esta ocasin he decidido trabajar solo con seis caracteres en el nombre y seis
en el serial, pero podramos haber trabajado con la cantidad que quisiramos, y en lugar de que la
condicin sea EDX==6, podramos haber tomado el largo de la cadena del nombre con la funcin
lstrlenA y almacenarla en una variable Largo y poner EDX==largo. Es cuestin de gustos y ganas
de trabajar, je....yo tena ganas de dormir la siesta, jejeje.
Bien, si EDX es igual a 6, lo que vamos haciendo es tomando los caracteres del nombre y los vamos
xoreando primero con 30h y luego con 29h y lo almacenamos en una variable llamada key. Lo
que yo pongo como key+ebx es para ir incrementando lugares en la variable y no sobreescribir
siempre el mismo carcter. Un ejemplo y seguimos:
Por ejemplo, primero el contador ebx vale 0, por lo que el primer carcter lo almacenaremos en la
primer posicin de la variable key, una vez que se incremente el contador, EBX==1, pasaremos a
guardar el segundo carcter del nombre el la segunda posicin de la variable key. Fijense que si no
hacemos esto estaramos reescribiendo el primer carcter del nombre.
Bueno, una vez que hemos tomado todos los caracteres del nombre y los hemos xoreado con los
valores esos, saltamos al tercer bucle. Este es parecido al anterior, lo que vamos haciendo es
tomando lo caracteres del serial, sean lo que sean, y lo xoreamos con 29H y los vamos almacenando
en una variable key2. Cuando llegamos a tomar todos los caracteres del serial introducido, saltamos
a la ltima parte.
En esta ltima parte, vamos tomando los caracteres del serial vlido y del serial invlido y los
vamos comparando, si son iguales, incrementamos un contador secundario (EDX). Una vez que
tomamos todos los caracteres y realizamos las comparaciones, llega el momento de verificar si el
serial es vlido. Para esto he utilizado una de la formas ms estpidas que hay, pero que sirve. Por
supuesto que esto es un clculo sencillo y la comparacin es estpida, o sea que se compensan una
cosa con la otra, jeje, pero no se les ocurra matarse haciendo un clculo monstruoso del serial,
encriptando datos, y haciendo lo que su mente les diga, y luego estropear todo ese gran esfuerzo con
una comparacin fcil de saltar como esta, porque el esfuerzo no habr servido para nada y la
aplicacin se podr registrar en 2 segundos.
Bien, si el contador ha llegado a seis, quiere decir que todas las comparaciones han sido exitosas,
eso quiere decir que el serial es vlido, por lo tanto metemos un 1 en la variable flag. Y a la vuelta
de la llamada comprobamos si el flag es igual a 1, en cuyo caso daremos las felicitaciones, sino no
emitiremos ningn mensaje y el pobre chico no sabr que pas, je (tampoco se les ocurra hacer este
tipo de comparaciones a la salida de un call, busquen algo ms sutil y que llame menos la atencin
de mentes inquietas, je).
Por ltimo, una cosa que era muy sencilla, pero que me tuvo dando algunas vueltas en su momento.
El tema del flag, si hemos metido un serial vlido, el flag pasa a valer 1 y nos dan las gracias, pero
si luego volvemos a meter el mismo nombre y otro serial, vemos que nos vuelve a dar las gracias,
esto se debe a que el flag sigue puesto a 1, por lo que debemos resetearlo, es decir ponerlo a 0, es
por eso que al final de la llamada a la MsgBox de felicitaciones he agregado:
mov [flag],0 ;Limpiamos el flag

reversing_ar@yahoo.com.ar

http://www.joe-cracker.tk/ncr.htm

10

Tutorial n 34 by +NCR/CRC! [ReVeRsEr]


Bien, ahora nos falta declarar las variables en el *.inc, yo las he dejado as:
.data?
hInstance dd ?
hIcon dd ?
.data
men2 db "Los has logrado!!!",0
tit2 db "Felicitaciones!!!",0
tit3 db "KeyGenMe v4.0 by +NCR",0
men3 db "Gracias a Pr@fesorX por disearme el logo!!!",10,13,10,13
db "Verdad que es bonito? :-)",10,13,10,13
db "--<Mientras + ganas + conocimientos",10,13
db "mientras + conocimientos - lmites>--",0
tit db "About",0
men db "--< Coded by +NCR/CRC! [ReVeRsEr] >--",10,13,10,13
db " reversing_ar@yahoo.com.ar",10,13,10,13
db "Visita www.crackslatinos.hispadominio.net",10,13
db "
www.iespana.es/OllyDBG/NCR.htm",10,13
db "
http://www.joe-cracker.tk/ncr.htm",10,13,10,13
db " Saludos a los integrantes de CracksLatinos!!!",0
nombre dd 10 dup (0),0
serial dd 10 dup (0),0
flag dd 2 dup (0),0
key dd 7 dup (0),0
key2 dd 7 dup (0),0
Solo nos queda ensamblar con Ctrl+F5 y tendremos el programa corriendo. Ahora vamos a crear el
keygen para este crackme. Es muy sencillo...
Primero creamos un nuevo proyecto tal cual hicimos con el anterior y le agregamos dos edits y dos
botones, uno para generar el serial y el otro como About, yo voy a utilizar la funcin change para ir
generando el serial a medida vamos escribiendo el nombre. Esto ltimo est muy bien explicado en
la solucin del concurso 2 de ASM, el encargado fue el amigo RedH@wk (Saludos Red!!!).
Bien, una vez puestos todos los controles me queda as:

reversing_ar@yahoo.com.ar

http://www.joe-cracker.tk/ncr.htm

11

Tutorial n 34 by +NCR/CRC! [ReVeRsEr]


Este es el cdigo:
.elseif eax==WM_COMMAND
mov eax,wParam
mov edx,eax
shr edx,16
.if ax==1004
invoke GetDlgItemText,hWin,1004,ADDR nombre,30
.if eax!=0
call generar
invoke SetDlgItemText,hWin,1005,ADDR key
invoke lstrlen,offset nombre
xor ecx,ecx
lKey:
mov byte ptr ds:[key+ecx],0
inc ecx
.if ecx!=eax
jmp lkey
.endif
.endif
.elseif eax==1007
invoke MessageBoxEx,hWin,offset mensaje,offset titulo,MB_ICONINFORMATION,0
.endif
Como vern ,esto es parecido a lo que hicimos antes vamos tomando los caracteres del nombre y los
almacenamos en una variable llamada nombre, luego llamamos a la funcin que genera el serial y
por ltimo mostramos los resultados del serial generado con la funcin SetDlgItemText. Lo que est
debajo de la llamada a SetDlgItemText:

Es para limpiar le variable en donde tenemos guardado el serial generado anteriormente. Hago esto
porque tuve el problema de que si meta un nombre y luego daba a generar me sala su
correspondiente serial, pero si luego meta otro nombre y le daba a generar, siguen estando
algunos caracteres del serial anterior y por lo tanto se juntan con el nuevo y eso no est bien, por lo
tanto busque una manera de solucionar ese problema y sali esto. Creo que haba otra manera ms
sencilla de hacer esto, pero no recuerdo cual.....si alguien se acuerda que me diga porque me tiene
bastante intrigado, as que si puede escribir a la lista o a mi privado y contarme como es, se lo
agradecera.

Bien, ahora pasemos a generar el serial:

reversing_ar@yahoo.com.ar

http://www.joe-cracker.tk/ncr.htm

12

Tutorial n 34 by +NCR/CRC! [ReVeRsEr]

generar:
invoke lstrlen,offset nombre ;Tomamos la longitud del nombre
mov [largo],eax ;Movemos el largo de la cadena a la variable largo
xor eax,eax ;Ponemos EAX==0
xor ecx,ecx ;Ponemos ECX==0
sBucle: ;Inicia el bucle
.if ecx==largo ;Si el largo de la cadena es igual al contador...
jmp final ;saltamos al final
.endif
mov al, byte ptr ds:[nombre+ecx] ;Tomamos el primer carcter del nombre
xor al,30H ;Lo xoreamos con 30h
mov byte ptr ds:[key+ecx],al ;Movemos el resultado a la variable key
inc ecx ;Incrementamos el contador
jmp sBucle ;Volvemos al inicio del bucle
final:
ret ;Volvemos de la llamada
Y las variables han quedado de esta forma:
nombre dd 30 dup (?)
largo dd ?
key dd 30 dup (?)
Muy sencillo, no tiene nada de raro. En el crackme, habamos xoreado, primero, los caracteres del
nombre con 30h (con eso generamos el serial vlido) y luego con 29h, pero eso es solo para realizar
las comparaciones, tal vez sea una forma de despistar a los muy newbies (a un cracker avanzado no
le hace ni cosquillas, je), as que lo nico que debemos hacer es xorear a cada carcter del nombre
con 30h y mostrar el resultado.
Si se fijan, en el crackme habamos establecido que el nombre y serial, tenan que tener si o s seis
caracteres para poder realizar las operaciones, pero aqu no tenemos esa condicin, sino que
mientras le metamos letras, nos generar un serial.
Despedida
Creo que este es el final del tut. Espero que les haya gustado. Si tienen alguna queja, comentario,
duda, lo que sea, escriban a reversing_ar@yahoo.com.ar
Agradecimientos
Es tanta gente a la que le tengo que agradecer que no me alcanzara todo el tut, je: Ricardo Narvaja,
RedH@wk, Pr@fesorX, Daniel, Odraude, Shadow&Dark, Morales (Gracias por aclararme el tema
del SEH), COCO, Yllera, Juan Jos, Joe Cracker (Gracias por la encomienda ), Flipi, AkirA
(lstima que te has retirado ), KaoD (Gracias por ser el beta-tester, je), DeGeTe, _Primax y por
supuesto a los dems integrantes de la lista.
+NCR/CRC! [ReVeRsEr]
Julio de 2004

reversing_ar@yahoo.com.ar

http://www.joe-cracker.tk/ncr.htm

13

También podría gustarte