Karpoff Spanish Tutor 1999-2002
Programa:

Crackme!  D^3AM v1.0 DE DeAtH


 
PROTECCION:  Encontrar numero de serie Y Hacer KeyGenerador
Descripcion: Crackme para practicar en este mundo de la ingenieria inversa, se trata de encontrar el numero de serie correcto y ademas hacer un Generador de Keys 
Dificultad: Aficionado
DOWNLOAD: http://come.to/karpoff
Herramientas: Softice, W32dasm, y Bastantes Nociones sobre el Funcionamiento del Copro y en Sobremanera unas ordenes concretas
CRACKER: Nandois   FECHA: 01/02/2002

 

 

 INTRODUCCION
Hola!!!
Este es un Crackme con el cual pasas de querer dejarlo todo para siempre mas, a ver lo alucinante que es este mundo de la ingenieria inversa y lo poco que sabes, de este mundo, al menos yo.
De este Crack lo menos importante,es lo importante de un crack y es encontrar el numero de serie, pues realmente cuando tienes el numero de serie de un programa
ya tienes lo que querias, poco importa, como lo has conseguido.
Pero en este caso el Productor del crack, pedia para que el mismo se diera por resuelto que se tenia que hacer un generador del mismo.
Y aqui es donde realmente se hace interesante la manera que DeAth se monto el numero y me complico la existencia.
Basta de charla y vamos a ver el Crack.

 

 

 AL ATAKE
 

 

De entrada vemos con el FileInspector, que usa UPX para comprimir el archivo

vemos que se puede descomprimir  sin problemas, y el archivo nos pasa de 13Kb a 50Kb, en fin  una vez
descomprimido lo corremos con el Wsdamm, pasamos un ratito con el y encontramos, un salto que una vez
modificado nos dice que somos unos buenos crackers ect. ect..
 
Abrimos el Sice y despues de un breve paseo por él vemos en un lugar, que se origina un numero,
cerramos el Sice ponemos el numero que vimos y jo, funciona.
En un ratito hemos pillado un salto que hablando hipoteticamente, haciendole un pequeño cambio, nos
registra el producto, y luego mirando un poco mas vemos que tenemos el numero que nos registra dicho
producto, ya ni tan siquiera, tener que molestarnos en modificar el programa.
Pues vaya, piensas, tecnicamente es una muy mala proteccion, pues no se puede decir que este muy bien
protegido, es que no existe proteccion.

Visto esto y muy contentos, nos metemos en la boca del lobo intentando hacer el generador de Keys del programa. Y aqui es donde no tiene desperdicio el montaje que hace DeAth.

Vamos a por el;

 

Lo primero que hay que tener presente es que el nombre de entrada tiene que tener como minimo " seis digitos " o mas.

El segundo control que hace DeAtH es que el numero ó la clave que se ponga tiene que terminar con la letra " d ".

Pasados estos dos controles, empieza el baile para la obtencion del numero de serie correcto.

Primero coge los digitos, tercero y segundo y los multiplica.
aqui tenemos la referencia a esta primera operacion.

* Reference To: MSVBVM60.__vbaVarMul, Ord:0000h
                                  |
:004068FF FF159C104000            Call dword ptr [0040109C]

Guarda el resultado y va por la segunda operacion 
Para Esta operacion se utilizan el penultimo digito y el cuarto.


* Reference To: MSVBVM60.__vbaVarAdd, Ord:0000h
                                  |
:00406AC4 FF15F8104000            Call dword ptr [004010F8]
:00406ACA 8D8DECFBFFFF            lea ecx, dword ptr [ebp+FFFFFBEC]
:00406AD0 50                      push eax

El resultado de la suma lo multiplica por dos dos veces.

A continuacion al valor obtenido le añade el total que tenia de la multiplicacion
anterior.
Y guarda este total al que a partir de ahora llamaremos  total.

Siguiendo la manipulacion del nombre ahora se coge  el quinto digito y se multiplica por tres el valor obtenido se añade al  total generando un nuevo total

Segimos, ahora se coge el primer digito y sexto digito.
se multiplican y el valor se añade al total con lo cual tenemos un nuevo valor total.

