Protecciones Win 32 por Dongle SSI.
Trabajo inicial alrededor de blancos Win32 dificiles

22 Enero 1998

por Spyder


Cortesía de la página de Fravia de ingeniería inversa

levemente editado
por fravia+

Hay un crack, un crack en todo Asi es como la luz entra.

Dificultad

( )Principante (x)Intermedio (x)Advanzado ( )Experto

Este ensayo describe un metodo para trabajar alrededor de una proteccion bastante torpe para programas Win32 que utilizan dongles Sentinel.


Protecciones Win 32 por Dongle SSI.
Trabajo inicial alrededor de blancos Win32 dificiles
Escrito por Spyder

Introduccion

Esto no es un crack completo de algo, solo un trabajo que hace posible un crack aparentemente imposible. Yo se poco acerca de dongles, o acerca de compañias que los fabriquen. Para este blanco la compañia se llama "Sentinel", y si usted ve referencias a Sentinel o SSI, entonces estamos hablado de la misma cosa. Si usted intenta un listado completo y encuentra megabytes de basura eso tambien es una buena (o mala?) señal.

Se poco acerca del codigo real del dongle - nunca tuve que mirarlo - pero instalar breakpoints en la puerta I/O de la impresora o algo asi, es la *ultima* forma de iniciar un crack de cualquier programa protegido por dongles (aka dongled program) (IMHO).

Herramientas requeridas

Borland Turbo debuger.
Borland Tdump es practico.
Un buen editor de binario
Un buen disasembler (puede usted decir IDA?).

URL/FTP del blanco

No hay un blanco especifico.



Ensayo

Porque este crack tendria que ser imposible?. Bien, el codigo del dongle es una envoltura para un ejecutable semi-protegido. Cuando la envoltura se aplica, encripta la mayoria del codigo ejecutable, de hecho se coloca al final del programa y toma el punto de entrada del mismo. Cuando se hace correr el programa el codigo del dongle se hace con el control, y si esta contento con el dongle encontrado desencritpta el ejecutable y le transfiere el control. El ejecutable puede entonces llamar nuevamente al codigo del dongle para realizar cualquier chequeo especifico que quiera, para confirmar que el todavia esta presente, en varios momentos durante la ejecucion.

Pero aun cuando rompa el codigo inicial del dongle usted necesitara entender y remendar el ejecutable principal. La encripcion hace la comprension dificil y el emparchado casi imposible. La ruptura completa del codigo del dongle es improbable que sea una opcion. Este tipo de dongles hacen cosas como devolver un valor de una cadena variable que se les pasa, el algoritmo y las llaves para hacer eso estan realmente asentados dentro del dongle - no hay ninguna manera facil de emparchar el codigo del driver del dongle para obtener el mismo resultado.

No he mirado los detalles exactos de la encripcion principal, pero no es debil. Estoy bastante seguro que es una encripcion rotativa (encriptado por convolucion (N.d.T.)) donde cambiar un byte afecta a todos los siguientes, es por eso que emparcharla sea tan dificil. Tambien estoy bastante seguro que las llaves de encripcion salen del dongle (deben trabajar de esta forma si los proveedores del dongle tienen algo de sentido) de modo que usted necesitara el dongle por al menos un par de horas. Pero, usted tambien podria tener UN POCO DE SUERTE. "Crackear sin suerte es tan imposible como crackear sin sentimiento".

Si el programa tiene un Demo, o quizas algun tipo de opcion para obtener la licencia por la red, entonces debe ser desencriptado sin la presencia del dongle, asi usted puede correrlo y entoces decidir si realmente necesita el dongle o la licencia de la red o cualquier cosa para utilizarlo totalmente. Entonces, conociendo esto, como vamos a trabajar con el?. Mi aproximacion es deshacer lo que se hizo cuando la cubierta fue aplicada, re-creando algo cercano al programa original antes de que fuera cubierto, entonces se pueden usar tecnicas normales de "reversing" . Eche una mirada a estas interesantes partes del volcado de un programa de muestra:-

Entry RVA     0003D950
Image base    00400000

Object table:
#   Name      VirtSize    RVA     PhysSize  Phys off  Flags
--  --------  --------  --------  --------  --------  --------
01  .text     0001E200  00001000  0001E200  00000400  E0000020 [CERW]
02  .rdata    00000800  00020000  00000800  0001E600  C0000040 [IRW]
03  .data     00013E24  00021000  0000D200  0001EE00  C0000040 [IRW]
04  .PAD000   00000E00  00035000  00000E00  00000000  C0000080 [URW]
05  .SSINod   00007A00  00036000  00007A00  0002C000  E0000040 [IERW]
06  .rsrc     00000800  0003E000  00000800  00033A00  C0000040 [IRW]
07  .idata    00000C00  0003F000  00000C00  00034200  C0000040 [IRW]
08  .reloc    00000200  00040000  00000200  00034E00  42000040 [IDR]

SSINod es el codigo agregado del dongle, PAD000 es donde se encuentra el segmento .reloc (que contiene las direcciones de importacion utilizadas durante la carga del programa)del programa original. Image base es donde el modelo del programa queda cargado en una memoria plana (la mayoria de las direcciones son relativas a esta base). La entrada RVA es la direccion de inicio del programa. El proximo paso es obtener el programa cargado y desencriptado dentro del Turbo debuger. Si el programa corre y queda corriendo mientras presenta un mensaje de error entonces la mejor manera de operar es encender el TD32 en una ventana DOS y enlazarse al programa. Una de las maravillas del debuger Win32, simplemente cliquee sobre File|Attach y seleccione una ventana, despues de lo cual TD32 obtendra el mando del programa y usted podra echar una mirada alrededor.

Tambien se podria iniciar el programa con el TD32 pero obtener el control una vez corriendo y desencriptado no es tan facil. Incluso se puede confiar en la imagen de memoria cuando el programa ha terminado, o quizas mirar en el stack y encontrar lugares donde se pueden colocar breakpoints. Estoy seguro que es mucho mas facil con el SoftICE, pero SoftICE (hasta donde yo se) no puede hacer todo lo que hace TD32. Sin embargo asumo que se maneja de algun modo para conseguir el mando del programa usando TD32. Heche una mirada a la RVA image base + .text para estar seguro que luce como codigo, para confirmar que el programa ha sido desencriptado, sino quizas necesite pedir prestado otro dongle a sus amigos y comenzar otra vez.

Ahora abra una ventana de volcado, vaya (Ctrl+G) a la direccion de image base y comienze marcando un bloque mediante la retencion y arrastre del mouse sobre los bytes hexadecimales requeridos (el marcado de bloques en TD32 es un poco extraño y las teclas shift y cursor no siempre funcionan). Ahora vaya hasta el fin del segmento .text (hasta donde se debe extender el bloque marcado). Seleccione Block|Write (Ctrl+B, W) y amablemente TD32 descargara el header ejecutable y el segmento completo de texto desencriptado en un archivo para usted. TD32 parece escribir los bloques a aproximadamente 1-2KB por segundo, lo que es lo bastante lento como para que se pueda ir a tomar un cafe o un coctail (!). (Lamento si estoy siendo demasiado especifico acerca del "manejo" del TD32, pero la primera vez que hice esto, no comprendia que se pudieran descargar bloques de memoria al disco y gaste horas escribiendo el volcado de memoria en un archivo y luego escribi un programa propio para volver los datos a binario, por eso quiero asegurarme que mis lectores conozcan este truco - un pequeño conocimiento a veces va por un largo camino).

Ahora una cosa mas antes de terminar con el TD32. Eche una mirada al segmento PAD000. Sera principalmente ceros y vera un bloque de direcciones de 32 bits. Estas son las entradas de importacion que se agregan en el momento de la carga en el segmento .reloc y parte del codigo del dongle los copia aqui, donde el ejecutable principal espera que esten. El orden y numero de las entradas no es el mismo que en el segmento .reloc, entonces no se puede simplemente copiarlo, ni manosear las RVA's para colocarlos en el lugar correcto. Ponga un breakpoint de escritura en la memoria fisica en cualquier de estos sitios y reinicie el programa desde el TD32 (Ctrl+F2). TD32 hara un break en medio del codigo del dongle, el que esta copiando estas entradas. Eche una mirada al codigo y - si esta como el material que yo he visto - podra encontrar una tabla de pares (parejas) de direcciones de 32 bits apuntada por EBX. Estos son pares de direcciones relativas (a la imagen) dentro de .reloc con la direcciones relativas requeridas en PAD000 para las mismas importaciones. Marque esta tabla y descarguela al disco como antes.

Ahora henos terminados con el TD32 y - probablemente - con el dongle.

Poniendo todo junto de nuevo

Ahora tenemos que insertar la descarga desencriptada en el ejecutable, lo que es una clase de edicion binaria, pero bastante tramposa. Eche otra mirada a la tabla "tdump'ed" y trate de comprender que significa...

Entry RVA     0003D950
Image base    00400000

Object table:
#   Name      VirtSize    RVA     PhysSize  Phys off  Flags
--  --------  --------  --------  --------  --------  --------
01  .text     0001E200  00001000  0001E200  00000400  E0000020 [CERW]
02  .rdata    00000800  00020000  00000800  0001E600  C0000040 [IRW]
03  .data     00013E24  00021000  0000D200  0001EE00  C0000040 [IRW]
04  .PAD000   00000E00  00035000  00000E00  00000000  C0000080 [URW]
05  .SSINod   00007A00  00036000  00007A00  0002C000  E0000040 [IERW]
06  .rsrc     00000800  0003E000  00000800  00033A00  C0000040 [IRW]
07  .idata    00000C00  0003F000  00000C00  00034200  C0000040 [IRW]
08  .reloc    00000200  00040000  00000200  00034E00  42000040 [IDR]

La RVA del segmento .text es 1000 que en la memoria comienza en la image base + 1000 = 401000. El Phys off (Physical offset (N.d.T.)) es donde se encuentra .text en el archivo ejecutable. Esto significa que la descarga desencriptada tiene C00 bytes entre 400 y 1000, que necesitan ser cortados. El header del archivo ejecutable no esta encriptado, y en mi experiencia siempre es identico en la imagen en memoria. Con su editor favorito, corte los C00 bytes y "pegue" la imagen descargada encima del ejecutable.

Arreglando las importaciones

Tenemos la descarga de los pares de direcciones para mover las direcciones de importacion entre los segmentos .reloc y .PAD000 al inicio. Deberiamos tener suficiente espacio para el codigo en el segmento .SSINod dado que una vez que este realmente crackeado el programa no debe tener que llamar alli nunca. Yo transforme la descarga binaria en hexadecimal, luego lo edite manualmente como definiciones de bytes (db) para cualquier ensamblador antiguo que pueda crear un archivo binario como salida. Agregue un A1h delante de la primera direccion para formar "mov eax,[????]" y A3h en la siguiente para "mov [????],eax". Recuerde sumar la direccion de Image base a todas las direcciones porque son relativas. Verifique dos veces que esta cargando de .reloc y guardando en .PAD000.

Yo simplemente volque este fragmento binario en el ejecutable al comienzo del segmento .SSINod. Entoces podria arreglar la RVA del punto de entrada en el header del ejecutable para apuntar a este codigo (o arregalr un salto luego).

Donde estamos ahora?

En este estado usted debe tener un ejecutable sin encriptar y que empieza ejecutando un trozo de codigo que mueve direcciones de importacion a donde el programa original las espera. El punto de entrada posiblemente apunte a este codigo, pero no lo ejecuta porque el parche de importacion esta seguido de la basura del dongle. El ejecutable debe ser del mismo tamaño del original - sino tengo miedo de que se haya embrollado en alguna parte de la edicion. Ahora tiene usted algo que puede comenzar a crackear, bueno para hacer listados, pero tendra que ubicar el punto original de entrada y arreglar dentro de el un salto al final del codigo emparchado de las importaciones antes de intentar ejecutarlo.

Si esta usando IDA bien puede descubrir el punto de entrada como funcion standard de libreria aunque IDA no parece reconocer automaticamente al compilador en estos ejecutables recontruidos (seleccione firma manual). La otra alternativa es hacer un debugging a otro programa construido con las mismas herramientas para ver como es el codigo del punto de entrada. Podria buscar codigos que se vean parecidos, sin embargo el codigo de arranque probablemente llame a GetVersion muy pronto. Una vez que a encontrado y arreglado el punto de entrada original, el trabajo esta terminado. Usted tiene ahora un ejecutable con las mismasd funciones que el original antes de que fuera envuelto.

Hay posibilidades de que el programa todavia llame al codigo del dongle pero como los autores esperan que la envoltura del dongle haga el analisis dificil y el parcheado imposible, es improblable que hayan hecho algo muy sofisticado, y si lo han hecho, eso nos satisface: mas desafios aun!

Notas Finales

Bien, espero que emcontraran esto interesante y quizas util. No he visto la encripcion de este dongle Sentinel en particular mas que en el segmento .text, de hecho, no siempre se encripta el segmento .text entero. La misma tecnica de recuperacion puede ser usada para otros esquemas basados en encripcion, pero las cosas se ponen mas dificiles cuando mas que el segmento .text este encriptado. Usted tendria que hacer un break y capturar una imagen del programa antes de que que corra lo bastante como para "manchar" su propio segmento de datos, el segmento .reloc es particularmente penoso dado que el OS lo "corrompe" durante la carga (sin embargo este tipo de material es igualmente dificil para los protectores).

La proteccion HASP suena bastante similar a mi Sentinel. Sospecho que la encripcion rotativa de Sentinel es mas robusta.

Spyder


www.000webhost.com