Está en la página 1de 10

CrackME2 – Yllera by +NCR/CRC!

[ReVeRsEr]

Programa CrackME 2 - Yllera


Download http://usuarios.lycos.es/crackmes/
Descripción Crackme
Herramientas OllyDBG 1.10 - RadASM
Dificultad Newbie
Compresor/Compilador MASM32 / TASM32
Protección Serial / Name
Objetivos Conseguir el serial – Hacer el KeyGen
Cracker +NCR Fecha: 04/08/04
Tutorial nº 42

Introducción

Bienvenidos otra vez a un nuevo tut...!!!. Esta vez con un nuevo crackme de mi amigo
Yllera. Cada día vamos mejorando en esto del ASM y este crackme es prueba de ello.

Como en el tut del carckme anterior, intentaremos conseguir el serial válido para
nuestro nombre y luego hacer el KeyGen.

Vayamos a ver que nos trae de nuevo este crackme.....

Comezemos

Ni bien arrancamos el crackme vemos esto:

Una interfaz muy mejorada respecto el crackme anterior,te quedo muy bonita Yllera XD

reversing_ar@yahoo.com.ar http://www.joe-cracker.tk/ncr.htm 1
CrackME2 – Yllera by +NCR/CRC! [ReVeRsEr]

Bueno, metamos un nombre cualquiera y un serial cualquiera. Yo he elegido como


nombre ReVeRsEr y como serial 45561223.

Le damos a aceptar y .....nada....esta vez no ha mensaje de error ni nada...je, se ve que


nos quiere complicar un poco más el trabajo. Miremos este programa en Olly.

Ni bien los abrimos vemos:

Ya sabemos que este es el EP (EntryPoint) del programa. Pero como vamos a conseguir
romper el programa para conseguir el serial. Pues bueno, hay varios caminos que
podemos seguir:

1- Poner un bp en el Punto H y seguir el procedimiento de este método.


2- Poner un bp en las apis que sabemos sirven para tomar nombre y serial y seguirle el
rastro a ver que hace con él.
3- Lo que hago yo siempre que trato con crackme que no tienen mucho código:

Cuando se trata de crackmes de este estilo, con poco código, cosa que no quiere decir
que sea fácil, al contrario, he tratado con crackmes como el de Enforcer o el de
eSn mIn que son bastante cortos pero que son terribles para crackear, sino mirenlos y
luego me cuentan, je.

Bien, lo que hago es recorrer el código de punta a punta tratando de encontrar o


descubrir las posibles partes del código que sean interesantes para poner un bp. Puede
ser un trabajo pesado en algunas ocasiones, pero yo me dejo llevar por la intuición, a
veces tengo razón y a vaces no, XD.

Tenemos suerte, porque hay solo dos llamadas a GetDlgItemTextA, y sabemos que esta
es la api que habitualmente se usa para tomar los datos el nombre y serial.

La parte en la que toma nombre y serial es esta:

004010EA . 6A 40 PUSH 40 ; /Count = 40 (64.)


004010EC . 68 38344000 PUSH CrackM E2.00403438 ; |Buffer = CrackM E2.00403438
004010F1 . 68 EC030000 PUSH 3EC ; |ControlID = 3EC (1004.)
004010F6 . FF75 08 PUSH DWORD PTR SS:[EBP+8] ; |hWnd
004010F9 . E8 E4030000 CALL <JM P.&user32.GetDlgItemTextA> ; \GetDlgItemTextA
004010FE . 6A 40 PUSH 40 ; /Count = 40 (64.)
00401100 . 68 7C324000 PUSH CrackM E2.0040327C ; |Buffer = CrackM E2.0040327C
00401105 . 68 ED030000 PUSH 3ED ; |ControlID = 3ED (1005.)
0040110A . FF75 08 PUSH DWORD PTR SS:[EBP+8] ; |hWnd
0040110D . E8 D0030000 CALL <JM P.&user32.GetDlgItemTextA> ; \GetDlgItemTextA
00401112 . 68 7C324000 PUSH CrackM E2.0040327C ; /String = "45561223"
00401117 . E8 AE030000 CALL <JM P.&kernel32.lstrlenA> ; \lstrlenA
0040111C . 0BC0 OR EAX,EAX
0040111E . 75 02 JNZ SHORT CrackM E2.00401122
00401120 ^ EB C1 JM P SHORT CrackM E2.004010E3
00401122 > E8 67000000 CALL CrackM E2.0040118E

