Analizando ejecutables de Windows con software libre

Tras haber repasado durante la creación de gpefile.py las estructuras internas del formato Portable Executable (PE) que describe a los ejecutables de Windows, otro de los pet projects en los que he picado código es un sencillo generador de gráficos de flujo de control (control flow graphs) para comprender el flujo de ejecución de los binarios de dicha plataforma.

Haciendo uso de pefile, pygraphviz y principalmente pymsasid, con unas 400 líneas de python es posible partir de un ejecutable cualquiera y obtener un gráfico como el siguiente.

autochk-fragment2autochk – full image (big!) – dot file


Desde luego este es un ejemplo extremadamente sencillo y trivial, analizando el binario
autochk.exe de ReactOS 0.3.16, un sistema operativo binary-compatible con Windows. El gráfico de flujo de control para un ejecutable moderno crece rápidamente a raíz de los distintos caminos que el compilador debe generar para representar las instrucciones presentes en el código fuente original de la utilidad (autochk.c).

El diagrama siguiente fue construido a partir del ejecutable hideflag.exe, que es un código histórico en este blog. He marcado en amarillo el bucle principal que se puede apreciar en el código fuente de la aplicación (en pascal, esta vez).

hideflag-fragment2hideflag – full image (big!) – dot file


Para el despliegue de los gráficos, dado que los visores en Debian se mambean con imagenes de varios megapíxeles (bugs
581891 y 163090 ya reportados en varios lugares), les recomiendo descargar los archivos .dot originales y visualizarlos directamente con la excelente utilidad xdot (también hecha en python, de paso).

En el diagrama, cada bloque básico inicia con un punto de entrada (primera instrucción a ejecutar, EIP, o destino de un salto) y finaliza con otro salto, una instrucción de retorno (ret), o bien abruptamente como resultado de un límite impuesto arbitrariamente por mí (esto último para evitar generar gráficos grandes con los cuales dot se marea, y créanme que algunos tardan más de diez minutos en desplegarse).

El bloque marcado en verde es comúnmente el primero en ejecutarse. Las flechas de colores indican, obviamente, el flujo de ejecución posible. Los códigos son los siguientes:

  • Flechas azules salto incondicional;
  • Flechas negras  continuación/fall-thru (instrucción que sigue directamente a la actual);
  • Flechas violetas llamada a función (sólo la ida, se asume que la llamada a función retorna a la instrucción siguiente);
  • Flechas verdes bloque a ejecutar en un salto condicional si la condición evaluada resulta verdadera;
  • Flechas rojas bloque a ejecutar en un salto condicional si la condición evaluada resulta falsa;
  • Flechas celestes callback al que apunta algún argumento del código (no implica que la función sea llamada en ese momento)

Las flechas punteadas representan saltos encadenados (JMP-to-JMP) que suelen verse en los binarios y que el script trata de reducir a fin de simplificar las secuencias en los gráficos generados (de ahí que el destino no coincida con las dirección del salto original, pero a la larga termina allí).

En algunas instrucciones, si el operador es una dirección de memoria válida y refiere a la sección de datos del ejecutable, el script añade el contenido de dicha dirección como comentario a la instrucción desensamblada (útil para ver cadenas de formato pasados como parámetro a llamadas a impresión en pantalla); si en cambio refiere a la sección de código, interpreta que se trata de un puntero a función utilizada como callback. De forma similar, trata de interpretar las llamadas a funciones de bibliotecas (resumiendo CALL y CALL-to-JMP) mediante información existente en la IAT si estuviera disponible.

Desde ya, el código que genera estos gráficos tiene innumerables errores y limitaciones (ej, evaluación de saltos indirectos, mejor detección de callbacks, interpretación de loop/loopX y muchas más cosas). En resumen, es sumamente borrador, por eso no lo puse en línea con esta entrada. En realidad lo estoy utilizando como preprocesador para una fase siguiente de decompilación. En cuanto lo tenga mas o menos prolijo lo subo a una cuenta de github, por si a alguno le interesa. También me va a servir a mí para acostumbrarme a usar ese servicio, hehe.

Lo curioso de todo es lo cómodo que resulta Debian para hacer análisis de ejecutables de Windows, jaj.

Desensamblando binarios en línea

oda_screenAnalizando un firmware desconocido? No tenés a mano nasm/ndisasm? No te acordás los opcodes de memoria?

Online Disassembler es el sueño de todo hacker: un desensamblador en línea. ODA soporta una gran cantidad de arquitecturas y tiene las heurísticas necesarias para interpretar la estructura de muchos archivos binarios (PE, ELF, etc.). Permite subir uno o varios archivos, o bien escribir los bytes en el cuadro de texto para ver qué representan.

Probemos con esto. A qué código C correspondería la siguiente secuencia?

55 89 e5 d9 45 08 d8 45 0c d9 05 a0 84 04 08 de f9 5d c3

Tips: la arquitectura es 32 bits, y en el valor almacenado en ds:0x80484a0 es 2.0 (en IEEE754 binary32). Facilísimo.

Pero ODA no es el único desensamblador en línea. Pym’s es un proyecto similar, hecho en python y también permite subir un archivo, desensamblarlo y navegar el código, aunque es más limitado en cuanto a las arquitecturas y tipos de archivo soportados. Aún así, es otra opción a considerar.

Bien, solo eso por ahora. Happy reversing!

Un vistazo a código de la demoscene ’93

Desde mis primeros años cerca de las computadoras siempre me fascinaron las demos.

No, no me refiero a las versiones recortadas de programas o juegos que se dan con fines comerciales, nada de eso. En nuestro contexto también se denominan demos a ciertas presentaciones multimedia creadas por programadores y artistas como una forma de arte alternativo y como muestra de sus capacidades.

Cualquiera que vea una demo en funcionamiento podría confundirla simplemente con un videoclip medio bizarro que se reproduce en la PC. A simple vista parecería ser sólo eso. Sin embargo, el archivo que almacena ese “video”, por así decirlo, suele pesar apenas 64 kilobytes, o incluso menos, 4 kilobytes; y una de las características que más asombran es precisamente esa: ¿cómo logran “almacenar” este tipo de animaciones en un archivo tan pequeño?

El truco, en realidad, radica en que el video en sí (y la música, normalmente) no está contenido en el archivo binario, sino que el binario es un archivo que al ejecutarse genera completamente la animación, como una especie de “mueble autoensamblable”.

Además de este detalle, los programadores de demos buscan aprovechar al máximo las características del hardware para el cual están trabajando, logrando animaciones que en muchos casos son impensables de ver en esos limitados equipos.

Buena parte de estas demos son creadas por grupos multidisciplinarios denominados demogroups, cuyos miembros son muy buscados por los departamentos de recursos humanos de la industria de videojuegos, sea como programadores, artistas gráficos o músicos, e incluso figuran entre los participantes de la reconocida conferencia académica de gráficos por computadora SIGGRAPH.

El coder aancsiid resume en pocos párrafos “Qué es una demo”, y los artículos Demo (Computer_programming) y Demoscene en Wikipedia son buenos puntos de partida para acercarse a la historia y las particularidades de las demos, pero lo que no pueden dejar de conocer son los clásicos sitios Pouet.net y Scene.org, dedicados exclusivamente a las obras de esta subcultura.

De las que me han dejado con la mente en blanco recuerdo a heaven seven de exceed, fr-041:debris de farbrausch,  elevated de rgba&tbc, chaos theory de conspiracy/cns, y las mas nuevas como agenda de fairlight, spin de asd.

Para que se den una idea, el ejecutable de heaven seven pesa 64 kilobytes, y logra todo esto …

con sólo 64 kilobytes !!!debris pesa 177 kilobytes, y la demo elevated pesa 4 kilobytes… Piensen que al día de hoy el código HTML de una página web pesa en promedio unos 52 kb, y una fotografía digital pesa por lo menos 3.000 kb. Esta gente logra toda una experiencia multimedia en apenas una fracción de eso… Pero no se queden con lo que les digo: si tienen una máquina a mano, bájense los binarios y ejecútenlos, para ver la realidad.

Cyberhades tiene también una buena lista de posts dedicados al tema, y precisamente es por ellos que me entero de que el grupo Future Crew ha dejado disponible el código fuente de la demo “Second Reality” con motivo del 20 aniversario de su creación.

Y aquí repito: el CÓDIGO FUENTE DE LA DEMO. Piensen que, dadas las exepcionales secuencias gráficas que los demogroups eran capaces de generar en aquella época, los hacks que éstos utilizaban para lograrlas eran secretos muy bien protegidos que muchas veces definían los primeros puestos en las competencias internacionales (demoparties). Por ello, poder acceder al código completo de una, ver su estructura interna y descifrar su funcionamiento es un regalo que hay que agradecer.

Además de felicitar a Future Crew por su amplia trayectoria, merece mis respetos Fabien Sanglard al acercarnos esta maravilla a los mortales mediante un ilustrado análisis de los fuentes de Second Reality que, por caso, contienen código en Assembler, C y Pascal. Recordemos que Sanglard nos viene deleitando ya con la aproximación al código fuente detrás de Prince of Persia, Doom y Quake.

Me encantaría seguir charlando de demos, pero mejor que eso es sentarse a ver algunas por demoscene.tv, capped.tv, o mejor, ejecutándolas en vivo en la PC.

Open Security Training, CS:APP y gPEFile

Finalizando las vacaciones, antes de reincorporarme al trabajo diario, dediqué unos días a seguir uno de los cursos de análisis de malware que tenía agendado desde hace tiempo, en este caso, el de Open Security Training.

