Sunteți pe pagina 1din 13

CARGANDO FUNCIONES IMPORTADAS MANUALMENTE

Presentado por: Ivn Portilla

Tema: Importacin de funciones por archivos ejecutables.

Domingo 22 de mayo de 2011

Cargando funciones importadas manualmente The Swash

Pgina 1

TEORA GENERAL
Hola, aqu estoy escribiendo otro artculo que he estado preparando desde el da en el publiqu el anterior o por lo menos la base. En este artculo intentar mostrarles como cargar las funciones que importamos manualmente, es decir no participar ni dependeremos del sistema operativo. Con que fin cargamos las funciones manualmente? Bueno, en realidad tengo 2 objetivos y son: 1- Mostrar como Windows carga las direcciones de las funciones (API) que importamos. 2- Una vez conociendo como funciona, podremos relacionarlo con Empaquetadores y cifradores de archivos. Como todo necesitaremos conocer un poco de lo que trataremos claro teniendo algunas nociones sobre el formato portable executable (PE) y posteriormente dejar un cdigo que se encarga de hacer esta tarea, en realidad la base de todo esto es el cdigo porque a mano sera muy complejo.

Cargando funciones importadas manualmente The Swash

Pgina 2

DIRECTORIO DE DATOS (DATA DIRECTORY)

El directorio de datos (IMAGE_DATA_DIRECTORY), como sabemos es una estructura que encontramos en la cabecera de los archivos ejecutables posterior a la cabecera opcional (IMAGE_OPTIONAL_HEADER) en el cual encontramos una serie de datos que hacen referencia a distintas ubicaciones. Este directorio proporciona 0x10 entradas cada una de 8 bytes, repartiendo 4 para una direccin RVA y los otros 4 para el tamao de lo que apunta ese RVA.

Lo que nos interesa es el segundo directorio correspondiente a la tabla de importaciones, el cual nos proporciona como ya sabemos una direccin RVA (Relative virtual Address), la cual apunta al lugar del ejecutable donde se encuentra todo en cuanto a las importaciones as que observemos:

Cargando funciones importadas manualmente The Swash

Pgina 3

Por qu fsicamente no se encuentra en la ubicacin 0x6A18? La respuesta es porque 0x6A18 es una direccin relativa a la direccin virtual, no una direccin fsica as que tenemos que convertir esa direccin RVA a direccin fsica, pero Cmo lo hacemos? El editor LordPE nos ofrece su utilidad de conversin:

Cmo convirti el RVA a direccin virtual y direccin fsica? 1- Debemos saber la direccin RVA a que seccin hace referencia. 2- Le restamos el Virtual Address de la seccin correspondiente en nuestro caso 0x1000. 3- Sumamos el PointerToRawData de la seccin correspondiente en nuestro casi 0x400.

Con esto ya podemos pasar a conocer la estructura que manejan las importaciones.

Cargando funciones importadas manualmente The Swash

Pgina 4

IMAGE IMPORT DESCRIPTOR

Esta estructura est formada por 5 campos, cada uno con valor DWORD (4 bytes) y la explico a continuacin: OriginalFirstThunk: Este campo tiene una direccin RVA que apunta a otro RVA (AddressOfFunction) que posteriormente puede apuntar a la estructura IMPORT_BY_NAME o puede apuntar a un valor el cual se importa por ordinal, pero generalmente se usa poco por lo que puede variar en cuanto al cambio de sistema operativo.

Explicar los campos de esta estructura: - Hint: Este es un campo de tamao WORD (2 bytes) en el cual se encuentra el ordinal de la funcin, la cual es una opcin para ubicarlo en la tabla de exportaciones de la DLL correspondiente. - Name1: Este es un campo de tamao variable, el cual contiene la cadena con el nombre de la funcin.

Cargando funciones importadas manualmente The Swash

Pgina 5

TimeDateStamp: Este campo contiene marca del tiempo y datos de la DLL en la cual se encuentra la funcin, en realidad no muy tenido en cuenta. Forwarder Chain: No documentado. Name: Este campo contiene una direccin RVA que apunta haca la cadena que contiene el nombre de la DLL. FirstThunk: Es muy similar al OriginalFirstThunk con algunas diferencias, este campo apunta a un RVA, que fsicamente este RVA apunta a la importacin por nombre o por ordinal, pero en memoria FirstThunk apunta al sitio donde el sistema operativo carga las direcciones de las funciones que importamos.

Ejecutable sin funciones cargadas.