reversing_ar@yahoo.com.ar http://www.joe-cracker.tk/ncr.htm 2
CrackME2 – Yllera by +NCR/CRC! [ReVeRsEr]

Ahí podemos observar las dos llamadas a GetDlgItemTextA. La primer llamada es para
tomar el nombre y la segunda para tomar el serial. Luego de la segunda llamada a
GetDlgItemTextA viene una llamada a lstrlenA que se utiliza para tomar la longitud del
serial. Si la longitud es cero (0), quiere decir que no hay ninguna cadena en la EditText,
por lo tanto no llamara a la rutina de generación del serial que está en [401122], en
cambio si hay algo escrito en dicho Edit, procederá a generar el serial.

Nota: como una vez me dijo ‘KoaD, no hace falta tomar la longitud del serial
nuevamente dado que en la llamada a GetDlgItemTextA ya se toma una vez y queda
en EAX. Por lo tanto se podría hace de esta manera:

invoke GetDlgItemText,hWin,1003,ADDR nombre,30


.if eax!=0
call GenSerial
.endif

Pero uno por costumbre siempre lo hace, o por lo menos a mi me pasa. En fin
...sigamos.

Hemos metido nombre y serial, por lo tanto entraremos en la llamada y veremos esto:
0040118E $ C705 20344000>M OV DWORD PTR DS:[403420],0 ;M ueve un cero a una variable
00401198 . 33C0 XOR EAX,EAX ;Limpia EAX
0040119A . 33DB XOR EBX,EBX ;Limpia EBX
0040119C . 33C9 XOR ECX,ECX ;Limpia ECX
0040119E . A1 38344000 M OV EAX,DWORD PTR DS:[403438] ;M ueve el nombre a EAX
004011A3 > 8A81 38344000 M OV AL,BYTE PTR DS:[ECX+403438] ;Toma un carácter del nombre
004011A9 . 0AC0 OR AL,AL ;M ientars haya caracteres...
004011AB . 75 08 JNZ SHORT CrackM E2.004011B5 ;Va a la segunda comprobación
004011AD . 890D 8C344000 M OV DWORD PTR DS:[40348C],ECX ;M ueve a una varible el contador del bucle.
004011B3 . EB 07 JM P SHORT CrackM E2.004011BC
004011B5 > 0AC0 OR AL,AL ;Como no es el último carácter, incrementamos el contador para tomar el
siguiente carácter
004011B7 . 74 03 JE SHORT CrackM E2.004011BC
004011B9 . 41 INC ECX ;Incrementa el contador
004011BA .^ EB E7 JM P SHORT CrackM E2.004011A3 ;Vuelve al inicio del bucle

Bueno, sin mucha vuelta, lo que hace acá es contar la cantidad de caracteres del nombre
incrementando un contador. Una vez que ha terminado con todos los caracteres, mueve
el contador, en este caso ECX, a una variable.

Una vez que hemos pasado eso seguimos por esta parte:

004011BC > \33C0 XOR EAX,EAX ;Vuleve a lipiar los registros que utiliza en la rutina
004011BE . 33DB XOR EBX,EBX
004011C0 . 33C9 XOR ECX,ECX
004011C2 . A1 38344000 M OV EAX,DWORD PTR DS:[403438] ;Otra vez mueve el nombre a EAX
004011C7 > 8A81 38344000 M OV AL,BYTE PTR DS:[ECX+403438] ;Va tomando de a un caracter
004011CD . 8B1D 8C344000 M OV EBX,DWORD PTR DS:[40348C] ;M ueve la cantidad de caracteres del
nombre a EBX
004011D3 . 3BCB CM P ECX,EBX ;Se fija si ha tomado el último carácter....
004011D5 . 75 06 JNZ SHORT CrackM E2.004011DD ;Si no es el último..salta a generar el primer serial
004011D7 . E8 C5000000 CALL CrackM E2.004012A1 ;Llamada a la segunda parte de la generacion del serial
004011DC . C3 RETN ;Vuelve de la llamada anterior
004011DD > 3C 2F CM P AL,2F ; Switch (cases 0..F1) ;Aquí comienza con las
comparaciones ......
004011DF . 77 0C JA SHORT CrackM E2.004011ED

reversing_ar@yahoo.com.ar http://www.joe-cracker.tk/ncr.htm 3
CrackME2 – Yllera by +NCR/CRC! [ReVeRsEr]

004011E1 . B8 31000000 M OV EAX,31 ; Cases


0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F,10,11,12,13,14,15,16,17,18,19,1A,1B,1C,1D,1E,1F,20,21,22,23,24,25,26,27,28,29,2
A,2B,2C,2D,2E,2F of switch 004011DD
004011E6 . E8 AA000000 CALL CrackM E2.00401295
004011EB .^ EB DA JM P SHORT CrackM E2.004011C7
004011ED > 3C 40 CM P AL,40
004011EF . 77 07 JA SHORT CrackM E2.004011F8
004011F1 . E8 9F000000 CALL CrackM E2.00401295 ; Cases
30,31,32,33,34,35,36,37,38,39,3A,3B,3C,3D,3E,3F,40 of switch 004011DD
004011F6 .^ EB CF JM P SHORT CrackM E2.004011C7
004011F8 > 3C 49 CM P AL,49
004011FA . 77 09 JA SHORT CrackM E2.00401205
004011FC . 2C 10 SUB AL,10 ; Cases 41,42,43,44,45,46,47,48,49 of switch 004011DD
004011FE . E8 92000000 CALL CrackM E2.00401295
00401203 .^ EB C2 JM P SHORT CrackM E2.004011C7
00401205 > 3C 52 CM P AL,52
00401207 . 77 09 JA SHORT CrackM E2.00401212
00401209 . 2C 19 SUB AL,19 ; Cases 4A,4B,4C,4D,4E,4F,50,51,52 of switch 004011DD
0040120B . E8 85000000 CALL CrackM E2.00401295
00401210 .^ EB B5 JM P SHORT CrackM E2.004011C7
00401212 > 3C 5A CM P AL,5A
00401214 . 77 09 JA SHORT CrackM E2.0040121F
00401216 . 2C 22 SUB AL,22 ; Cases 53,54,55,56,57,58,59,5A of switch 004011DD
00401218 . E8 78000000 CALL CrackM E2.00401295
0040121D .^ EB A8 JM P SHORT CrackM E2.004011C7
0040121F > 3C 60 CM P AL,60
00401221 . 77 0C JA SHORT CrackM E2.0040122F
00401223 . B8 33000000 M OV EAX,33 ; Cases 5B,5C,5D,5E,5F,60 of switch 004011DD
00401228 . E8 68000000 CALL CrackM E2.00401295
0040122D .^ EB 98 JM P SHORT CrackM E2.004011C7
0040122F > 3C 69 CM P AL,69
00401231 . 77 09 JA SHORT CrackM E2.0040123C
00401233 . 2C 30 SUB AL,30 ; Cases 61,62,63,64,65,66,67,68,69 of switch 004011DD
00401235 . E8 5B000000 CALL CrackM E2.00401295
0040123A .^ EB 8B JM P SHORT CrackM E2.004011C7
0040123C > 3C 72 CM P AL,72
0040123E . 77 0C JA SHORT CrackM E2.0040124C
00401240 . 2C 39 SUB AL,39 ; Cases 6A,6B,6C,6D,6E,6F,70,71,72 of switch 004011DD
00401242 . E8 4E000000 CALL CrackM E2.00401295
00401247 .^ E9 7BFFFFFF JM P CrackM E2.004011C7
0040124C > 3C D1 CM P AL,0D1
0040124E . 75 0C JNZ SHORT CrackM E2.0040125C
00401250 . B8 35000000 M OV EAX,35 ; Case D1 of switch 004011DD
00401255 . E8 3B000000 CALL CrackM E2.00401295
0040125A . EB 13 JM P SHORT CrackM E2.0040126F
0040125C > 3C F1 CM P AL,0F1
0040125E . 75 0F JNZ SHORT CrackM E2.0040126F
00401260 . B8 35000000 M OV EAX,35 ; Case F1 of switch 004011DD
00401265 . E8 2B000000 CALL CrackM E2.00401295
0040126A .^ E9 58FFFFFF JM P CrackM E2.004011C7
0040126F > 3C 7A CM P AL,7A ; Default case of switch 004011DD
00401271 . 77 0E JA SHORT CrackM E2.00401281
00401273 . 2C 41 SUB AL,41
00401275 . E8 1B000000 CALL CrackM E2.00401295
0040127A .^ E9 48FFFFFF JM P CrackM E2.004011C7
0040127F . EB 14 JM P SHORT CrackM E2.00401295
00401281 > 3C 7F CM P AL,7F
00401283 . 72 10 JB SHORT CrackM E2.00401295
00401285 . E8 00000000 CALL CrackM E2.0040128ª

Bien, vemos que esta parte es bastante fácil. Lo que es ir comparando cada carácter del
nombre con algunas constantes....voy a explicar algunas:

reversing_ar@yahoo.com.ar http://www.joe-cracker.tk/ncr.htm 4
CrackME2 – Yllera by +NCR/CRC! [ReVeRsEr]

Por ejemplo, la primera comparación es:

004011DD > \3C 2F CM P AL,2F ; Switch (cases 0..F1) ;El carácter es mayor o igual que 2Fh?.....
004011DF . 77 0C JA SHORT CrackM E2.004011ED ;Si es mayor o esta por encima de 2Fh, salta a la otra
comparación...sino....
004011E1 . B8 31000000 M OV EAX,31 ; Cases ;M ueve 31h (1 en decimal) a EAX
004011E6 . E8 AA000000 CALL CrackM E2.00401295 ;Llama a una rutina....

Otra de las comparaciones que hace es, al final de la rutina:


00401281 > \3C 7F CM P AL,7F ;Compara el carácter del nombre con 7Fh
00401283 . 72 10 JB SHORT CrackM E2.00401295 ;Si esta por debajo de este valor....
00401285 . E8 00000000 CALL CrackM E2.0040128ª ;Llama a otra rutina diferente....

Vemos que siempre hace este tipo de comparaciones...y que la rutina a la que está
llamando continuamente, salvo en la última comparación....es a [401295]. Si vemos que
hay en esa dirección, observamos esto:

00401295 /$ 33DB XOR EBX,EBX ;Limpia EBX


00401297 |. 8AD8 M OV BL,AL ;M ueve lo que haya en Al a Bl
00401299 |. 8999 CC334000 M OV DWORD PTR DS:[ECX+4033CC],EBX ;M ueve EBX a una variable en la cual
va guardando el serial
0040129F |. 41 INC ECX ;Incrementa el contador para seguir tomando caracteres
004012A0 \. C3 RETN ;Vuelve a la rutina

esta subrutina es sencilla, solo va guardando los caracteres finales (luego de hacer las
restas, en algunos casos) del serial en la variable que ha destinado para ello.

La otra rutina que está al final es la siguiente:

0040128A /$ C705 20344000>M OV DWORD PTR DS:[403420],1 ;M ueve un 1 a una variable


00401294 \. C3 RETN ;Vuelve a la rutina

Bueno, esto no se para que lo utiliza....veremos más adelante para que es útil o si es un
detalle menor que no influye demasiado.

Por que al inicio dije que con esto genera la primera parte del serial o el primer
serial?...pues porque este serial que genera no es el definitivo, sino que a partir de este
luego generara el serial definitivo y el que nos servirá para pasar todas las
comprobaciones.

Una vez que ha tomado todos los caracteres del serial, podemos hacer un Follow in
Dump en esta parte:

00401299 |. 8999 CC334000 M OV DWORD PTR DS:[ECX+4033CC],EBX

Y ver que es lo que ha dejado en esa variable:

Ahí podemos ver el primer serial que se genera a partir de nuestro nombre.

reversing_ar@yahoo.com.ar http://www.joe-cracker.tk/ncr.htm 5
CrackME2 – Yllera by +NCR/CRC! [ReVeRsEr]

Bien, pasada esta parte llegamos a esta otra:

004012A1 $ 33C0 XOR EAX,EAX ;Limpia los registros


004012A3 . 33DB XOR EBX,EBX
004012A5 . 33C9 XOR ECX,ECX
004012A7 . A1 CC334000 M OV EAX,DWORD PTR DS:[4033CC] ;M ueve el 1º serial generado a EAX
004012AC > 8A81 CC334000 M OV AL,BYTE PTR DS:[ECX+4033CC] ;Toma de a un carácter del serial
004012B2 . 8B1D 8C344000 M OV EBX,DWORD PTR DS:[40348C] ;Recupera la cantidad de caracteres del
nombre
004012B8 . 3BCB CM P ECX,EBX ;Se fija si ha llegado al último carácter del serial
004012BA . 75 06 JNZ SHORT CrackM E2.004012C2 ,Si no es el último....sigue con el bucle..sino...
004012BC . E8 1E000000 CALL CrackM E2.004012DF ;Llama a una rutina
004012C1 . C3 RETN ,Vuelve a la rutina anterior
004012C2 > 3C 32 CM P AL,32 ;Aca comeinza el bucle....compara Al con 32h (2 dec), si es mayor...
004012C4 . 77 04 JA SHORT CrackM E2.004012CA ;Salta a la segunda comparación..sino....
004012C6 . EB 0A JM P SHORT CrackM E2.004012D2 ;Se va a final del bucle
004012C8 . EB 06 JM P SHORT CrackM E2.004012D0
004012CA > 3C 33 CM P AL,33 ;Compara Al con 33h (3 dec), si es menor.....
004012CC . 72 02 JB SHORT CrackM E2.004012D0 ;Salta a la resta....sino
004012CE . EB 00 JM P SHORT CrackM E2.004012D0 ;Salta a la resta de todos modos ¿?
004012D0 > 2C 02 SUB AL,2 ;Le resta 2 a lo que haya en Al
004012D2 > 33DB XOR EBX,EBX ;Xorea EBX
004012D4 . 8AD8 M OV BL,AL ;M ueve lo que haya en Al a Bl
004012D6 . 8999 BC344000 M OV DWORD PTR DS:[ECX+4034BC],EBX ,M ueve EBX a una nueva variable, el
seerial definitivo
004012DC . 41 INC ECX ;Incrementa el contador para tomar el siguiente caracter
004012DD .^ EB CD JM P SHORT CrackM E2.004012AC ,Salta al inicio del bucle

Bien, básicamente, lo que hace acá es ir tomando uno a uno los caracteres del nombre y
los va comparando con dos contantes que son 2 y 3, hace su comparación y en base al
resultado tiene dos caminos para elegir:

1- Hacer la resta al carácter del 1º serial.


2- No hacer resta y dejar el carácter tal cual está.

Bien, si una vez que ha tomado todos los caracteres hacemos un Follow in Dump en
esta línea:

004012D6 . 8999 BC344000 M OV DWORD PTR DS:[ECX+4034BC],EBX

Veremos el serial definitivo en el dump:

Hasta acá ya tenemos para ahcer el KeyGen, luego repasaremos lo que hace y lo
programaremos. También tenemos realizada la tarea de conseguir el serial, por
supuesto, si ahora vamos con este numerito y lo ponemos en el edit del serial con el
mismo nombre que antes, veremos que nos da las gracias....pero sigamos a ver que hace
luego.

reversing_ar@yahoo.com.ar http://www.joe-cracker.tk/ncr.htm 6
CrackME2 – Yllera by +NCR/CRC! [ReVeRsEr]

Superada esta parte vamos a esta otra:

004012DF /$ 33C0 XOR EAX,EAX ;Limpia los registros


004012E1 |. 33DB XOR EBX,EBX
004012E3 |. 33C9 XOR ECX,ECX
004012E5 |. A1 7C324000 M OV EAX,DWORD PTR DS:[40327C] ,M ueve el serial falso a EAX
004012EA |> 8A81 7C324000 /M OV AL,BYTE PTR DS:[ECX+40327C] ;Toma de a un caracter
004012F0 |. 0AC0 |OR AL,AL ;Es el último carácter?...
004012F2 |. 75 08 |JNZ SHORT CrackM E2.004012FC ;Si no es el último salta a la otra comprobación..
004012F4 |. 890D A4344000 |M OV DWORD PTR DS:[4034A4],ECX ;M ueve el contador a una nueva variable
004012FA |. EB 07 |JM P SHORT CrackM E2.00401303 ;Salta a otra tarea
004012FC |> 0AC0 |OR AL,AL ;Como no es el último carácter...
004012FE |. 74 03 |JE SHORT CrackM E2.00401303 ;El salto no se produce....
00401300 |. 41 |INC ECX ;Y por eso incrementa el contador
00401301 |.^ EB E7 \JM P SHORT CrackM E2.004012EA ;Vuelve al inicio del bucle
00401303 |> 33C0 XOR EAX,EAX ;Limpia los registros....
00401305 |. 33DB XOR EBX,EBX
00401307 |. A1 8C344000 M OV EAX,DWORD PTR DS:[40348C] ;Toma la cantidad de caracteres del nombre
0040130C |. 8B1D A4344000 M OV EBX,DWORD PTR DS:[4034A4] ;Toma la cantidad de caracteres del serial
falso
00401312 |. 3BC3 CM P EAX,EBX ;Los compara...
00401314 |. 74 10 JE SHORT CrackM E2.00401326 ;Si son iguales, sigue..sino....
00401316 |. E8 6FFFFFFF CALL CrackM E2.0040128ª ;La rutina que no sabíamos que hacía, je
0040131B |. C705 BC344000>M OV DWORD PTR DS:[4034BC],6B8E9C ;M ueve una constante a una nueva
variable
00401325 |. C3 RETN ;Vuelve de la rutina
00401326 |> E8 3D000000 CALL CrackM E2.00401368 ;Tres llamadas...ya veremos que hace cada una
0040132B |. E8 06000000 CALL CrackM E2.00401336
00401330 |. E8 5C000000 CALL CrackM E2.00401391
00401335 \. C3 RETN ;Vuelve a la rutina

Bien, en esta parte, lo que hace es lo mismo que al inicio de todo este lio. Como antes
contó los caracteres del nombre, ahora cuenta los caracteres del serial falso que hemos
metido nosotros. Luego recupera ambos valores, la cantidad de caracteres del nombre y
la cantidad de caractere del serial falso, los compara y si no son iguales, mueve un 1 a
esa variable que al inicio, no sé si recuerdan, no sabíamos para que utilizaba, parece que
la está utilizando como un tipo de flag, luego veremos para que.

Bien, pasada esa otra parte, vemos que hay tres rutinas, o subrutinas, ya no sé por donde
ando, je, que están seguidas unas de otras. Bueno, en la primer rutina veremos esto:

00401368 /$ 33C0 XOR EAX,EAX ;Limpia los registros


0040136A |. 33DB XOR EBX,EBX
0040136C |. 33C9 XOR ECX,ECX
0040136E |. 33D2 XOR EDX,EDX
00401370 |. 8B15 8C344000 M OV EDX,DWORD PTR DS:[40348C] ;Recupera la cantidad de caracteres del
nombre
00401376 |> 3BD1 /CM P EDX,ECX ;Lo compara con lo que hay en ECX, el contador
00401378 |. 75 01 |JNZ SHORT CrackM E2.0040137B ;Si son iguales, vuelve de la llamada..sino....
0040137A |. C3 |RETN
0040137B |> A1 7C324000 |M OV EAX,DWORD PTR DS:[40327C] ;M ueve el serial falso a EAX
00401380 |. 8A81 7C324000 |M OV AL,BYTE PTR DS:[ECX+40327C] ,Toma de a un carácter y lo guarda en AL
00401386 |. 8AD8 |M OV BL,AL ;Luego mueve Al a Bl
00401388 |. 8999 24334000 |M OV DWORD PTR DS:[ECX+403324],EBX ;Luego EBX a una nueva variable
0040138E |. 41 |INC ECX ;Incrementa ECX, el contador
0040138F \.^ EB E5 \JM P SHORT CrackM E2.00401376 ,Vuelve al inicio del bucle

Acá lo que hace es cambiar del posición de memoria el serial.

reversing_ar@yahoo.com.ar http://www.joe-cracker.tk/ncr.htm 7
CrackME2 – Yllera by +NCR/CRC! [ReVeRsEr]

En la siguiente llamada tenemos esto:

00401336 $ 33C0 XOR EAX,EAX ;Limpia los registros


00401338 . 33DB XOR EBX,EBX
0040133A . 33C9 XOR ECX,ECX
0040133C . 33D2 XOR EDX,EDX
0040133E . 8B1D 8C344000 M OV EBX,DWORD PTR DS:[40348C] ;Recupera la cantidad de caracteres del
nombre
00401344 > 8A81 24334000 M OV AL,BYTE PTR DS:[ECX+403324] ;Toma carácter a carácter el serial falso
desde la nueva posición de memoria
0040134A . 3BD9 CM P EBX,ECX ;Se fija si es el último caracter
0040134C . 75 01 JNZ SHORT CrackM E2.0040134F ;Si no es el último salta....
0040134E . C3 RETN ;Si es el último, regresa de la llamada
0040134F > 3C 32 CM P AL,32 ;Realiza las mismas operaciones que para realizar el serial válido
00401351 . 77 04 JA SHORT CrackM E2.00401357
00401353 . EB 0A JM P SHORT CrackM E2.0040135F
00401355 . EB 06 JM P SHORT CrackM E2.0040135D
00401357 > 3C 33 CM P AL,33
00401359 . 72 02 JB SHORT CrackM E2.0040135D
0040135B . EB 00 JM P SHORT CrackM E2.0040135D
0040135D > 2C 02 SUB AL,2
0040135F > 8981 78334000 M OV DWORD PTR DS:[ECX+403378],EAX
00401365 . 41 INC ECX
00401366 .^ EB DC JM P SHORT CrackM E2.00401344

