Boulet otra vez refleja la vida mejor que uno mismo.
Me pregunto... ¿cómo hace para meterse en mis pensamientos?
jueves, febrero 27, 2014
domingo, febrero 23, 2014
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.
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).
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:
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.
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.
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).
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)
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.
viernes, febrero 14, 2014
Traducción completa del manual del administrador de Debian
Raphaël Hertzog anunció la disponibilidad de las traducciones completas en Español y Francés del libro "The Debian Administrator's Handbook, Debian Wheezy from Discovery to Mastery" que escribiera en co-autoría con Roland Mas. Al día de hoy es quizás la referencia más completa, actualizada -y correcta, además- del sistema operativo Debian en su versión 7 (Wheezy).
La traducción en español fue llevada a cabo por Matías Bellone, Adrià García-Alzórriz, Rene Saavedra y otros colaboradores.
El libro puede adquirirse en papel, en digital, consultarse gratuitamente en línea o leerse localmente instalando el paquete debian-handbook (en este último caso, en inglés).
La traducción en español fue llevada a cabo por Matías Bellone, Adrià García-Alzórriz, Rene Saavedra y otros colaboradores.
El libro puede adquirirse en papel, en digital, consultarse gratuitamente en línea o leerse localmente instalando el paquete debian-handbook (en este último caso, en inglés).
Suscribirse a:
Entradas (Atom)