Ejecutable con funciones cargadas.

Como podemos analizar, lo que hace Windows es leer el RVA al cual apunta el campo FirstThunk, y posteriormente leer el contenido del RVA que correspondera al Hint y Name1 correspondientes a la funcin, obtiene la direccin de la funcin con el API GetProcAddress. Una vez obtenida la direccin de la funcin la escribe en el lugar apuntado por FirstThunk, y esta es la principal diferencia entre OriginalFirstThunk y FirstThunk. Una vez entendido esto creo que podremos entrar en tema y explicar el desarrollo de la idea de cmo nosotros cargaremos esa funciones, algunos inconvenientes y soluciones.

Cargando funciones importadas manualmente The Swash

Pgina 6

ANLISIS GENERAL
Como dijimos anteriormente aqu lo que aremos ser plasmar la idea general de cmo cargar las funciones manualmente. Necesitaremos conocer dos funciones que nos proporciona el API de Windows y son: LoadLibraryA: Esta funcin requiere un solo parmetro y es un puntero a la cadena que tiene el nombre de una librera, la cual esta funcin la cargar en memoria y nos dar el puntero a ella. GetProcAddress: Esta funcin requiere dos parmetros: - La direccin de la librera en la cual est la funcin que buscamos (LoadLibraryA). - El puntero a la cadena que contiene la funcin a buscar (Ejemplo: VirtualProtect).

EL PROBLEMA:
Segn lo anterior necesitaremos estas funciones, pero contamos con un gran problema y es que muy seguramente no siempre encontraremos importadas estas funciones, y tampoco queremos importarlas as que recurriremos a ciertas tcnicas para obtenerlas y salir del problema.

LA SOLUCIN:
Las libreras de enlace dinmico (DLL) tienen una caracterstica, recuerdan el directorio de datos? El primer directorio contiene un RVA que apunta al directorio de Exportacin de la DLL donde podremos encontrar informacin acerca de las funciones que exporta y entre esa informacin podremos encontrar un RVA de cada funcin as que podremos encontrar a GetProcAddress. Otro inconveniente es que no tenemos acceso a la librera KERNEL32.DLL que es la que tiene la funcin que necesitamos, pero y Cmo lo solucionamos? Cargando funciones importadas manualmente The Swash Pgina 7

Nuestra solucin se encuentra en la PEB (Process Environment Block) estructura en la cual se encuentra informacin que Windows necesita para cargar el programa y en esta informacin se encuentran libreras cargadas, etc. Si encontramos las libreras cargadas seguramente estar KERNEL32.DLL que como sabemos es utilizado por todos los programas que se ejecutan en Windows as que solo necesitamos saber cmo localizarlo. No profundizar al respecto porque de lo contrario alargara demasiado este artculo, as que supongo si tienen curiosidad lo investigarn.

OTRO PROBLEMA:
Otro problema con el que nos topamos es que como sabemos la seccin que contiene las importaciones por lo general (.rdata & .idata) no tienen permiso de escritura y si no tenemos este permiso no podremos escribir las direcciones de las funciones para que funcione el programa.

LA SOLUCIN:
Tenemos dos soluciones: - Dar permisos de escritura a la seccin que contiene las importaciones. - Usar el API VirtualProtect la cual nos permite cambiar los permisos de un espacio en memoria. Explicar ambas aunque la primera resulta muy fcil, pero puede dejarnos algunos problemas como por ejemplo algunas detecciones por software Antivirus los cuales se darn cuenta que no es normal que una seccin de datos tenga permiso de escritura. Hacerlo nos resultara tan fcil como lo siguiente:

Ahora conozcamos un poco a VirtualProtect:

Cargando funciones importadas manualmente The Swash

Pgina 8

BOOL WINAPI VirtualProtect ( __in LPVOID lpAddress, - Direccin a cambiar permisos. __in SIZE_T dwSize, - Tamao del bloque a cambiar permisos. __in DWORD flNewProtect, - Permisos a asignar. __out PDWORD lpflOldProtect Buffer que almacena los permisos antiguos. );

Ya que conocemos la estructura de VirtualProtect solo ser necesario llamarla con GetProcAddress y LoadLibraryA y podremos usarla, pero usaremos para el tercer parmetro la constante PAGE_EXECUTE_READWRITE (0x40) y tendremos este problema solucionado. Como les haba dicho les traigo una Shellcode (cdigo en ensamblador para inyectar a ejecutables) la cual hace todo lo explicado y a continuacin explico cmo usarla.

SHELLCODE

Segn Wikipedia: Una shellcode es un conjunto de rdenes programadas generalmente en lenguaje ensamblador y trasladadas a opcodes que suelen ser inyectadas en la pila (o stack) de ejecucin de un programa para conseguir que la mquina en la que reside se ejecute la operacin que se haya programado. En la shellcode que hice hay que cambiar dos cosas: 1- 14200000 = Import RVA. 2- JMP EntryPoint. Ser necesario editar los datos anteriormente mencionados porque como sabemos esto cambia en cada ejecutable.

INSTALANDO LA SHELLCODE
Cargando funciones importadas manualmente The Swash Pgina 9

Lo primero que necesitaremos es un espacio vaco en el ejecutable y recordemos que debe tener permisos de ejecucin, yo lo ar en un pequeo ejecutable ensamblado con MASM32 el cual importa dos funciones MessageBoxA y ExitProcess (Adjunto), en la seccin de cdigo. La shellcode ocupa 0x14F bytes o en decimal 335 bytes, as que tomaremos un espacio en la seccin y recordaremos empezar en mltiplo de 4 para evitar problemas con las instrucciones:

Guardamos y procederemos a abrir con Olly nuestro ejecutable para obtener algunos datos y ensamblar algunas instrucciones. Primero tomamos apunte del punto de entrada original que en nuestro caso es: 0x401000. Luego localizamos esta parte:

Y tomamos apunte de la direccin de ese primer CALL que en nuestro caso corresponder a 0x401062. Cargando funciones importadas manualmente The Swash Pgina 10

Localizamos la ltima instruccin que ser el ltimo CALL de la shellcode y cambiamos por JMP punto de entrada original:

Guardamos los cambios y ahora cambiaremos dos valores con LordPE: En el IMAGE_DATA_DIRECTORY guardaremos el valor del RVA (2010) de las importaciones y posteriormente junto con el tamao lo pondremos a 0:

Y modificaremos el punto de entrada a la direccin Relativa del primer valor que guardamos el primer CALL:

Y an nos queda reemplazar ese otro valor que les comente de la shellcode y lo reemplazaremos por el valor que guardamos del RVA:

Una vez editado todo lo anterior ejecutamos el programa y:

Creo que nuestro programa se ha ejecutado correctamente sin inconvenientes y por si dudan, si prueban cambiando el RVA de las importaciones sin usar la shellcode el programa no ejecutar ya que Windows carga las direcciones en base a ese RVA.

RELACIONANDO ESTA CIFRADORES Y PACKERS:

TCNICA

CON

Si analizamos bien lo que hicimos sabremos que no es tan fcil cifrar la tabla de importaciones porque no bastar con cifrar en disco y descifrar en memoria ya que Windows carga las direcciones de las funciones antes de

Cargando funciones importadas manualmente The Swash

Pgina 11

llegar siquiera al punto de entrada del programa, as que lo que si se podra hacer es: - Cifrar en disco todas las importaciones (incluyendo cadenas de las API). - Insertar una rutina que descifre esa parte anteriormente cifrada. - Posteriormente que ejecute nuestra shellcode para que cargue las funciones en memoria. - Salto al punto de entrada original. Quiz algunas cosas de esta rutina y la shellcode haga que salten algunos Antivirus y es porque son tcnicas utilizadas en malware pero fcilmente pueden modificarse. Con esto termino y paso a la despedida.

DESPEDIDA
Como es costumbre en mis artculos suelo siempre despedirme, as me lo ensearon desde pequeo y tambin suelo agradecer a quienes me han apoyado y ayudado sin condiciones. Mis agradecimientos a: - [Zero] - Psymera - Thor - Karcrack - Steve10120 - Shaddy - CracksLatinos - https://groups.google.com/group/crackslatinos?hl=es - Sector-Viruz - https://groups.google.com/group/sector-viruz?hl=es - H-SEC - http://foro.h-sec.org/ Es un honor compartir mi trabajo con todos ustedes, muchas gracias por compartir los suyos tambin. Espero hayan aprendido algo con l o por lo menos se hayan divertido. Hasta la prxima. Cargando funciones importadas manualmente The Swash Pgina 12

Cualquier duda, crtica o sugerencia: @MSN : the_swash@hotmail.es @GTalk: jcuastumal@gmail.com

Cargando funciones importadas manualmente The Swash

Pgina 13

S-ar putea să vă placă și