En esta parte lo que hace es a partir de nuestro serial, generar otro para luego usarlo en
la comparación. Es de suponer que si el serial es falso, no se generará lo que el
programa espera y nos hechará afuera con el RET, pero si el serial es el verdadero,
generara un serial idéntico al válido y luego los comparará carácter a carácter. Esta
subrutina se engancha con la que sigue. Nos importante para nuestra tarea de conseguir
el serial o de programar el KeyGen, pero si quieren entender bien como hace la
comparación sigan la ejecución del programa y entenderán lo que quiero decir.

La última rutina contiene esto:

00401391 $ 33C0 XOR EAX,EAX


00401393 . 33DB XOR EBX,EBX
00401395 . 33C9 XOR ECX,ECX
00401397 . 33D2 XOR EDX,EDX
00401399 . 8B15 8C344000 M OV EDX,DWORD PTR DS:[40348C]
0040139F > 3BD1 CM P EDX,ECX
004013A1 . 75 02 JNZ SHORT CrackM E2.004013A5
004013A3 . EB 21 JM P SHORT CrackM E2.004013C6
004013A5 > 8B81 78334000 M OV EAX,DWORD PTR DS:[ECX+403378]
004013AB . 8A81 7C324000 M OV AL,BYTE PTR DS:[ECX+40327C]
004013B1 . 8A99 BC344000 M OV BL,BYTE PTR DS:[ECX+4034BC]
004013B7 . 38D8 CM P AL,BL
004013B9 . 75 05 JNZ SHORT CrackM E2.004013C0
004013BB . 41 INC ECX
004013BC .^ EB E1 JM P SHORT CrackM E2.0040139F
004013BE . EB 06 JM P SHORT CrackM E2.004013C6
004013C0 > E8 C5FEFFFF CALL CrackM E2.0040128A
004013C5 . C3 RETN

Ahí lo que hace es tomar carácter a carácter nuetro serial válido y el falso generado
nuevamente en la rutina anterior y los va comparando. Si alguna comparación no diera,
se iría nuevamente a la runtina que utiliza como flag. Si todos las comparaciones
resultaron satisfactorias, el programa devía su ejecución a la parte en la que comienza a
generar el mensaje de felicitaciones. Al principio no sabía para que se utilizaba esto,
pero luego me di cuenta treceando con los datos válidos, je.

reversing_ar@yahoo.com.ar http://www.joe-cracker.tk/ncr.htm 8
CrackME2 – Yllera by +NCR/CRC! [ReVeRsEr]

Esta es la rutina en la que genera el mensaje de felicitaciones:


004013C6 > \33C0 XOR EAX,EAX
004013C8 . 33DB XOR EBX,EBX
004013CA . 33C9 XOR ECX,ECX
004013CC . 8A1D 73304000 M OV BL,BYTE PTR DS:[403073]
004013D2 . 80C3 35 ADD BL,35
004013D5 . 891D 10304000 M OV DWORD PTR DS:[403010],EBX
004013DB . 8A1D 73304000 M OV BL,BYTE PTR DS:[403073]
004013E1 . 80C3 48 ADD BL,48
004013E4 . 891D 11304000 M OV DWORD PTR DS:[403011],EBX
004013EA . 8A1D 73304000 M OV BL,BYTE PTR DS:[403073]
004013F0 . 80C3 38 ADD BL,38
004013F3 . 891D 12304000 M OV DWORD PTR DS:[403012],EBX
004013F9 . 8A1D 73304000 M OV BL,BYTE PTR DS:[403073]
004013FF . 80C3 41 ADD BL,41
00401402 . 891D 13304000 M OV DWORD PTR DS:[403013],EBX
00401408 . 8A1D 73304000 M OV BL,BYTE PTR DS:[403073]
0040140E . 80EB 0D SUB BL,0D
00401411 . 891D 14304000 M OV DWORD PTR DS:[403014],EBX
00401417 . 8A1D 73304000 M OV BL,BYTE PTR DS:[403073]
0040141D . 80C3 36 ADD BL,36
00401420 . 891D 15304000 M OV DWORD PTR DS:[403015],EBX
00401426 . 8A1D 73304000 M OV BL,BYTE PTR DS:[403073]
0040142C . 80C3 45 ADD BL,45
0040142F . 891D 16304000 M OV DWORD PTR DS:[403016],EBX
00401435 . 8A1D 73304000 M OV BL,BYTE PTR DS:[403073]
0040143B . 80C3 34 ADD BL,34
0040143E . 891D 17304000 M OV DWORD PTR DS:[403017],EBX
00401444 . 8A1D 73304000 M OV BL,BYTE PTR DS:[403073]
0040144A . 80C3 36 ADD BL,36
0040144D . 891D 18304000 M OV DWORD PTR DS:[403018],EBX
00401453 . 8A1D 73304000 M OV BL,BYTE PTR DS:[403073]
00401459 . 80C3 3E ADD BL,3E
0040145C . 891D 19304000 M OV DWORD PTR DS:[403019],EBX
00401462 . 8A1D 73304000 M OV BL,BYTE PTR DS:[403073]
00401468 . 80C3 38 ADD BL,38
0040146B . 891D 1A304000 M OV DWORD PTR DS:[40301A],EBX
00401471 . 8A1D 73304000 M OV BL,BYTE PTR DS:[403073]
00401477 . 80C3 45 ADD BL,45
0040147A . 891D 1B304000 M OV DWORD PTR DS:[40301B],EBX
00401480 . 8A1D 73304000 M OV BL,BYTE PTR DS:[403073]
00401486 . 80EB 0D SUB BL,0D
00401489 . 891D 1C304000 M OV DWORD PTR DS:[40301C],EBX
0040148F . 8A1D 73304000 M OV BL,BYTE PTR DS:[403073]
00401495 . 80C3 0E ADD BL,0E
00401498 . 891D 1D304000 M OV DWORD PTR DS:[40301D],EBX
0040149E . 8A1D 73304000 M OV BL,BYTE PTR DS:[403073]
004014A4 . 80C3 42 ADD BL,42
004014A7 . 891D 1E304000 M OV DWORD PTR DS:[40301E],EBX
004014AD . 8A1D 73304000 M OV BL,BYTE PTR DS:[403073]
004014B3 . 80EB 04 SUB BL,4
004014B6 . 891D 1F304000 M OV DWORD PTR DS:[40301F],EBX
004014BC . C3 RETN

