{"id":816,"date":"2014-02-23T10:30:34","date_gmt":"2014-02-23T13:30:34","guid":{"rendered":"http:\/\/www.maurom.com\/blog\/?p=816"},"modified":"2017-07-05T19:32:30","modified_gmt":"2017-07-05T22:32:30","slug":"analizando-ejecutables-de-windows-con-software-libre","status":"publish","type":"post","link":"https:\/\/maurom.com\/blog\/2014\/02\/23\/analizando-ejecutables-de-windows-con-software-libre\/","title":{"rendered":"Analizando ejecutables de Windows con software libre"},"content":{"rendered":"<p>Tras haber repasado durante la creaci\u00f3n de\u00a0<a href=\"\/blog\/2012\/03\/01\/open-security-training-csapp-y-gpefile\/\">gpefile.py<\/a>\u00a0las estructuras internas del formato <a href=\"http:\/\/en.wikipedia.org\/wiki\/Portable_Executable\">Portable Executable (PE)<\/a>\u00a0que describe a los ejecutables de Windows, otro de los <em>pet projects<\/em> en los que he picado c\u00f3digo es un sencillo generador de gr\u00e1ficos de flujo de control (<a href=\"http:\/\/en.wikipedia.org\/wiki\/Control_flow_graph\">control flow graphs<\/a>) para comprender el flujo de ejecuci\u00f3n de los binarios de dicha plataforma.<\/p>\n<p>Haciendo uso de\u00a0<a href=\"https:\/\/code.google.com\/p\/pefile\/\">pefile<\/a>, <a href=\"http:\/\/pygraphviz.github.io\/\">pygraphviz<\/a>\u00a0y principalmente\u00a0<a href=\"http:\/\/code.google.com\/p\/pymsasid\/\">pymsasid<\/a>, con unas 400 l\u00edneas de python es posible partir de un ejecutable cualquiera y obtener un gr\u00e1fico como el siguiente.<\/p>\n<div align=\"center\"><a href=\"http:\/\/www.maurom.com\/blog\/wp-content\/uploads\/2014\/02\/autochk.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-849\" alt=\"autochk-fragment2\" src=\"\/\/maurom.com\/blog\/wp-content\/uploads\/2014\/02\/autochk-fragment2.png\" width=\"861\" height=\"396\" srcset=\"https:\/\/maurom.com\/blog\/wp-content\/uploads\/2014\/02\/autochk-fragment2.png 861w, https:\/\/maurom.com\/blog\/wp-content\/uploads\/2014\/02\/autochk-fragment2-300x137.png 300w\" sizes=\"(max-width: 861px) 100vw, 861px\" \/><\/a><em>autochk &#8211;\u00a0<a href=\"\/blog\/wp-content\/uploads\/2014\/02\/autochk.png\">full image<\/a>\u00a0(big!) &#8211; <a href=\"\/blog\/wp-content\/uploads\/2014\/02\/autochk.dot\">dot file<\/a><br \/>\n<\/em><\/div>\n<p><span style=\"line-height: 1.5em;\"><br \/>\nDesde luego este es un ejemplo extremadamente sencillo y trivial, analizando el binario <\/span><em><span style=\"line-height: 1.5em;\">autochk.exe<\/span><\/em><span style=\"line-height: 1.5em;\">\u00a0de <\/span><a style=\"line-height: 1.5em;\" href=\"http:\/\/www.reactos.org\/\">ReactOS 0.3.16<\/a><span style=\"line-height: 1.5em;\">, un sistema operativo binary-compatible con Windows. El gr\u00e1fico de flujo de control para un ejecutable moderno crece r\u00e1pidamente a ra\u00edz de los distintos caminos que el compilador debe generar para representar las instrucciones presentes en el c\u00f3digo fuente original de la utilidad (<\/span><a style=\"line-height: 1.5em;\" href=\"http:\/\/code.reactos.org\/browse\/~raw,r=60656\/reactos\/trunk\/reactos\/base\/system\/autochk\/autochk.c\">autochk.c<\/a><span style=\"line-height: 1.5em;\">).<\/span><\/p>\n<p>El diagrama siguiente fue construido a partir del ejecutable <em><a href=\"http:\/\/www.maurom.com\/files\/hideflag_bitnegro.blogspot.com.zip\">hideflag.exe<\/a><\/em>, que es un c\u00f3digo <a href=\"\/blog\/2007\/08\/16\/la-molesta-marca-de-agua-del-starter-edition\/\">hist\u00f3rico en este blog<\/a>. He marcado en amarillo el bucle principal que se puede apreciar en el c\u00f3digo fuente de la aplicaci\u00f3n (en pascal, esta vez).<\/p>\n<div align=\"center\"><em><a href=\"http:\/\/www.maurom.com\/blog\/wp-content\/uploads\/2014\/02\/hideflag.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-850\" alt=\"hideflag-fragment2\" src=\"\/\/maurom.com\/blog\/wp-content\/uploads\/2014\/02\/hideflag-fragment2.png\" width=\"870\" height=\"289\" srcset=\"https:\/\/maurom.com\/blog\/wp-content\/uploads\/2014\/02\/hideflag-fragment2.png 870w, https:\/\/maurom.com\/blog\/wp-content\/uploads\/2014\/02\/hideflag-fragment2-300x99.png 300w\" sizes=\"(max-width: 870px) 100vw, 870px\" \/><\/a>hideflag &#8211;\u00a0<a href=\"\/blog\/wp-content\/uploads\/2014\/02\/hideflag.png\">full image<\/a>\u00a0(big!) &#8211;\u00a0<a href=\"\/blog\/wp-content\/uploads\/2014\/02\/hideflag.dot\">dot file<\/a><br \/>\n<\/em><\/div>\n<p><span style=\"line-height: 1.5em;\"><br \/>\nPara el despliegue de los gr\u00e1ficos, dado que los visores en Debian se mambean con imagenes de varios megap\u00edxeles (bugs <\/span><a style=\"line-height: 1.5em;\" href=\"http:\/\/bugs.debian.org\/581891\">581891<\/a><span style=\"line-height: 1.5em;\"> y <\/span><a style=\"line-height: 1.5em;\" href=\"https:\/\/bugzilla.gnome.org\/show_bug.cgi?id=163090\">163090<\/a><span style=\"line-height: 1.5em;\"> ya reportados en varios lugares), les recomiendo descargar los archivos <\/span><em style=\"line-height: 1.5em;\">.dot<\/em><span style=\"line-height: 1.5em;\"> originales\u00a0y visualizarlos directamente con la excelente utilidad <\/span><em><a style=\"line-height: 1.5em;\" href=\"https:\/\/github.com\/jrfonseca\/xdot.py\">xdot<\/a><\/em><span style=\"line-height: 1.5em;\">\u00a0(tambi\u00e9n hecha en python, de paso).<\/span><\/p>\n<p>En el diagrama, cada <a href=\"http:\/\/en.wikipedia.org\/wiki\/Basic_block\">bloque b\u00e1sico<\/a>\u00a0inicia con un punto de entrada (primera instrucci\u00f3n a ejecutar, EIP, o destino de un salto) y finaliza con otro salto, una instrucci\u00f3n de retorno (<em>ret<\/em>), o bien abruptamente como resultado de un l\u00edmite impuesto arbitrariamente por m\u00ed (esto \u00faltimo para evitar generar gr\u00e1ficos grandes con los cuales <em>dot<\/em> se marea, y cr\u00e9anme que algunos tardan m\u00e1s de diez minutos en desplegarse).<\/p>\n<p>El bloque marcado en <span style=\"font-weight: bold; color: green;\">verde<\/span> es com\u00fanmente el primero en ejecutarse. Las flechas de colores indican, obviamente, el flujo de ejecuci\u00f3n posible. Los c\u00f3digos son los siguientes:<\/p>\n<ul>\n<li><span style=\"color: blue;\"><strong>Flechas azules<\/strong> <span style=\"line-height: 100%; font-size: 150%; vertical-align: middle;\">\u279e<\/span><\/span> salto incondicional;<\/li>\n<li><span style=\"color: black;\"><strong>Flechas negras<\/strong> <span style=\"line-height: 100%; font-size: 150%; vertical-align: middle;\">\u279e<\/span><\/span>\u00a0continuaci\u00f3n\/fall-thru (instrucci\u00f3n que sigue directamente a la actual);<\/li>\n<li><span style=\"color: violet;\"><strong>Flechas violetas<\/strong> <span style=\"line-height: 100%; font-size: 150%; vertical-align: middle;\">\u279e<\/span><\/span> llamada a funci\u00f3n (s\u00f3lo la ida, se asume que la llamada a funci\u00f3n retorna a la instrucci\u00f3n siguiente);<\/li>\n<li><span style=\"color: green;\"><strong>Flechas verdes<\/strong> <span style=\"line-height: 100%; font-size: 150%; vertical-align: middle;\">\u279e<\/span><\/span> bloque a ejecutar en un salto condicional si la condici\u00f3n evaluada resulta verdadera;<\/li>\n<li><span style=\"color: red;\"><strong>Flechas rojas<\/strong> <span style=\"line-height: 100%; font-size: 150%; vertical-align: middle;\">\u279e<\/span><\/span> bloque a ejecutar en un salto condicional si la condici\u00f3n evaluada resulta falsa;<\/li>\n<li><span style=\"color: lightblue;\"><strong>Flechas celestes<\/strong> <span style=\"line-height: 100%; font-size: 150%; vertical-align: middle;\">\u279e<\/span><\/span> callback al que apunta alg\u00fan argumento del c\u00f3digo (no implica que la funci\u00f3n sea llamada en ese momento)<\/li>\n<\/ul>\n<p>Las flechas punteadas <span style=\"line-height: 100%; font-size: 150%; vertical-align: middle;\">\u21e2<\/span> representan saltos encadenados (<em>JMP-to-JMP<\/em>) que suelen verse en los binarios y que el script trata de reducir a fin de simplificar las secuencias en los gr\u00e1ficos generados (de ah\u00ed que el destino no coincida con las direcci\u00f3n del salto original, pero a la larga termina all\u00ed).<\/p>\n<p>En algunas instrucciones, si el operador es una direcci\u00f3n de memoria v\u00e1lida y refiere a la secci\u00f3n de datos del ejecutable, el script a\u00f1ade el contenido de dicha direcci\u00f3n como comentario a la instrucci\u00f3n desensamblada (\u00fatil para ver cadenas de formato pasados como par\u00e1metro a llamadas a impresi\u00f3n en pantalla); si en cambio refiere a la secci\u00f3n de c\u00f3digo, interpreta que se trata de un puntero a funci\u00f3n utilizada como callback. De forma similar, trata de interpretar las llamadas a funciones de bibliotecas (resumiendo <em>CALL<\/em> y <em>CALL-to-JMP<\/em>) mediante informaci\u00f3n existente en la <a href=\"http:\/\/www.karmany.net\/index.php\/ingenieria-inversa\/19-ingenieria-inversa-novatos\/146-pe-header-que-es-la-iat-import-address-table\">IAT<\/a> si estuviera disponible.<\/p>\n<p>Desde ya, el c\u00f3digo que genera estos gr\u00e1ficos tiene innumerables errores y limitaciones (ej, evaluaci\u00f3n de <a href=\"http:\/\/en.wikipedia.org\/wiki\/Indirect_branch\">saltos indirectos<\/a>, mejor detecci\u00f3n de <a href=\"http:\/\/en.wikipedia.org\/wiki\/Callback_(computer_programming)\">callbacks<\/a>, interpretaci\u00f3n de <em>loop\/loopX<\/em>\u00a0y muchas m\u00e1s cosas). En resumen, <strong>es\u00a0sumamente\u00a0borrador<\/strong>, por eso no lo puse en l\u00ednea con esta entrada. En realidad lo estoy utilizando como preprocesador para una fase siguiente de <a href=\"http:\/\/en.wikipedia.org\/wiki\/Decompiler\">decompilaci\u00f3n<\/a>. En cuanto lo tenga mas o menos prolijo lo subo a una cuenta de github, por si a alguno le interesa. Tambi\u00e9n me va a servir a m\u00ed para acostumbrarme a usar ese servicio, hehe.<\/p>\n<p>Lo curioso de todo es lo c\u00f3modo que resulta Debian para hacer an\u00e1lisis de ejecutables de Windows, jaj.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Tras haber repasado durante la creaci\u00f3n de\u00a0gpefile.py\u00a0las estructuras internas del formato Portable Executable (PE)\u00a0que describe a los ejecutables de Windows, otro de los pet projects en los que he picado c\u00f3digo es un sencillo generador de gr\u00e1ficos de flujo de control (control flow graphs) para comprender el flujo de ejecuci\u00f3n de los binarios de dicha [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[8,9,10,6],"_links":{"self":[{"href":"https:\/\/maurom.com\/blog\/wp-json\/wp\/v2\/posts\/816"}],"collection":[{"href":"https:\/\/maurom.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/maurom.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/maurom.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/maurom.com\/blog\/wp-json\/wp\/v2\/comments?post=816"}],"version-history":[{"count":1,"href":"https:\/\/maurom.com\/blog\/wp-json\/wp\/v2\/posts\/816\/revisions"}],"predecessor-version":[{"id":1589,"href":"https:\/\/maurom.com\/blog\/wp-json\/wp\/v2\/posts\/816\/revisions\/1589"}],"wp:attachment":[{"href":"https:\/\/maurom.com\/blog\/wp-json\/wp\/v2\/media?parent=816"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/maurom.com\/blog\/wp-json\/wp\/v2\/categories?post=816"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/maurom.com\/blog\/wp-json\/wp\/v2\/tags?post=816"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}