De momento como veis la elaboracion de la Key es una serie de operaciones aritmeticas facilonas y que hemos visto en muchos trabajos, y esto es lo que 
en su momento pensó DeAtH, y es a partir de aqui, que la cosa se lia.

Voy a poner la siguiente operación y luego la comentamos.

Este codigo empieza o esta dentro de la call401048.
* Reference To: MSVBVM60.__vbaVarPow, Ord:0000h
                                  |
:00406E48 FF1548104000            Call dword ptr [00401048]

MOVSX EDX, DWORD ptr[ESI+4]
MOV[ESP+48],  EDX
FILD DWORD ptr[ESP+48]
FSTP REAL8 ptr [ESP+20] 
MOVSX EDX, WORD ptr [ESI+08]
MOV [ESP+48], EDX
FILD DWORD  ptr [ESP+48]
FSTP REAL8 ptr [ESP+20]

FLD REAL8 ptr [ESP+20]
FSTP REAL8 ptr[ESP]
FLD REAL8 ptr[ESP-08]
FSTP REAL8 ptr[ESP]
FLD REAL8 ptr[7FEA6F98]
FLD REAL8 ptr[EBP+08]
FCOMP st(1)
FSTSW AX
SAHF
FLD REAL8 ptr[EBP+08]
FCOMP st(1)
FSTSW AX
SAHF
FSTP st(0)
FLD REAL8 ptr[EBP+08]
FLD REAL8 ptr[ebp+10]
FXCH st(1)
FSTP REAL8 ptr[ESP]
FST REAL8[ESP+08]
FSTCW WORD ptr [ESP]
FSTCW  WORD ptr [ESP+06]
FLD REAL8 ptr[EDX]
FYL2X
FLD st(0)
FRNDINT
FSUBR st(1)
FXCH st(1)
FCHS
F2XM1
FLD1
FADDP st(1), st
FSCALE
FSTP (1)
FST REAL8 ptr [ESP]
FLDCW WORD ptr[ESP].

Bien, aqui termina una serie de operaciones que como no tenia ni idea de lo 
que hacian, me hicieron hacer muchas cosas, entre ellas dejar el Crack para otro mas experimentado que yo, pero a base de hacer preguntas, y buscar, empezé a entender lo que hacia el crackme.

Todo lo expuesto anteriormente es el paso siguiente en la elaboracion del numero bueno del crackme, se coge el segundo digito del nombre y se transforma en Real extendido (64bits) y luego le aplica una serie de operaciones con la que obtiene un numero en base 64bits.

Como ejemplo vale decir que si el segundo digito fuera la letra " b ", que tiene un valor igual a 62hexa, despues de pasarlo a real-extendido 64bits  el valor 
de 62 hexa seria igual a 4058800000000000.
y este valor una vez pasadas las anteriores operaciones quedaria como

40C2C20000000000.-

Lo que no he podido conseguir ni llegar a saber es como y que operaciones se hacen para convertir un numero decimal a real extendido, lo pedi a muchos lugares, y, o no saben o no quieren contestar.
Pero como lo que interesaba era hacer el generador, cuando uno no sabe bien como va la cosa , siempre se puede improvisar, y a base de unos inventos propios y mucho trabajo se consiguió.

A partir de aqui se trabaja la elaboracion de la key en base real-extendido 16bits

Una vez conseguido el valor que nos da la elaboracion del segundo digito, le sumamos el TOTAL que teniamos de las operaciones anteriores obteniendo un nuevo  TOTAL  pero recordad en base real-extendido 16bits.
Acontinuacion coge los digitos tercero y primero los multiplica y el valor obtenido lo añade al total consiguiendo un nuevo  TOTAL.

Luego coge el cuarto digito por delante y el cuarto digito por detras los multiplica
y su resultado lo añade al total con la que ya tenemos un nuevo  TOTAL.

Ahora para seguir mareando la perdiz, coge el ultimo digito del nombre y el cuarto por detras, los resta y el resultado lo añade al total, con lo que ya tenemos un nuevo  TOTAL.

Ahora se coge la constante 65hexa, la multiplica por el total, y ya tenemos un nuevo  TOTAL.