Una vez que hemos vuelto de la llamada vemos esto:

00401122 > \E8 67000000 CALL CrackM E2.0040118E


00401127 . 8B0D 20344000 M OV ECX,DWORD PTR DS:[403420]
0040112D . 83F9 01 CM P ECX,1
00401130 . 75 04 JNZ SHORT CrackM E2.00401136
00401132 .^ EB AF JM P SHORT CrackM E2.004010E3
00401134 . EB 4F JM P SHORT CrackM E2.00401185
00401136 > 0BC9 OR ECX,ECX
00401138 . 75 4B JNZ SHORT CrackM E2.00401185
0040113A . 6A 00 PUSH 0 ; /Style = M B_OK|M B_APPLMODAL

reversing_ar@yahoo.com.ar http://www.joe-cracker.tk/ncr.htm 9
CrackME2 – Yllera by +NCR/CRC! [ReVeRsEr]

0040113C . 68 75304000 PUSH CrackM E2.00403075 ; |Title = "Crackme por Yllera"


00401141 . 68 10304000 PUSH CrackM E2.00403010 ; |Text = "buen cracker ;o)"
00401146 . 6A 00 PUSH 0 ; |hOwner = NULL
00401148 . E8 A7030000 CALL <JM P.&user32.M essageBoxA> ; \M essageBoxA

Vemos que a la salida del call, recupera el flag de la rutina que estaba en [40128ª] y la
testea con 1, si es igual a 1, señal de que el flag ha sido modificado, nos saca del
programa sin dar señal de mesaje de error, en cambio si el flag no fue modificado, lo
que hace es llevarnos a la zona en la que ya ha desencriptado el mensaje de
Felicitaciones y nos muestra dicha MessageBoxA.

Por lo tanto, pienso que con solo forzar un 1 dentro del flag con un injerto pequeño, nos
daría la posibilidad de que el crackme nos diera la posibilidad de registrarnos con
cualquier serial sea falso o verdadero dado que la comparación siempre daría
satisfactoriamente y así estariamos siempre en el mensaje de felicitaciones, je, yo lo he
probado y me ha funcionado perfectamente. Pero esa no es el objetivo de los crackmes,
con un programa suele ser distinto pues hay veces en las que calcular el serial resulta
bastante complicado y resulta más fácil modificar el código. Pero los objetivos de los
crackmes es que aprendamos.....

Bueno, esto se ha extendido demasiado, así que el keygen lo dejaremos para la segunda
parte.

Salu2.......

+NCR/CRC! [ReVeRsEr]

Agosto de 2004

Pd: saludos Yllera, mis felicitaciones por el crackme......

reversing_ar@yahoo.com.ar http://www.joe-cracker.tk/ncr.htm 10

También podría gustarte