con ejemplos. - brainoverflow.org
Transcripción
con ejemplos. - brainoverflow.org
… con ejemplos. Sitio Web: http://www.resrever.net Contacto: [email protected] Última actualización: 28/10/2012 Pwneando Ensamblador (con Ejemplos) by Christian Navarrete is licensed under a Creative Commons Reconocimiento-NoComercial-SinObraDerivada 3.0 Unported License . 1 Agradecimientos Quiero dar las gracias principalmente a Ricardo Narvaja que aunque no tengo el gusto de conocerlo fue mi inspiración para realizar este e-Book. Son ese tipo de personas que regala todo su conocimiento sin esperar nada a cambio. De igual modo quiero agradecer a la “Mexican g4ng-bang”, a mis grandes amigos desde hace ya muchos años con los cuales he pasado muy buenos momentos a su lado, buenos, malos, pero siempre juntos, y ellas son (por orden alfabético, para no herir sentimientos XD) Lilith alt3kx b0rr3x b3ck calderpwn chipx0r ch0ks Carlos Ayala Daemon Dex Despise hkm hecky nitr0us NataShell666 preth00nker r1lx0r Raito …y a toda la lista interminable de amigos y seguidores de Twitter. ¡Gracias! 2 Contenido Introducción ........................................................................................................................4 ¿Por qué aprender Ensamblador?......................................................................................4 ¿Por qué Ensamblador e Ingeniería Inversa de Código (RCE)?..............................................4 Temas y Objetivo..............................................................................................................6 Notas finales ....................................................................................................................6 Requerimientos....................................................................................................................7 Instalación de MASM32 ........................................................................................................7 Instalación y Configuración de WinAsm Studio .......................................................................8 Comprobación de funcionamiento: WinAsm Studio y MASM32...............................................9 Instalación de Visual C++ 2005 Express ................................................................................11 Instalación de Cygwin (Compilador gcc) ...............................................................................12 Instalación y Configuración de OllyDBG ...............................................................................14 Instalación de IDA Freeware................................................................................................17 Importancia del dominio de las Herramientas ......................................................................19 Conociendo la interfaz y funcionamiento de OllyDbg ............................................................19 Conociendo la interfaz y funcionamiento de IDA Dissassembler ............................................37 Estructura de un Programa en Ensamblador ........................................................................50 Entendiendo los Registros del CPU ......................................................................................52 Aprendiendo el Set de Instrucciones x86..............................................................................52 La instrucción - INC.............................................................................................................52 3 Introducción Como diría mi hermano @r1lx0r... “Endúlzame el oído” y convénceme de utilizar Ensamblador. Bien, pues aquí va mi “sp33ch”! Como muchos ya lo saben y para los que apenas se enteran, este es un nuevo proyecto el cual he querido realizar desde hace ya hace bastante tiempo y heme aquí, tomando una copa de vino tinto chileno… escuchando mi canción favorita de Hall & Oates – Out of touch y decidido a escribir el inicio de esta historia. Hehe, en fin, aquí vamos… ¿Por qué aprender Ensamblador? ENSAMBLADOR. Si, y con letras MAYUSCULAS. Sin duda es una palabra a la cual se le merece un profundo respeto. Es una palabra que a muchos causa miedo, y temo decir que es correcta dicha apreciación, sin embargo, no es tan “rudo” como parece. El problema con el lenguaje ensamblador es que la gente que hoy en día se encuentra interesada en aprender ensamblador se topa de primer instancia con la falta información acerca de cómo programar en este lenguaje, aunado a la poca información existente que es muy obsoleta – ¿Ensamblador para DOS?-. Ya no es como hace muchos años, en los cuales existía mucha información al respecto, la escena en su máximo esplendor… la Phrozen Crew, el grupo 29a, Fravia y +ORC… mucha gente –en especial los Argentinos y Españoles- le pegaron durísimo a todas aquellas “artes oscuras” y que hoy en día, aún permanecen haciéndolo. Personalidades como Ricardo Narvaja, Nahuel Riva, Rubén SantaMarta, Dave Aitel, o Gerardo Richarte son algunos de los nombres figuran en este campo. Ahora, uno tiene que arreglárselas por su propia mano y tratar de encontrar el máximo de recursos para poder aprenderlo tan bien y como se hacía en esos años. Ese ha sido el reto que me ha orillado a iniciar con este proyecto, ya que como se imaginan, pasé por el mismo problema y decidí hacerle la vida menos pesada a la gente interesada en este tema. ¿Por qué Ensamblador e Ingeniería Inversa de Código (RCE)? La respuesta es muy simple y obvia. No me dejarán mentir aquellas personas que al igual que yo hemos tenido una larga trayectoria en la cuestión de seguridad. Lamentablemente se nos ha orillado a ser los “Sabelotodo” y muy pocas veces uno que otro ha logrado especializarse en un tema en particular. En mi caso, buscando algún área que pudiera considerar como un “real challenge”… algo que sobresaliera de las demás áreas en el cual “todos” son expertos. Sabemos que cualquiera pueda explotar un SQL Injection, descargar y compilar exploits, Defacear un sitio Web o utilizar Frameworks de explotación, pero pocos pueden entender/programar en Ensamblador y muy pocos pueden realizar Ingeniería Inversa. Aquí la diferencia. 4 Hoy día he llegado a la conclusión de buscar dicha especialización, es por eso que me he decidido el enfocar mi carrera profesional al estudio y al “mastering” del arte del RCE. Hablemos un poco de aquellos temas que utilizan Ensamblador e Ingeniería Inversa. Malware - Sabemos que se pueden utilizar lenguajes de programación de Alto nivel para hacer un simple virus, es más, un simple script podría ser un virus. ¡Ja! ¿Pero en dónde queda Ensamblador? Bien, pues en aquellos años muchos de los virus que se han creado han sido en lenguaje ensamblador y esto es simplemente por la capacidad que tiene el propio lenguaje que en conjunto la integración y uso de los recursos del sistema operativo permita realizar tareas a un nivel muy bajo y por lo cual tener la capacidad de ejecutar tareas muy específicas, tareas con las cuales probablemente con un lenguaje de alto nivel sea un poco más difícil. Un ejemplo práctico y puntual. Muchos de los virus que han sido creados en lenguajes como C++, VB o .NET -por mencionar algunos-, hacen referencia y uso a ciertas librerías que no son “nativas” del S.O., lo cual desde el punto de vista de un malware developer, no sería muy práctico en cuanto a la “dependencia” del propio virus al utilizar dichas librerías. ¿Para qué utilizar librerías si puedes hacer uso de la API del S.O. con ayuda de Ensamblador? Si bien es cierto se pueden llamar o generar rutinas de Ensamblador dentro de código de otros lenguajes, pero bueno, esa es otra historia. Cracking – Estoy seguro les suena conocido. Como sabrán de igual modo se requiere conocimiento de lenguaje Ensamblador para poder meterse a esta actividad y probablemente un poco acerca de otros lenguajes, por aquello de crear algún Keygen o alguna herramientilla por ahí. La ventaja del Cracking es que existen aún material no tan anticuado el cual tocan temas acerca de cómo auto-entrenarse utilizando programas “Crackme”. ¿Cómo entra en acción Ensamblador en esta área? Sencillo. Si en algún momento te has bajado un Tuto de cracking, supongo que te suena familiar el nombre de la herramienta Ollydbg, pues bueno, para utilizarla necesitas saber Ensamblador, por lo menos lo básico, sin embargo, si estas tomando este asunto enserio entonces deberás de incrementar tu conocimiento en Ensamblador al máximo nivel. Siempre es divertido estar jugando en el “Lado oscuro de la fuerza”, sin embargo existen grandes riesgos con la cuestión de crackear software comercial por lo que hay que irse con cuidado con este tema. Vulnerabilidades – Oh yeah baby! - Cuando hablamos de descubrir vulnerabilidades sabemos que existen diferentes métodos y técnicas para llevarlo a cabo. Es aquí donde palabras como Fuzzing, Análisis Dinámico/Estático o Auditoría de Código entran en acción, sin embargo la mejor forma –y tal vez no la más trivial- de encontrar vulnerabilidades es a través del Análisis Binario. Compañías como Secunia, VUPEN, CORE Security o Immunity Inc. son algunas de las empresas que utilizan gran parte del conocimiento de lenguaje ensamblador para poder realizar este tipo de actividades. 5 Actividades que van desde el “reversing” de Software así como el de la realización de exploits para aprovecharse de dichas vulnerabilidades. Si lo que estas buscando es una carrera formal en RCE, encontrar vulnerabilidades 0-day en Software de alto perfil y probablemente ser entrevistado en algunas revistas, definitivamente tienes que dominar Ensamblador como primer prioridad. Como se habrán dado cuenta, Ensamblador es una pieza esencial para la rea lización de este tipo de actividades, afortunadamente todas las herramientas pueden ser utilizadas –y combinadas- acorde a tu necesidad. Por ejemplo; podrías utilizar OllyDBG para realizar un análisis dinámico de tus muestras de malware, ó si estás dispues to a tomar el reto de resolver un Crackme o en su caso utilizarlo para analizar un software en busca de vulnerabilidades. Así que si te especializas en una herramienta, estarás matando dos pájaros de un tiro… o más. Temas y Objetivo Esta es una pregunta interesante. Planeo cubrir temas relacionados a RCE, Ensamblador x86/IA32 (principalmente) en plataforma Windows (Win32), Linux (POSIX) y algunas otras arquitecturas, y muchas cosas más. Sin embargo, conforme vayamos avanzando es como iremos cubriendo dichos temas. El objetivo es obvio... APRENDER. Tú sabrás como utilizar el conocimiento. Manejaré un esquema de adquisición del conocimiento de manera empírica… más práctico que teórico, o lo que es lo mismo, aprenderemos la teoría sobre la práctica. Si tienes conocimiento en el tema y deseas ayudar, bienvenido(a). Notas finales No me considero ni creo ser un experto en el tema, por lo cual el contenido de esta serie de posts podrían contener algunos errores por lo cual cualquier sugerencia es bienvenida. Para las críticas no-constructivas, ahórrense su tiempo. Como dicen... Si no ayudas no estorbes. Sin ofender. Quiero agradecer de antemano a todos aquellos amigos con los que hemos pasado grandes momentos desde hace ya muchísimos años. Para concluir con esta entrada me gustaría dejar unas palabras de +ORC... "Give a man a crack, and he'll be hungry again tomorrow, teach him how to crack, and he'll never be hungry again". Enfoquen la fuerza de este mensaje a donde ustedes deseen. Bien, el momento ha llegado. Es tiempo de que empecemos a poner manos a la obra. 6 Antes que nada, asumo que ustedes… 1. No tienen problema con el idioma Inglés – Esto es esencial ya que *casi* toda la información disponible se encuentra en este idioma. 2. Manejo y entendimiento básico de programación con ANSI C/C++ o algún otro lenguaje de Alto nivel, así como el uso de sus respectivos compiladores. 3. Tienen experiencia trabajando con Máquinas Virtuales – Requeriremos de un entorno virtual para poder trabajar durante todas las sesiones. Requerimientos Hasta este momento deben contar con lo siguiente: 1. Máquina virtual con Windows XP (de preferencia sin Service Pack). No importa si utilizan VMWare o VirtualBox. En lo personal recomiendo VirtualBox ya que como saben es gratuito y se evitan problemas futuros con respecto a actualizaciones y similares. 2. Haber descargado el Software que se encuentra en la siguiente dirección: http://www.resrever.net/p/software.html . OJO: Solamente descargado (no instalarlo). Hay algunas adecuaciones que tendremos que realizar a la configuración del software para que puedan interactuar entre ellos sin ningún problema. El proceso de instalación/configuración, dependiendo el caso los estaremos cubriendo en las siguientes secciones. Instalación de MASM32 ¡Amonos Rickys! Es hora de instalar el corazón de todo este asunto de Ensamblador y me refiero al Compilador y Linker los cuales nos permitirán convertir nuestro código en Ensamblador a un hermoso archivo ejecutable. Pasos a seguir: 1. 2. 3. 4. 5. 7 Descargar el archivo .zip (masm32v11r.zip) que contiene MASM32. Ejecutamos el instalador (install.exe) Seguir el wizard, no hay pierde, hasta concluir con la instalación. Confirmar que el path al final de la instalación sea: “C:\masm32”. Al finalizar, se ejecutará automáticamente el IDE que trae por default MASM32. ¡No se espanten! Sabemos que no es muy agraciado y por lo cual utilizaremos un IDE que nos inspire programar en Ensamblador. Instalación y Configuración de WinAsm Studio Para poder generar nuestro código en ensamblador vamos a requerir de un IDE. El IDE que elegí para trabajar es WinAsm Studio y prácticamente cuenta con una Interfaz muy accesible e intuitiva. Una de las mejores características de este software es que ya está “configurado” para trabajar con MASM32 (Compilador y Linker) y de igual modo ya tiene una integración con OllyDbg el cual nos será de gran utilidad en las prácticas posteriores. Pasos a seguir: 1. 2. 3. 4. Descargar el archivo .zip (WinAsm515Full.zip) que contiene WinAsm Studio. Descomprimir el contenido en “c:\WinAsm”. Ejecutar el IDE (WinAsm.exe). Creen un nuevo folder en el cual vamos a ir guardando todos los programas que vayamos generando. En mi caso es “c:\reversing”. 5. En el menú “Tools => Options => Files & Paths” verán que el IDE ya trae configurados los paths de MASM32 y del propio WinAsm. 6. En la sección “Projects Path”, den click y seleccionen “c:\reversing”. Como nota adicional. Recuerden que deben respetar los paths de las herramientas y no crear folders especiales para de este modo no experimentemos algún problema después. Ahora, en la pestaña “Miscellaneous” veremos que de igual modo que OllyDbg es el debugger por default del IDE. 8 Comprobación de funcionamiento: WinAsm Studio y MASM32 ¡Perfecto! Hasta este momento tenemos el Compilador, Linker y nuestro IDE instalados. Ahora, probemos que no hay ningún problema y generemos un pequeño programa de prueba. Para algunos se les hará conocido el ya famoso programa de prueba de programación en Ensamblador para Win32 de Iczelion. Bueno, pues éste mismo será el que utilizaremos. Pasos a seguir: 1. Abran WinAsm Studio. 2. En el menú, “File => New project”, seleccionen: Standard Exe 3. Copien el siguiente código a WinAsm Studio: 9 .386 .model flat,stdcall option casemap:none include \masm32\include\windows.inc include \masm32\include\kernel32.inc includelib \masm32\lib\kernel32.lib include \masm32\include\user32.inc includelib \masm32\lib\user32.lib .data MsgBoxCaption MsgBoxText db "Resrever.Net",0 db "Ensamblador r0x!",0 .code start: invoke MessageBox, NULL, addr MsgBoxText, addr MsgBoxCaption, MB_OK invoke ExitProcess, NULL end start Y guarden el archivo como: “c:\reversing\programa1.asm” 4. Den click en el menú: “File => Save Project As” y les pedirá que asignen un nombre al proyecto. Pueden utilizar el mismo nombre del proyecto para su programa. 5. Ahora vayan al menú: “Make => Go All” o la combinación de teclas: Shift + F8 para “compilar y linkear” el código ensamblador. Posterior a esta acción aparecerá de forma automática la siguiente ventana: 10 Nice, eso quiere decir que nuestra instalación de WinAsm Studio y MASM32 está trabajando a la perfección. Si a este momento a ustedes no les apareció la pantalla anterior, verifiquen que paso omitieron. Finalmente, nuestra carpeta “c:\reversing” debe lucir de la siguiente manera: Se preguntarán en este momento que significa todo ese código que pegamos en WinAsm Studio, pues bien, no se preocupen ya que explicaremos la función de cada uno y de igual manera agregaré ligas a sitios en donde profundizan en la estructura del programa, opciones de configuración y demás. El objetivo de este paso fue básicamente verificar que todo este correcto y en perfecto orden. Instalación de Visual C++ 2005 Express Otro de los componentes esenciales es el compilador de C++. Vamos a utilizar esta herramienta para generar pequeños programas en C que al momento de compilarlos podamos de igual modo generar su respectivo código en Ensamblador. Esto es muy interesante ya que podremos visualizar un mismo código desde dos perspectivas (lenguajes) diferentes. 11 Pasos a seguir: 1. Descargar el archivo .exe (vcsetup.exe) que descargará los archivos necesarios para instalar Visual C++ 2005 Express. 2. Instalamos el compilador. 3. Terminamos. La etapa de configuración la realizaremos cuando vayamos a generar el primer programa en C/C++. Instalación de Cygwin (Compilador gcc) Cygwin es básicamente un paquete que simula el entorno UNIX/Linux bajo Windows. A lo largo de las prácticas nos encontraremos con la necesidad de utilizar el compilador “gcc” que al igual que con Visual C++ generaremos código C y al mismo tiempo generando código Ensamblador pero ahora con una ventaja más; en sus diferentes sintaxis: Intel y AT&T. Pasos a seguir: 1. Descargar el archivo .exe (setup.exe) que descargará los archivos necesarios para instalar Cygwin. 2. Continuamos la instalación normalmente. 3. Al momento de que nos pida seleccionar los paquetes; en el campo “Search” vamos a escribir: gcc y dentro de “Devel” damos doble click en “gcc-core: C compiler” como lo muestra la siguiente pantalla: 4. La siguiente ventana nos indicará las dependencias de gcc-core (binutils, gcc-mingw-core, etc.). Dejamos la opción default y continuamos. 12 5. Al finalizar, nos presentará una pantalla preguntando si queremos generar los iconos de acceso directo, dejamos seleccionadas dichas opciones y finalizamos la instalación. 6. Veremos que en el Escritorio ya tenemos el acceso directo a Cygwin y accedemos a él. 7. Al entrar en la Shell de Cygwin, vamos a teclear: “gcc –v” para confirmar que el compilador gcc ha sido instalado correctamente. En caso afirmativo veremos una pantalla igual a la que se muestra a continuación: 13 Instalación y Configuración de OllyDBG OllyDbg es una herramienta “De facto” en la cuestión de debuggear aplicaciones y hay muchas áreas que hacen uso de ella. Por ejemplo; los analistas de Malware las utilizan para realizar un análisis dinámico de sus muestras (samples). Los crackers lo utilizan para identificar los puntos de entrada de datos (inputs) o para analizar – o tratar de identificar- los algoritmos utilizados para la protección de un software... ó los security researchers quienes de igual modo lo utilizan para identificar el punto de quiebre de un software y de este modo determinar el “fault” que les permitirá de algún modo controlar dicho comportamiento y convertirlo posteriormente en una vulnerabilidad explotable. ¿Interesante no? Bueno, OllyDbg es nuestro mejor amigo desde este momento. Pasos a seguir: 1. Descargar el archivo .zip (odbg110.zip) que contiene OllyDbg. 2. Extraer el contenido del archivo en “c:\OllyDbg”. 3. Aparecerá una ventana mostrando lo siguiente: Simplemente den click en “Si” para continuar. Esto es simplemente para decirle a OllyDbg cual DLL utilizar, si la propia de la herramienta o la del SO. 4. Den click en el menu: “Options => Just in-time debugging” 5. Den click en las opciones: “Make OllyDbg just-in-time debugger” y en “Confirm before attaching” y posteriormente click en el botón “Done”. 14 6. Den click en el menu: “Options => Add to Explorer”. 7. Den click en las opciones: “Add OllyDbg to menu in Windows Explorer” y posteriormente click en el botón “Done”. 15 Esta acción permitirá agregar al Explorador de Windows agregar un menú para que podamos abrir cualquier ejecutable utilizando el debugger. 8. Den click en el menu: “Options => Debugging options”. En la pestaña “CPU” habiliten las opciones tal como son mostradas con el marcador amarillo en la imagen. 16 Esta acción permitirá a OllyDbg mostrarnos la ruta de los llamados utilizando los “CALLS” de ensamblador, lo cual nos permitirá “trazar” los saltos en el código. Con esto concluimos con la personalización de la configuración de OllyDbg. Cabe mencionar que OllyDbg tiene la posibilidad de utilizar varios plug-ins. En posteriores cursos vamos a ver cómo es que agregamos plug-ins a OllyDbg, como utilizarlos y con qué objetivo. Por el momento para la finalidad que estamos buscando en este documento es más que suficiente. Instalación de IDA Freeware Para los que ya tienen un poco de experiencia en el RCE el nombre de “IDA” se les hará muy conocido. Pues bueno, para los que no lo conocen “IDA” es un software que es utilizado por mucha gente, tanto para los investigadores de cuestiones de seguridad, analistas, ingenieros, etc. IDA es comúnmente nombrado como “IDA Pro” el cual es básicamente la versión comercial/profesional de dicho software. Afortunadamente existe una versión Freeware que es la que utilizaremos. Pasos a seguir: 1. Descargar el archivo .exe (idafree50.exe) que contiene IDA Freeware. 2. Continuar con el proceso de instalación tradicional. 3. Al término de la instalación, ejecutamos el programa y nos deberá mostrar la siguiente pantalla: Existen excelentes tutoriales y libros acerca del uso de la interfaz de IDA Pro, de OllyDbg y prácticamente de todo el software que estaremos utilizando. Pueden encontrar dichos recursos en el apartado “Referencias” en mi sitio web. 17 Les sugiero que visiten la sección antes mencionada ya que siempre es bueno de cierto modo “dominar” la interfaz de las herramientas que estemos usando, esto nos permitirá una mayor flexibilidad y facilidad de acceso a ciertas funcionalidades del programa mientras nos encontremos manipulando archivos ejecutables. Hasta este momento ya tenemos los componentes necesarios para irnos con todo a aprender Ensamblador, recapitulemos: 1. 2. 3. 4. 5. 6. 7. WinAsm – LISTO MASM32 – LISTO Visual C++ 2005 – LISTO Cygwin – LISTO OllyDbg – LISTO IDA Freeware – LISTO Fuerza y Ganas – ¡LISTAS! ;) Y bien... Señores pasajeros, sean tan amables de abrocharse sus cinturones que ya estamos por empezar lo bueno. Hehehe. 18 Importancia del dominio de las Herramientas Para poder llegar a ser experto en un área en específico deberás dominar las herramientas, es por ello que como ya hemos mencionado anteriormente, OllyDbg e IDA serán *casi* nuestras herramientas principales y es por ello que veremos de primer instancia como dominarlas para posteriormente no tener problemas con su uso cuando ya estemos entrado en materia fuerte. Conociendo la interfaz y funcionamiento de OllyDbg Como ya muchos de ustedes saben, hay algunas guías que explican acerca de la interfaz de OllyDbg sin embargo voy a intentar reinventar la rueda, pero tampoco explicare a tan “Alto nivel” ya que probablemente hay personas que estén leyendo este documento que nunca han visto tales guías, así que comencemos. Para familiarizarnos con la interfaz de OllyDbg vamos a utilizar el programa de prueba (programa1.exe) que generamos al inicio de este libro. 1. Vayan a la carpeta “c:\reversing” 2. Click derecho en “programa1.exe” y “Open with OllyDbg”. 1. Barra de Botones – Estos botones son la parte principal de la herramienta, ya que desde aquí nos permitirá el acceso a diferentes funcionalidades que nos ayudarán a explorar el ejecutable que hayamos cargado. De izquierda a derecha, accedamos a cada una de ellas: 1. 19 - Esta funcionalidad nos permite ver cuáles son los módulos –o dll’scargados por nuestro programa ejecutable entre otras cuestiones relacionadas a mostrar un estatus. En el primer recuadro de lado izquierdo se muestra la locación de memoria en donde los módulos se han cargado y en el recuadro derecho el módulo en cuestión. Veamos más a detalle: 1. Selecciona la dirección de memoria 00400000, den click derecho y den click en el menu “Dump at address”. La acción anterior hará que nos muestre en la pantalla principal de OllyDbg lo que se encuentra en la dirección de memoria 00400000. 20 Ahora dividiré en columnas esta pantalla para explicar a detalle que significa cada cosa. La primera columna de izquierda a derecha, tal como comentamos anteriormente, contiene las direcciones de memoria de nuestro ejecutable. La segunda columna muestra el contenido del la dirección de memoria correspondiente lo cual básicamente es una representación en código Hexadecimal de los datos. En la siguiente figura realizaremos la conversión de Hexadecimal a ASCII utilizando una herramienta en línea. http://www.dolcevie.com/js/converter.html La tercera columna muestra los datos contenidos en la dirección de memoria pero ahora en su representación en código ASCII. 4D 5A = M Z Pueden encontrar una gran variedad de herramientas en línea o documentos relacionados a la representación de datos en la sección de “Recursos” en mi blog. 21 Ahora hablemos un poco acerca de los archivos o librerías cargadas junto con el programa: En el recuadro se podrá ver que la primer línea contiene programa1.exe el cual es el que estamos cargando, posteriormente verán que se cargan algunas DLL’s adicionales pertenecientes al Sistema Operativo. Esto es muy importante, interesante y útil desde la perspectiva de estar realizando un análisis de malware o de vulnerabilidades en software, ya que de este modo podremos saber que otros componentes son requeridos por un ejecutable en específico y probablemente nos dé una pista de dónde mirar, ya sea que tengamos una muestra de malware y tengamos que identificar que DLL’s son cargadas o identificar la DLL afectada por alguna vulnerabilidad. Nasty! Hehe Para finalizar con en análisis de la funcionalidad “Log data”, veamos la línea correspondiente al “Entry point”. 1. Den doble click en la línea que indica “Program entry point”. 22 Esta acción nos direccionará a la pantalla principal de OllyDbg posicionándonos en la dirección de memoria 00401000 o mejor dicho “Program entry point” lo cual en palabras más entendibles significa que es el inicio del programa programa1.exe, es decir, el lugar desde el cual se “iniciará” la ejecución de instrucciones del programa. No se preocupen por entender mucho de lo que voy comentando, conforme vayamos avanzando las cosas se tornarán más claras. Como nota adicional, la funcionalidad de OllyDbg llamada “Show modules window - ” también nos muestra prácticamente las mismas opciones que en la funcionalidad “Show Log window ” sin embargo es mayormente recomendable utilizar la funcionalidad “Show modules window” ya que también contiene opciones más avanzadas las cuales nos serán de gran utilidad en un futuro. Continuemos con la siguiente funcionalidad de OllyDbg… 2. - Esta funcionalidad al igual que las acciones que realizamos en el funcionalidad “Show Log window” nos permite ver cuáles son los módulos –o dll’s- cargadas por nuestro programa ejecutable, sin embargo nos ofrecerá opciones mucho más potentes. Como hemos hecho anteriormente, dividiré la pantalla en columnas para una mejor explicación. 23 La primera columna tenemos la dirección “Base”. Una cosa es la dirección base y otra el “Entry point”. Veamos la diferencia de manera gráfica. Por el momento anoten cuales son las direcciones “Base” y “Entry”: Base = 00400000 Entry = 00401000 1. Den click derecho en la primer línea y seleccionen la opción “View code in CPU”. Veamos ahora como se visualiza en el “Mapa de memoria”. 24 En la primera línea del recuadro en la primera columna (columna de las direcciones de memoria) veremos que contiene: 00400000. Algo interesante aquí es que como pueden ver que en la columna “Section” se encuentra en blanco, es decir, que no tiene una sección de instrucciones lo cual confirma que la dirección “Base” o el área de memoria reservada para programa1.exe que empieza en 00400000. Si dan click en esa primer línea verán que el contenido es básicamente la cabecera PE (Portable Executable) y demás información. Veamos: En esta imagen se puede apreciar en la parte superior izquierda del recuadro la dirección “Base” (00400000) y veremos de igual modo que en la tercer columna de izquierda a derecha contiene “ASCII MZ” lo cual indica NO el principio de las instrucciones, sino el principio del archivo ejecutable ó cabecera PE. Como dato curioso, “MZ” son las iniciales del creador del formato ejecutable “Mark Zbikowski”, un ingeniero de Micro$oft. Regresemos a la captura de pantalla anterior… (La copio nuevamente a continuación para fácil identificación) 25 Ahora veamos donde se sitúa el “Entry point” el cual acorde a la nota previamente indica que es: 00401000 y curiosamente vemos que es la siguiente dirección de memoria (segunda línea, primer columna) es esta misma dirección. Sin embargo, en este caso en la columna “Section” verán que ahora si contamos con una sección, y es la sección “.text” la cual contiene las instrucciones que ejecutará el procesador a la hora de ejecutar el programa programa1.exe. Nos mostrará la siguiente pantalla: Detallemos de izquierda a derecha… El primer recuadro muestra la dirección de memoria la cual ya hemos explicado con anterioridad. El segundo recuadro muestra el código en Ensamblador de programa1.exe o lo que es lo mismo, el código contenido en la sección “.text”. Por el momento hagan una nota mental acerca de las “secciones” como las que hemos visto hasta este momento. Cuando entremos en acción en la estructura de un programa en ensamblador verán a que me refería con esto de las “secciones”. 26 Para concluir veamos las últimas columnas que faltan por explicar: La segunda columna llamada “Size” en este caso contiene el valor: 00004000 lo cual indicar el tamaño requerido para programa1.exe. Regresemos a la imagen inicial del mapa de memoria de programa1.exe: En este caso verán que desde la dirección 00400000 hasta 00403000 contiene cuatro veces 00001000 y si se suma da un igual de 00004000. Por lo cual, este es el espacio de memoria asignado para: Cabecera PE 00001000 = 27 + sección .text 00001000 + sección .rdata 00001000 + sección .data 00001000 Por último, la quinta columna llamada “File version” es de gran ya que nos muestra la versión del archivo. Esto sirve por ejemplo, para identificar versiones vulnerables de librerías de algún programa de las cuales tenemos conocimiento, por lo cual si hay algún programa que utilice dicha librería pudiera existir el caso de poder explotarla. Sigamos con la funcionalidad “Show Memory window”. 3. - Esta funcionalidad es muy poderosa y útil ya que nos permite ver una radiografía de la memoria tanto desde la perspectiva del archivo ejecutable que estamos cargando, como de la memoria utilizada por programas del propio Sistema Operativo (kernel32.dll, gdi32.dll, user32.dll, etc.). Afortunadamente para este momento ya he explicado detalladamente cómo utilizar ciertas funcionalidades que hacen uso del mapa de memoria (Memory map), sin embargo en este caso me enfocaré a solamente explicar aquellas cuestiones que me parecen importantes de mencionar. 28 En el primer recuadro de izquierda a derecha encontrarán las columnas que contienen las direcciones de memoria, tamaño, el owner (el programa), las secciones y el tipo de contenido. En este caso, un punto importante es que como ya lo hicieron anteriormente que es el identificar en la dirección base “base address” y el punto de entrada “Entry point”, básicamente aquí es lo mismo, sin embargo aplica para aquellos “módulos” o librerías cargadas por el Sistema Operativo (tercer columna). La cuarta y quinta columna muestran el tipo de sección y una descripción de que es lo que contiene. Para el caso de las secciones, las más significativas a este momento con la sección .text que contiene código, “imports” y “exports” y la sección .data que contiene datos –o variables- a utilizarse en el programa. No sientan pánico. Por último las columnas “Access” e “Initial” (séptima y octava columna) de las cuales la primera muestra “los permisos de acceso” a cada una de las secciones del programa. 29 Veamos cuales son los permisos de las secciones en programa1.exe. 1. Doble click en la línea que contiene “PE header”. 2. Se abrirá el “Dump” o volcado de la cabecera PE. Como podrán ver, cada una de las secciones tiene su propios “permisos”. 30 La sección .text puede ejecutar y leer (EXECUTE|READ), la sección .rdata solamente leer (READ) y por último la sección .data solo puede leer y escribir (READ|WRITE). Básicamente la asignación de permisos son para controlar en donde se “pueden” escribir datos, por default hay secciones –como la .text- en la cual no se puede escribir datos, ya que un usuario no “debería” escribir en una sección de instrucciones, ¿Correcto? Sin embargo el control de acceso puede ser controlado por el usuario ya sea utilizando herramientas a la hora del “debugging” o a través de programas con rutinas específicas. 4. - Esta funcionalidad nos sirve básicamente para mostrar la interfaz principal de OllyDbg. Pueden presionar este botón si se encuentran perdidos entre miles de ventanas ;). Aprovecharé para mencionar los componentes de la interfaz de OllyDbg de manera muy rápida y sencilla. Recuerden, NO pretendo hacer una guía completa del uso del debugger. Existen MILLONES de guías acerca del uso de la interfaz de esta herramienta, así que si les quedó duda o requieren mayor información... 1. Busquen en la sección “Recursos” de mi sitio web. 2. Google => OllyDbg tutorial. Continuemos... 2. Barra de Control – Los botones contenidos en esta barra nos permitirán controlar la ejecución del programa. Como desde un inicio he recalcado que este e-Book sería práctico, veamos cómo se reflejan por lo menos las acciones que no son obvias utilizando el programa de prueba “programa1.exe”. 31 Veamos… 1. 2. 3. 4. 5. Reiniciar el programa = Ctrl +F2 Cerrar el programa = Alt + F2 Ejecutar el programa = F9 Pausar la ejecución del programa = F12 “In paso un paso”. Esta opción nos permite ir básicamente de línea en línea sobre la ejecución del programa = F7 Esta es una de las opciones que mas estarás utilizando. Tal como lo dice la explicación, se trata de ir paso a paso sobre cada línea de instrucciones del programa. 1. Posicionan el mouse en el primer CALL y presionas la tecla “F2”. Esta acción asignará un “Breakpoint” el cual cuando se ejecute el programa se “pausará” en esa posición. Breakpoint = pausar 2. Presionas “Ctrl + F2”, click en “Si”. 3. Presionas “F7” cinco veces seguidas. 4. Verás que a pesar de tener un Breakpoint asignado, no se generó ninguna pausa, es decir, se fue de largo. 6. Similar al anterior, pero en este caso ejecuta las funciones que se va encontrando durante la ejecución = F8 5. Presionas “Ctrl + F2”, click en “Si”. 32 6. Presionas “F8” cinco veces seguidas. 7. Ahora, veremos que la ejecución “paró” en el Breakpoint que asignaste anteriormente y además ejecutó la rutina. 7. Se ejecutan las instrucciones y ejecutando las subrutinas que se va encontrando durante la ejecución = Ctrl + F11 8. Similar al anterior, pero en este caso ejecuta las llamadas –o calls- que se va encontrando durante la ejecución de igual manera = Ctrl + F12 8. Presionas “Ctrl + F2”, click en “Si”. 9. Presionas “Ctrl + F12”. 10. Esta acción brinca directamente a la instrucción CALL: 9. Ejecutar hasta retornar –o llegar a RETN- = Ctrl + F9 11. Presionas “Ctrl + F2”, click en “Si”. 12. Presionas “Ctrl + F9”. 33 13. Esta acción brinca directamente a la instrucción RETN que es la que indica el término de la ejecución del programa. 10. Una forma rápida para dirigirnos hacia una dirección de memoria en específico es dando click en el último botón: “Go to Address in Disassembler”. Veamos que sucede. 14. Presionas “Ctrl + F2”, click en “Si”. 15. Click en el botón “Go to Address in Disassembler”. 16. Escribes la dirección de memoria de RETN (7C91EB94) y presionas “Enter”. Como resultado saltará directamente a dicha dirección de memoria tal como se muestra en la siguiente pantalla: 34 Bien, por último veamos de manera muy general los componentes de la interfaz principal (ventanas) de OllyDbg. Para mayor entendimiento dividiré y agregaré numeración a cada una de las secciones contenidas en la interfaz de OllyDbg. 1. Esta es la sección principal, en donde veremos las direcciones de memoria, los opcodes, las instrucciones contenidas en el programa y de igual modo una excelente funcionalidad de OllyDbg que muestra en un formato sencillo la representación del código en Ensamblador pero desde la perspectiva de un programa de “Alto nivel” o mejor dicho, como se vería desde la perspectiva de Windows a través de la API de Windows. 2. En esta sección de muestran los registros y de igual modo aquí verán los datos que son contenidos en ellos. Los registros es un tema muy importante e interesante, y lo estaremos abordando más a detalle posteriormente. 3. En esta sección de muestra el resultado de las operaciones de las instrucciones tal y como se van ejecutando. 4. Aquí se muestra el “Dump”, o lo que es lo mismo el volcado de los datos en memoria. 35 5. Y por último el viejo pero poderoso “Stack”!. Aquí es en donde verán cómo es que los datos se van comportando conforme un programa se encuentra en ejecución. Acciones como asignación de variables las verán en el Stack de OllyDbg. Aquí concluimos nuestra visita a cada una de las funcionalidades principales de OllyDbg y su interfaz. Hay algunas funcionalidades que no cubrí en esta sección, como es el uso de “Search for”, “Find references to”, “Follow in Dump” es porque en posteriores prácticas las utilizaremos y explicaré en su momento el funcionamiento de cada una de ellas. Antes de cerrar este capítulo de la interfaz de OllyDbg les comentaré que para los que no sabían es posible disfrazar la interfaz con colores distintos a los que trae Olly por default. Diríjanse aquí para saber las instrucciones que necesitan para que personalicen su OllyDbg al gusto: http://www.ollydbg.de/schemes.htm. En mi caso, pongo guapo a mi OllyDbg con el mismo tema que usa ImmunityDbg ]¬) 36 Conociendo la interfaz y funcionamiento de IDA Dissassembler r0x! Hemos llegado a un tema que a mucha gente le interesa y desafortunadamente ha sido el “menos” documentado o explicado y me refiero al uso de IDA. En internet es mejor conocido como IDA Pro, y que como lo comentamos anteriormente la cuestión del es “Pro” es porque es la versión comercial, sin embargo para la finalidad de este e-Book utilizaremos la versión “Freeware”. Si desean ver específicamente la diferencia entre las versiones Freeware y comerciales al momento de iniciar IDA Freeware les desplegará la ayuda en automático, y es allí en donde podrán ver a detalle la cuestión de las diferencias. A este punto ya deberás tener instalado el software en tu PC/VM. ¡Empecemos! Pasos a seguir: 1. Ejecutamos IDA Freeware, nos aparecerá la pantalla (banner) inicial. Click en “OK”. 2. Aparecerá la pantalla de acción en la cual darás click en el botón “New”. 37 3. Posteriormente seleccionarás la opción “Portable Executable”: 4. Seleccionas: “programa1.exe” y das click en el botón “Abrir”. 5. En la siguiente pantalla, mostrará la opción “Analysis options”. Esta opción permitirá personalizar la opción del análisis del ejecutable en caso de ser necesario. Esta opción la dejarás sin seleccionar. 38 6. La pantalla siguiente por default viene habilitada la opción “Create imports segment” y básicamente su función es la de incluir en una ventana todos los “imports” que utilice el ejecutable que estas cargando en IDA. 7. Y el último paso del wizard es la del inicio del análisis. Esto quiere decir que IDA empezará a analizar el archivo a cargar, su estructura, para que al final IDA nos muestre todo lo relacionado al ejecutable a través de su sexy interfaz. 39 8. Al término del análisis se abrirá la pantalla principal de IDA. Tal como lo he hecho para OllyDbg, he dividido en secciones y agregado una numeración cada una de ellas para ir explicando cada una de ellas a detalle posteriormente. 1. Barra de botones: Aquí encontrarás la barra de botones. Básicamente son accesos directos a cada una de las funcionalidades de IDA. 2. Barra de Desplazamiento o Navegación: Esta opción permite “direccionarte” a través de las secciones del ejecutable. Tiene 2 opciones principales. La primera es utilizando un menú desplegable y la segunda es con el mouse y conforme deslizas el mouse vas viendo en la pantalla el contenido de la sección que te encuentres navegando. Aquí una nota que me gustaría agregar. Como verás en la barra de lado derecho, contiene diferentes colores (azul, gris, rosa, etc.) y esto es porque dichos colores tienen asignada una sección. 40 5. Color Azul – Si deslizas el mouse sobre esta sección, mostrará la interfaz de navegación conteniendo el código “desensamblado” del ejecutable. 6. Color Gris #1 – Si deslizas el mouse sobre esta sección, mostrará la interfaz de navegación conteniendo el código “desensamblado” del ejecutable, pero sin la interfaz de navegación. Además, muestra el contenido de código en la sección .text. 7. Color Rosa – Esta sección contiene los “imports” del ejecutable. Hablaremos más adelante acerca del significado de los imports. 41 8. Color Gris #2 – Como verás hay 2 colores grises, uno como ya mencionamos muestra el contenido de la sección .text y el segundo muestra el contenido en la sección .data, es decir, los datos utilizados (variables) en el ejecutable. En la pantalla anterior verán que las “strings” de texto que asignamos a programa1.exe. Recordemos: Como podrán apreciar, la sección .data contiene las “variables” asignadas con “db” las cuales contienen el texto que elegimos. Vean la diferencia de cómo se visualiza a nivel código y a nivel desensamblado. ¿Hace sentido? Bien, continuemos con el análisis de la interfaz de IDA… 42 3. Barra de funciones: Esta opción contiene varias sub-opciones las cuales veremos a continuación: 9. IDA View-A – Aquí muestra básicamente el contenido desensamblado utilizando la interfaz de navegación de IDA. Simple. 10. Hex View-A – Lo mismo que “IDA View-A” con la diferencia que se muestra el código sin la interfaz de navegación. 11. Exports – Aquí nos mostrará los “exports” utilizados por el ejecutable. Los exports son básicamente las funciones con las que cuenta el programa. En este caso tenemos “start” el cual significa el “inicio” del programa. 43 Como nota adicional, vean como de igual manera nos indica la dirección de memoria de la función. Muchas de las funcionalidades nos proveen de mucha información la cual es muy útil para la tarea que estés ejecutando. 12. Imports – Los imports -a diferencia de los exports- “importan” funciones desde librerías externas. En este caso como programa1.exe utiliza la API de Windows (ExitProcess y MessageBox) las cuales para que puedan ser utilizadas por el programa deberán ser importadas desde kernel32.dll y user32.dll respectivamente. Observen la columna “Library”. 13. Functions – Aquí se muestran las funciones utilizadas por el programa. En este caso muestra la función start y MessageBoxA. 44 Veamos a detalle… 14. Start, como sabes es una función, la cual obviamente tiene un principio y un fin. En este caso tenemos en el primer recuadro el inicio de la función y el segundo su finalización. Podemos decir que “start” es la función de inicialización del código del programa. 15. Otro tipo de función (o rutina) es la utilizada por la instrucción “CALL”. Lo que hace es mandar llamar a la función, brincar a esa parte en el código y ejecutar las instrucciones que se encuentran dentro de ella. En la imagen pueden observar que el código empieza con “push 0” y posteriormente finaliza con la llamada “call”. Bueno, lo que hace es “formar” el cuerpo de los argumentos requeridos para invocar a la función MessageBox. ¿No quedó claro? Veamos… Según la página de MSDN de Microsoft indica que la función MessageBox utiliza en total 4 parámetros (hWnd, lpText, lpCaption y uType). 45 Veamos una como hace “match” entre la función MessageBox y el código Ensamblador en IDA: Tal como lo habíamos mencionado, los parámetros utilizados por la función MessageBox deberán de igual modo ser asignados mediante la instrucción “push” en código Ensamblador, lo cual “agrega” dichos valores al “Stack”. Una vez que se tienen todas las variables en memoria por último se ejecuta el call a MessageBox el cual ejecuta la función. Como nota adicional, observen el orden de los parámetros pasados a la función MessageBox. Podemos apreciar como el último parámetro (uType) se encuentra ligado al primer “push” y así sucesivamente. Cuando llegue al tema del Stack sabrán el por qué sucede esto. 46 4. Ventana Principal - Bien, esta es la pantalla principal en donde se desplegará la interfaz de navegación y prácticamente todas las vistas generadas por cada una de las funcionalidades de IDA las cuales ya he explicado anteriormente. 5. Gráfica de Navegación – Esta es una funcionalidad muy buena y atractiva, ya que en una imagen tipo “Thumbnail” muestra el contenido (código) del ejecutable de una manera gráfica la cual facilita precisamente la navegación del código Ensamblador. Veamos… 47 6. Names – Esta función nos permite identificar todos los “nombres” contenidos dentro del código del programa. Como podemos observar en la siguiente pantalla en donde se muestra que nos indica con la letra “F” las funciones, con la letra “I” los nombres importados y con la letra “A” las strings en ASCII. Como comenté anteriormente, muchas funcionalidades contienen información que nos ayudan a ciertas tareas. En este caso vemos que la columna “Address” contiene las direcciones de memoria para cada uno de los nombres mostrados en la primera columna. En la archivo de ayuda de IDA podrán encontrar el resto de las representaciones para ésta y otras funcionalidades. 7. Strings – Esta funcionalidad es de un cierto modo de los más utilizados principalmente para la cuestión del Cracking ya que permite identificar todos los strings utilizados por el programa. Veamos… De igual modo, tenemos la columna que nos muestra la dirección de memoria, el tamaño, el tipo y finalmente el string. 48 Pueden notar que los strings utilizadas como variables en programa1.exe aparecen en las dos últimas líneas en la pantalla anterior. 8. Ventana de Estatus – Tal como su nombre lo indica, aquí es en donde se podrá ver todo lo que va sucediendo con el ejecutable desde su carga y posterior. Por último, les sugiero descarguen las “Cheat Sheets” que pueden encontrar en mi sitio: http://www.resrever.net/p/recursos.html de OllyDbg (Reverse-Engineering Malware Cheat Sheet) e IDA (IDA Pro Shortcuts). Fufff… este ha sido un camino algo largo. Hasta este momento hemos dado una buena revisión a las herramientas principales que serán de gran ayuda para aprender Ensamblador. Recapitulando: 1. Ya tienen instaladas y listas las herramientas, compiladores y documentación necesaria. 2. Ya saben cómo funciona OllyDbg e IDA. Por lo menos las funciones básicas. Creo que con eso ya estamos bien armados. Ahora, ¡A darle! ]¬) 49 Estructura de un Programa en Ensamblador Como ustedes recordarán al inicio del e-Book empezamos haciendo un pequeño programita el cual hemos estado utilizando como “rata de laboratorio” hasta este momento. Bien, es tiempo que empecemos a meternos de lleno al tema del Lenguaje Ensamblador; y para entenderlo tendrás que saber la estructura de un programa en Ensamblador, sus directivas, asignación de variables y demás. Como ya hemos comentado con anterioridad el lenguaje Ensamblador no es solo código, sino que de igual manera hay ciertas cuestiones involucradas como lo son los registros, banderas, etc. Si bien no es necesario enfocarnos a este tema desde un inicio la forma que manejaré será la de ir armando el programa y a la par ir viendo como se visualiza el programa que voy creando tanto en OllyDbg como en IDA. A continuación verás el código que utilicé para crear programa1.exe: Aquí la descripción de la numeración de la figura anterior: 1. .386 - Describe el modelo de CPU para el cual el código está dirigido; en este caso como estamos haciendo el programa para x86 se puede utilizar la directiva .386. Como nota adicional hay que poner atención en el punto inicial el cual es requerido antes de cualquier directiva. Ya verás en un momento más a que me refiero. 2. .model flat,stdcall - La directiva .model: En esta directiva se define básicamente el modelo –o tipo- de memoria utilizado que utilizará el programa que estás desarrollando. Aquí no hay muchas opciones por lo que solamente tendrás una: flat y stdcall. Stdcall indica el tipo de convención a utilizar para el paso de parámetros al utilizar funciones. No te alarmes, pronto veremos de qué trata este asunto con algunos ejemplos más adelante. 50 3. include – Tal como es utilizado en otros lenguajes, los “includes” tienen el mismo objetivo en Ensamblador; el cual es “incluir” en el código las librerías a utilizarse. Para el caso de Ensamblador sobre Windows (Win32) se utiliza principalmente las librerías e “includes” relacionadas a las dll’s que conocemos son parte del Sistema Operativo, y me refiero a windows, kernel32 y user32. ¿Cómo es esto? Sencillo. En Windows para que se puedan desplegar las ventanas hace uso de un DLL (user32.dll) y lo que hay “dentro” de user32.dll son meras funciones como lo es el caso del “MessageBox”, le cual al ser llamada dicha función despliega una ventana de mensaje; por lo cual si se incluye el uso de los archivos de user32 en el programa, está por entendido que se tiene planeado el despliegue de ventanas. Claro como el agua. 4. .data - La directiva .data contiene información inicializada del programa. Como te podrás dar cuenta utilizamos esta directiva para hacer la asignación de la “variable” MsgBoxCaption, asignándole el valor: “Resrever.Net”. Se puede decir que la directiva –también llamada sección- .data será el repositorio de las variables inicializadas del programa. Existen otras directivas como .DATA? la cual tiene la misma función que .DATA, con la única diferencia que ésta sirve para almacenar datos no-inicializados. De igual manera se tiene la directiva .CONST que como puede deducirse sirve para almacenar las constantes que se quieran utilizar en el programa. Para efectos del ejemplo se usará únicamente la directiva .data y conforme vayan avanzando los temas se irán retomando el resto de las directivas. MsgBoxCaption db "Resrever.Net",0 – Como lo comenté anteriormente, dentro del bloque de variables (.data). En este caso se está asignando el nombre de variable “MsgBoxCaption” asignando (db) el valor “Resrever.net”. Si te fijas al final lleva una coma y un cero y el motivo de esto es que todas las cadenas deberán ser terminadas con 0 –ó NULL-. 5. .code - La directiva .code, como es de suponerse es en donde se escribirá el código del programa. .start y end start – Indican el principio y el fin del bloque de código. invoke – Es una forma se “llamar” a una función. De igual modo se podría utilizar una llamada “CALL”, sin embargo para evitar cuestiones relacionadas al manejo de errores es mayormente recomendable el uso de invoke. En el código se utiliza invoke de la siguiente forma: invoke MessageBox, NULL, addr MsgBoxText, addr MsgBoxCaption, MB_OK en la cual se está haciendo una llamada a la función “MessageBox” con 4 parámetros (NULL, MsgBoxText, MsgBoxCaption y MB_OK). Nota que los valores de MsgBoxText (Ensamblador r0x!) y MsgBoxCaption (Resrever.Net) fueron asignadas previamente. Te recomiendo regresar a la página 49 para entender un poco más de la asignación de parámetros a las funciones. 51 Cada vez que generes un nuevo programa podrías utilizar la siguiente pieza de código como plantilla: .386 .model flat,stdcall option casemap:none include \masm32\include\windows.inc include \masm32\include\kernel32.inc includelib \masm32\lib\kernel32.lib include \masm32\include\user32.inc includelib \masm32\lib\user32.lib .data <variables> .code start: <código> end start Si deseas obtener mayor información acerca de la estructura de un programa en Ensamblador Win32 te sugiero visites el Tutorial Ensamblador Win32 de Iczelion en la siguiente liga: Liga: http://www.angelfire.com/rnb/byte/tut01_es.html Entendiendo los Registros del CPU Como ustedes recordarán al inicio del e-book, todo el tiempo me he enfocado en “primero practicar y después entender”, por lo cual eso es precisamente lo que haremos; veremos de una manera visual y dinámica el funcionamiento de las instrucciones x86 o lo que es lo mismo, veremos cómo se visualizan desde el punto de vista del procesador y de ser requerido abordaremos temas teóricos. Aprendiendo el Set de Instrucciones x86 En este punto me gustaría hacer una pausa y comentar algo que considero de relevancia. En éste primer acercamiento al set de instrucciones x86 voy a realizar un pequeño programa ejemplo por cada una de ellas y posteriormente iré trabajando sobre el programa correspondiente. La instrucción - INC La instrucción INC sirve para “incrementar” el valor numérico que tengas en un registro en particular. En el siguiente ejemplo verás cómo utilizar la instrucción INC para ir sumando un número al registro EAX (acumulador) de de igual manera iré explicando los eventos que me voy encontrando durante el análisis del programa. 52 Veamos cómo se usa en la práctica: Pasos a seguir: 1. Abran WinAsm Studio. 2. En el menú, “File => New project”, seleccionen: Standard Exe 3. Copia el siguiente código y guarda el proyecto en “c:\reversing” como inc.wap y el código como inc.asm. .386 .model flat,stdcall option casemap:none include \masm32\include\windows.inc include \masm32\include\kernel32.inc includelib \masm32\lib\kernel32.lib include \masm32\include\user32.inc includelib \masm32\lib\user32.lib .data .code start: ; Resrever.net ; Ejemplo de uso de la instrucción "INC" INC INC INC INC INC INC INC INC INC INC INC INC INC INC INC INC INC INC INC INC INC INC INC INC INC INC INC INC INC INC INC INC INC INC eax eax eax eax eax eax eax eax eax eax eax eax eax eax eax eax eax eax eax eax eax eax eax eax eax eax eax eax eax eax eax eax eax eax 53 ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; Incremento Incremento Incremento Incremento Incremento Incremento Incremento Incremento Incremento Incremento Incremento Incremento Incremento Incremento Incremento Incremento Incremento Incremento Incremento Incremento Incremento Incremento Incremento Incremento Incremento Incremento Incremento Incremento Incremento Incremento Incremento Incremento Incremento Incremento de de de de de de de de de de de de de de de de de de de de de de de de de de de de de de de de de de EAX EAX EAX EAX EAX EAX EAX EAX EAX EAX EAX EAX EAX EAX EAX EAX EAX EAX EAX EAX EAX EAX EAX EAX EAX EAX EAX EAX EAX EAX EAX EAX EAX EAX = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = 00000001 00000002 00000003 00000004 00000005 00000006 00000007 00000008 00000009 0000000A 0000000B 0000000C 0000000D 0000000E 0000000F 00000010 00000011 00000012 00000013 00000014 00000015 00000016 00000017 00000018 00000019 0000001A 0000001B 0000001C 0000001D 0000001E 0000001F 00000020 00000021 00000022 INC eax INC eax INC eax INC eax INC eax INC eax INC eax INC eax INC eax INC eax INC eax INC eax INC eax RETN ; ; ; ; ; ; ; ; ; ; ; ; ; Incremento Incremento Incremento Incremento Incremento Incremento Incremento Incremento Incremento Incremento Incremento Incremento Incremento de de de de de de de de de de de de de EAX EAX EAX EAX EAX EAX EAX EAX EAX EAX EAX EAX EAX = = = = = = = = = = = = = 00000023 00000024 00000025 00000026 00000027 00000028 00000029 0000002A 0000002B 0000002C 0000002D 0000002E 0000002F end start 4. Presiona: Shift + F8. 5. Se genera “inc.exe”, da click derecho en el archivo y selecciona “Open with OllyDbg”. 6. Regresas a OllyDbg y verás la siguiente pantalla: Vista - OllyDbg Como verás, OllyDbg te posiciona el cursor en la primer línea, lo cual quiere decir que aun no se ha “iniciado” la ejecución del programa. Nota que en la ventana de los registros (superior derecha) indica que el registro EAX contiene el valor “00000000”. Lo que haremos a continuación será utilizar la funcionalidad de OllyDbg de ir “paso a paso”, o sea tecleando “F7” para visualizar como es que en el número que se encuentra en el registro EAX se va incrementando conforme la ejecución de instrucciones va avanzando. OK, Continuemos… 54 7. Presiona la tecla “F7”. Bien, ahora vemos que el cursor se posiciona en la segunda línea y ahora el registro EAX dice que su valor es “00000001”. Repite el mismo paso (presiona F7). Tercer línea, y el registro EAX con el valor “00000002”. OK, creo que ya se entendió la idea del INCremento. Un detalle curioso es, por si no te has dado cuenta es que estas posicionado en la línea 3 y el valor de EAX es 2, bueno hay que recordar que el primer INCremento es de 0, después, 1, 2, etc. Aún falta ver más.. continuemos… 8. Presiona “F7” siete veces más. 55 Ahora EAX vale “00000009”, presta atención a lo que sucede a continuación: 9. Presiona “F7” nuevamente. WTF!! – ¿0000000A? ¿No se suponía que sería: 00000010? NO, y esto tiene una sencilla explicación, esos valores que estas incrementando al registro EAX se encuentran en formato Hexadecimal, lo cual quiere decir que tendrás un “rango” de: 0 a 9 (0123456789) y de la letra “A” a la “F” (ABCDEF). 10. Presiona nuevamente “F7”. 56 Tal como era de esperarse, EAX = 0000000B. 11. Presiona “F7” 4 veces más. Llegaste a “0000000F”, ¿Qué seguirá? 12. Presiona nuevamente “F7”. 57 ¿Huh? ¿00000010? Recapitulando… Iniciamos en “00000000” hasta “00000009”. Después de “0000000A” hasta “0000000F”. Ahora… ¿“00000010”? hasta…. ¡0000001F! 13. Presiona “F7” 15 veces. En efecto, ahora EAX vale “0000001F”, Continuemos… 14. Presiona “F7” 11 veces. 58 Ahora EAX es igual a: 0000002A. Recapitulando… Iniciamos en “0000001F” hasta “0000002A”, o lo que es lo mismo: o 0000001F, 00000020, 00000021, 00000022, 00000023, 00000024, 00000025, 00000026, 00000027, 00000028, 00000029, 0000002A ..y así sucesivamente con los números incrementados posteriormente . No te preocupes por ahora por lo teoría, recuerda que vamos “a la inversa”, primero practicas, lo entiendes, y después en la teoría verás “el por qué”. Como te darás cuenta aproveche el tema de la instrucción INC para de igual modo tocar un poco el tema de cómo trabaja el sistema Hexadecimal en la práctica. Vista – IDA Pro Veamos cómo se visualiza el código desensamblado del programa inc.exe en IDA Pro: ; ; +------------------------------------------------------------------+ ; This file is generated by The Interactive Disassembler (IDA) ; Copyright (c) 2010 by Hex-Rays SA, <[email protected]> ; Licensed to: Freeware version ; +------------------------------------------------------------------+ ; ; Input MD5 : 788EE2C9F1A31F7D89DC010D8ED4D532 ; ; ; ; ; ; ; ; File Name : C:\reversing\inc.exe Format : Portable executable for 80386 (PE) Imagebase : 400000 Section 1. (virtual address 00001000) Virtual size : 00000030 ( 48.) Section size in file : 00000200 ( 512.) Offset to raw data for section: 00000200 Flags 60000020: Text Executable Readable 59 ; Alignment : default .686p .mmx .model flat ; Segment type: Pure code ; Segment permissions: Read/Execute _text segment para public 'CODE' use32 assume cs:_text ;org 401000h assume es:nothing, ss:nothing, ds:_text, fs:nothing, gs:nothing public start start proc near inc eax inc eax inc eax inc eax inc eax inc eax inc eax inc eax inc eax inc eax inc eax inc eax inc eax inc eax inc eax inc eax inc eax inc eax inc eax inc eax inc eax inc eax inc eax inc eax inc eax inc eax inc eax inc eax inc eax inc eax inc eax inc eax inc eax inc eax inc eax inc eax inc eax inc eax inc eax inc eax inc eax inc eax inc eax inc eax inc eax 60 inc eax inc eax retn start endp Como verán existe una gran similitud –si no es que una mera igualdad - entre el código en “inc.asm” y lo obtenido por IDA Pro. Era de esperarse; sin embargo mientras más vaya avanzando verás el poder que ofrecen ambas herramientas (OllyDbg e IDA) al momento de analizar los programas que voy generando. *********************************************************************** Sugerencias o Comentarios: [email protected] http://www.resrever.net No olviden darse de alta en mi sitio para recibir actualizaciones acerca de este e-Book. *********************************************************************** 61