Aqui realiza una operacion, que mas bien, parece de relleno, pues lo que hace es restar uno al total acumulado.

A continuacion se coge la constante 5DC h.  1500 en decimal y se resta al total que teniamos, con lo cual ya tenemos un nuevo TOTAL.

Las tres siguientes operaciones, en principio parecen tres simples multiplicaciones pero tienen su trampita, para despistados o agotados, de tanto meneo de numeros. 
Primero se coge el total y se multiplica por tres y obtenemos un nuevo total.
despues cogemos el total y lo multiplicamos por dos y tenemos aqui la trampita,  pues guardaremos el resultado obtenido como  SUBTOTAL y TOTAL.
A  continuacion cogemos el total y lo multiplicamos por cuatro y asi obtenemos un nuevo  TOTAL.

La siguiente operacion se limita a sumar al total el subtotal que teniamos guardado, consiguiendo un nuevo TOTAL.
Aqui decia que habia trampa, porque los numeros de las multiplicaciones son en real-extendido muy parecidos, y como llevaba un ritmo de ir descartando los subtotales que tenia, y siempre trabajaba con el ultimo total conseguido, en esta operacion anterior, sino estas, ala guay,  en principio parece que sume el total dos veces, que es lo que me pareció a mi, y me llevo un ratito de culo, pues no cuadraban los resultados.

Bien una vez aqui se coge el  TOTAL  se le resta 5F5B9F0h. que viene a ser en decimal 99990000, y conseguimos un nuevo  TOTAL.

Para seguir a partir de aqui hace las siguientes comprobaciones.
primera si el resultado es positivo o negativo.
SI EL RESULTADO ES POSITIVO
           Si es positivo mira si es inferior a 989680h.  o 10000000decimal.
           si es inferior a 10000000, le suma al TOTAL los 10000000.-
           Y ya tenemos un nuevo  TOTAL.
SI EL RESULTADO ES NEGATIVO
          Si el resultado es negativo lo pasa a positivo con el mismo valor
          Y si es inferior a 10000000dec. le suma al  total positivado los 
          10000000dec. y ya tenemos un nuevo  TOTAL.

Ya casi lo tenemos, despues de tanta movida aun quiere mas, y coje la primera letra del nombre, la multiplica por dos, y el resultado lo suma al total, con lo cual obtenemos un nuevo  TOTAL  y  definitivo.

Solo falta transformar este total en base Real-extendido 64bits a decimal
y ya tenemos el numero deseado.

Bien no?.
En principio es un trabajo bastante comun de obtener un numero en base a un nombre
con una serie de operaciones, más o menos complejas.
Lo que yo he encontrado muy bueno, es la introducción de unas operaciones,que los que no tenemos conocimientos muy profundos de la informatica, nos sorprenden y que considero que se tienen que conocer, y estas estan muy relacionadas, por los datos que he acumulado, con el funcionamiento de coprocesador, y como trabaja la FPU y la pila de la FPU, y el efecto FIFO, ultimo de entrar primero en salir.
Yo en base a lo que he acumulado intentaré poner que hace cada orden.

Veamos.. las instrucciones de carga (fld y fild) Float Load u Float Integer Load respectivamente cargan un valor de una determinada direccion de memoria que puede ser de diferente tamaño y puede ir incluso indexada por algun registro... Ejemplos:

fild Dword Ptr ds:[MiVariable]
Cargaria un entero de 32bits de la direccion de memoria "MiVariable"

fld QWord Ptr ds:[eax]
Cargaria un real de 64bits de la direccion de memoria direccionada por eax.

Estas instrucciones introducen ese valor en la pila del coprocesador... esta pila es de tipo FIFO (First In First Out) es decir.. si nosotros cargamos un valor en la pila con fld el primer valor que sacariamos en caso de hacer un fst seria este.

El funcionamiento es exactamente igual que el manejo de pila del propio procesador.. es decir.. las instrucciones push y pop ... las Load serian el push y las Store serian el pop...

Las diferencias son:

Hay 8 posiciones de pila (vamos, esta limitado)
Las posiciones de la pila son referenciadas por unos registros para poder trabajar con ellas. St(0) St(1)...

St(0) siempre apunta al ultimo valor introducido en la pila.. este sera el primero en salir claro.
St(1) al siguiente, etc ,etc

Si nosotros realizamos un fadd st(0),st(1) la operacion es la siguiente.

St(0) = St(0)+ St(1); 

Como ves es lo mismo que hacer un add solo que se trabaja con la pila del coprocesador y no con registros normales... para hacer util el resultado hay que extraerlo de la pila usando alguna instruccion de store...

El unico problema que tiene esto es que si tu haces fadd st(3),st(5) ... el resultado queda en st(3) y antes de que salga este han de salir de la pila st(0),st(1) y st(2).... 

Las instrucciones de store toman un valor de la pila ( st(0) ) y lo almacenan en una posicion de memoria... 
Te las enumero:
fst     [Memoria]       <-- Toma el valor de st(0) y lo introduce en la memoria correspondiente.
fist    [Memoria]       <-- Toma el valor de st(0) lo convierte a entero y lo introduce en memoria.
fistp   [Memoria]       <-- Toma el valor de st(0) lo elimina de la lista con lo cual  st(1) pasa a ser st(0) , st(2) pasa a ser st(1), etc y lo introduce en memoria.
fstp    [Memoria]       <--- Idem que la anterior pero sin conversion a entero.

Memoria puede ser una constante ej:

fstp ds:[MiVariable]

o usando un registro para indexado ej:

fist ds:[eax].

Como comprobareis no hay instrucciones para pasar un valor de un registro de proposito general a una posicion de pila de copro y encima solo podemos introducir y sacar al estilo pila... esto en principio es algo lioso de pillar y complica a veces la programacion de alguna ecuacion, pero una vez te has acostumbrado ya no es tanto trauma.

Estas serian las operaciones principales, pero como habeis visto hay otras, que
utiliza en este crack, que intentare explicar, y no son todas, porque hay un mogollon.

FCOMP st(1) Esta es bastante facil pues lo que hace es en este caso comparar lo
                     que hay en st (0), cima de la pila con st (1).
FSTSW AX  aqui solo he llegado a saber que guarda la palabra de estado de la
                   FPU, en AX. Para ampliar esto necesitareis alguien mejor preparado
                   que yo
SAHF  Aqui solo puedo decir que copia en los flegs del procesador los 
           correspondientes bits de AH.
FXCH  st(1) Esta orden intercanbia los valores de st(0) y st(1)
FYL2X esta es el siguiente calculo (st(1)*log2(st(0))). el que quiera que se
           entretenga con el.
FRNDINT redondea  el valor de st(0) al entero mas proximo y lo deja en st(0).
F2XM1 esta es otro calculo, calcula 2 elevado a st(0)-1 y lo deja en st(0).
            aqui no me quedo claro si es 2elevado a st(0)-1
            o la operacion es 2 elevado a (st(0)-1), pero esta es la idea.
FSCALE otra operacion, multiplica st(0)por 2 elevado a st(1) y como siempre
              deja el resultado en st(0).

y termino, para los que saben de informatica a tope esto debe ser facilito
pero, para los menos buenos, tiene su tela y es interesante saberlo y darse
una vuelta por las paginas de Intel i Cia, para descubrir el copro.
He terminado.
Me lo puso muy mal el DeAtH, pero al final pude hacer el generador, no es que sea del todo correcto, tiene sus trampillas, pero funciona.
Con todos estos datos al que le interese, puede hacerlo.
supongo que habrá fallos de todo tipo, desde ortograficos a definiciones,
me gustaria que me los comentarais, pues lo que hago, es para aprender yo y acepto todos los consejos.

 nandois@teleline.es

AGRADECIMIENTOS. Los hay para mucha gente, pero en especial a Victor Jurado
y a Crick(que pesado soy, pero me ayudaste mucho) y como no a Karpoff.
Hasta otra.

 

 

Karpoff Spanish Tutor: Pagina dedicada a la divulgacion de informacion en Castellano, sobre Ingenieria Inversa y Programacion. Email "Colabora con tus Proyectos"
www.000webhost.com