sábado, 4 de febrero de 2012

Introducción a la ingeniería inversa x86 (Parte II)

Continuando con la serie de introducción a la ingeniería inversa, y una vez visto un pequeño resumen de algunos de los registros, comentado algunas de las instrucciones más vistas y un resumen de cómo funciona la Stack, pasamos a ver como podemos interpretar código en ensamblador y no perdernos en el intento.

Vamos a ver unos cuantos ejemplos de códigos en lenguaje C y su equivalencia en lenguaje ensamblador. (Para el desensamblado de la aplicación podéis utilizar cualquiera de las muchísimas herramientas que existen: OllyDbg, IDA Pro, Immunity Debugger, gdb, radare, etcétera, en futuros posts haré una pequeña mención a cada una de ellas detallando sus comandos y funciones básicas).

1 - Hello World

Comenzaremos con el típico “Hello World”.

image

Tal y como se puede observar, el código es bastante simple de entender.

  • 0x004013C6: Hasta dicha dirección nos encontramos con el prologo de la función (inicialización de la misma).
  • 0x004013C9: Nos encontramos con la instrucción CALL que seguramente la habrá introducido el compilador para llamar a vete a saber tu qué ;)
  • 0x004013CE: Se puede observar como se copia (MOV) el valor 0x00403064 asociada a la cadena “Hello World” en ESP (cima de la pila), por lo que ya tenemos en la PILA el valor que necesitamos.
  • 0x004013D5: Se llame a la función PUTS, la cual cogerá de la cima de la pila el valor que va a imprimir por pantalla (“Hello World”).
  • 0x004013DA: Tenemos el epílogo, donde se restaura la pila y retornamos a la función anterior.

2 - Hello World (Argumentos)

Pasamos a ver como se manejan los argumentos que le pasamos a una función.

image

Ya que el código es similar al anterior pasaremos a detallar lo más relevante.

  • 0x004013CE y 0x004013D1: Copia el valor de “EBP+arg_4” que equivale a “argv” en EAX, acto seguido incrementa el valor de EAX en 4 para así poder acceder a “argv[1]” donde se encuentra la dirección que apunta al valor que se ha pasado por argumento a la aplicación.
  • 0x004013D4, 0x004013D6 y 0x004013D9: Se copia el contenido de la dirección almacenada en [EAX] a EAX. Y para finalizar copiamos EAX en la cima de la pila para que la función PUTS pueda imprimir por pantalla el texto introducido.

Aunque parezca lioso al leerlo, os recomiendo debuggear paso a paso la aplicación fijándoos bien en como se van rellenando los registros y la pila.

3 - Función FOR

Vamos a ver como podemos detectar que se está realizando un bucle en nuestro código.

image

Si os fijáis, podemos definir claramente cuatro partes de código que realizan funciones distintas.

  1. Prologo y declaración de variables.
  2. (loc_4013E7): Encargado de preparar los parámetros y llamar a la función printf. De esta parte podemos destacar la instrucción INC, la cual incrementará en uno el valor indicado [esp+28].
  3. (loc_4013FF): Parte encargada de verificar el estado del bucle. En esta parte nos encontramos con una nueva instrucción JLE (Jump if Less than or Equal) saltar si es menor o igual, que junto a la instrucción CMP anterior se forma la estructura de comparar el valor [esp+28] con 9, si el resultado es menor o igual la instrucción JLE nos hará saltar a (loc_4013E7), de lo contrario continuará con la zona 4.
  4. Epílogo de la función encargado de restaura la pila y retornamos a la función anterior.

De este modo, ya podremos identificar un bucle en código ensamblador.

Os dejo también el flowgraph que nos ofrece IDA PRO, el cual de forma gráfica nos ayuda a interpretar mucho más rápido que función está realizando el código analizado.

image

Esto es todo por hoy, en las próximas entregas seguiremos interpretando algo más de código para familiarizarnos aún más con todo este lio ;)

Un saludo!!

3 comentarios:

  1. Hace un año más o menos había leido la primer entrada de Introducción a la Ingenieria inversa en x86 pero me aleje lamentablemente de estos temas y me enfoque en la explotación de aplicaciones web.

    Hace dias que venia con ganas de volver a leerlo ya que me interesa tanto este tema como el desarrollo de exploits :)

    Te agradesco tu aporte y lo leere atentamente.

    ResponderEliminar