La gente de OST provee el material, los ejemplos y los videos en línea para que uno vaya, a su tiempo, incorporando conocimientos repartidos en las siguientes clases:

Beginner Classes

Intermediate Classes

Advanced Classes

La primera clase sirve como base para las siguientes y discurre sobre los conceptos iniciales, describe el hardware sobre el que se programa en lenguaje ensamblador, describe con varios ejemplos las instrucciones del lenguaje más comunes, y muestra cómo seguir la ejecución de un programa con en Windows con Visual Studio Debugger (u OllyDbg, que no es tan distinto) y en GNU/Linux con gdb. Como bien hace mención el instructor, con conocer algunas pocas instrucciones ya es posible leer la mayoría de los programas.

La clase finaliza dejando como tarea el análisis y la resolución del clásico ejercicio de “bomba binaria” de la asignatura Arquitectura de Computadores de la Carnegie Mellon University, la cual requiere conocer técnicas básicas de ingeniería inversa para progresar a traves de las diferentes fases de la bomba, dando las respuestas correctas y evitando “explotarla”. Sin duda es un ejercicio que me ha entretenido mucho, me ha hecho pensar bastante, y que realmente debo recomendar como un buen inicio al arte de la ingeniería inversa.

Buscando información sobre el tema dí con el libro de cabecera de tal asignatura: Computer Systems: A Programmer’s Perspective, cuya edición 2011 es altamente recomendable. Está escrito en un lenguaje claro pero detallado, con ejemplos concretos (casi diría “palpables”) para explicar las abstracciones de sistema, y con un amplio conjunto de ejercicios para realizar. El sitio web contiene algunas secciones de ejemplo que sirven como preview, así como también material adicional al texto en papel. En retrospectiva, es el libro que me tendrían que haber recomendado cuando cursé las materias de arquitectura.

La clase “The Life of Binaries” trata efectivamente sobre “la vida de los ejecutables”, desde su creación: parsing del código fuente, abstract syntax trees, estrategias de compilación, lenguajes intermedios, enlazado del binario final; hasta su carga en memoria por el loader del sistema operativo y posterior ejecución en el computador. Se dan descripciones detalladas sobre los formatos binarios Portable Executable (PE) de Windows y Executable and Linkable Format (ELF) de Linux. El recorrido por el formato PE y su estructura, basado en el trabajo realizado por Ero Carrera, es muy completo y esclarecedor. La clase abarca también algunas de las técnicas que de ocultamiento y hooking utilizadas comúnmente en el malware, cómo funcionan realmente los virus de computadora, y qué técnicas es posible utilizar fácilmente para brindar mayor seguridad a los binarios que se generan.

A partir de esta clase se me ocurrió aprovechar el excelente trabajo realizado por Carrera con la biblioteca pefile y desarrollar con python-gtk2 un visor de archivos PE para interfaz gráfica, inspirado en el utilizado en los videos de entrenamiento. Dejo algunas capturas de la primera versión que no da vergüenza mostrar. El código, como siempre, se puede descargar desde el link que sigue y las correcciones y sugerencias serán bienvenidas.

Descargar: gpefile.py (v0.19, 78 KB)

Último cambio: Agregado despliegue de recursos RT_BITMAP, RT_GROUP_CURSOR, RT_GROUP_ICON, RT_STRING, GIF y PNG.

Me queda pendiente continuar con las clases siguientes, en cuanto el tiempo me lo permita. A la gente detrás del proyecto de Open Security Training, mi sincero agradecimiento por la dedicación y por el material brindado generosamente a la comunidad.

Adios a un maestro

Me entero por Tech Source from Bohol (y por reddit, pero no por slashdot, curiosamente) de una triste noticia: Fravia+ nos ha dejado tras una difícil enfermedad.

Para quienes hemos hecho andanzas en cracking y en la ingeniería inversa, Fravia ha sido mucho más que un maestro. Por mi parte, alrededor del año 98 tuve acceso por primera vez (y con un viejo módem Zoltrix de 33,6kbps) a la web [http://fravia.com] que mantuvo hasta su muerte y que es uno de los más completos repositorios de documentación sobre ingeniería inversa, con excelentes artículos de su autoría y de varios contribuyentes. Su web, replicada en varios mirrors por el mundo, es por así decirlo una especie de portal del tiempo, lo podrán ver por el estilo que conservó desde su creación; y a la vez un acervo muy completo de conocimiento, pero sólo para aquellos que saben encontrarlo.

Fiel a su estilo, antes de partir nos dejó un mensaje de despedida: Sour ‘n Sweet Swan Song.

Desde este humilde espacio vayan mi agradecimiento y mis más sinceros respetos. Y como rezaba en los artículos, recuerden:

There is a crack, a crack in everything.
That’s how the light gets in.

Copyright © All Rights Reserved · Green Hope Theme by Sivan & schiy · Proudly powered by WordPress