Developer's Diary

6 septiembre, 2015

Estudiando un packer para .NET

Filed under: Sin categoría — jnavero @ 8:58 PM

Introducción.

Existen aplicaciones para empaquetar y ofuscar código .NET para posteriormente ser distribuido, en este post vamos a realizar un pequeño estudio sobre el funcionamiento de uno de ellos, en este caso netsrink de la empresa pelock y como se puede ver en su web: http://www.pelock.com/

vemos la descripcion .netshrink is an executable compressor for managed files. It uses LZMA compression library and can decrease your file size by 50%. It can also protect your files with a password.

.netshrink uses LZMA compression library to achieve maximum compression ratios. Password protection uses verification based on SHA256 hash function and 256 bit AES / Rijndael encryption.

What’s supported:

  • compression of .NET executables only
  • password protection
  • command line options

Antes de comenzar.

Quiero dejar claro que en este tutorial no se va a crackear nada, es un estudio del compresor. No me hago responsable del uso que se le pueda dar a este documento, está escrito solo con fines didácticos.

Utilizando la herramienta.

Una vez instalada, he creado una aplicación en .NET Framework 3.5 (Hola mundo) con un Formulario y un botón que muestra un MessageBox.

hiworld

Algo sencillo, para nuestros fines, suficiente. Con esto arrancamos la aplicación que tiene este aspecto:

img1

Como podemos ver, no es la última versión pero, tampoco nos importa, lo importante es la funcionalidad en sí. La aplicación no es nada compleja al contrario es muy sencilla.  Fichero de entrada, fichero de salida, si deseamos con clave o sin ella y comprimir el fichero. En nuestra prueba, lo haremos sin protección y obtenemos el siguiente resultado:

img2

Supongo que comprimir 8 Kb no es posible y entre la compresión y unas cosas y otras, ocupa más que el original. Si le doy dos clicks, se abre una nag diciendo que esta aplicación está comprimida con una demostración del netshrink.

img3

Si pulsamos sobre aceptar, aparece nuestra aplicación correctamente. Y podemos ejecutarla como siempre.

¿Qué ha sucedido?

Abramos la aplicación en reflector a ver qué ha sucedido. Al abrirlo, tenemos un antes y un después que vemos a continuación:

img4img5

Supongo que no será necesario decir cuál es antes y cual es después…

En realidad me llamo mucho la atención ver tantas “Clases”. Se supone que está comprimido, no he leído nada de ofuscación del código ni nada por el estilo, sin embargo, veo que hay mogollón de cosas nuevas…

He usado el DeOfuscator 0.5 para intentar tener una visión de todo esto, después de deofuscarlo la aplicación ha dejado de funcionar, pero si lo abrimos nuevamente con reflector ya tiene mejor pinta (o por lo menos más legible).

img6

La pregunta que muchos estaréis haciendo posiblemente es ¿Qué estoy haciendo? Pues como dije en la introducción curiosear y ver cómo funciona este compresor. Después de mirar un par de minutos entre clases y funciones, hay una en especial que me llama la atención.

img7

No voy a dar clases de programación, pero, en esta función se carga nuestra aplicación en un Stream y después de varias operaciones llama a una función a la que le pasa un MemoryStream y un Stream (nuestra aplicación). Posiblemente, estemos ante las funciones propias que desempaquetan nuestra aplicación. Además si nos fijamos bien, tenemos un MessageBox.Show… y posteriormente la función assambly.EntryPoint.Invoke, la cual nos permitirá llamar a un ensamblado en memoria. Bueno la cosa está clara, partimos como premisa, que se desempaqueta y lo guarda en memoria en ese MemoryStream. Vamos a desempaquetar esto.

El tema principal, es que utiliza el espacio de nombres de .net llamado system.reflection (reflexión)

a través de la reflexión, se pueden acceder a métodos, propiedades o cualquier cosa que queramos de un ensamblado. En este caso estamos haciendo una llamada al punto de entrada del ensamblado (entrypoint) que llamará a nuestro  programa principal. Hace un tiempo cree un post que hablaba sobre cargar un ensamblado de forma dinámica que se puede ver aqui: https://devthisblog.wordpress.com/2014/04/07/net-reflection-cargando-un-ensamblado-de-forma-dinamica/

Y la pregunta del millón.

¿Podemos volver a ver la version original del programa después de hacer eso?

La respuesta es Sí y muy fácilmente. Si, cargamos el programa en Olly, nos vamos a Memory Map y buscamos Assembly Version. En mi caso han aparecido unos pocos, pero, he podido identificar el que me interesa de dos formas, El nombre del formulario principal que aparece y porque si vemos el trozo del dump inicial disponemos del Mz que es la cabecera.

img8

Botón derecho, y sobre Backup pulsamos en save data to file. Y si todo lo hemos hecho correctamente, tendremos el fichero original, antes de haberlo comprimido.

Esto es todo por ahora, saludos!

Anuncios

Dejar un comentario »

Aún no hay comentarios.

RSS feed for comments on this post. TrackBack URI

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

A %d blogueros les gusta esto: