You are on page 1of 14

Formato de archivos PE

Cuando se enfrenta al listado "en vivo" (en un depurador) o "muerto" (desensambl ado por ejemplo mediante W32DASM) de un programa target, el reverser es como un cirujano para quien los ms intrincados detalles de la anatoma y fisiologa del pacie nte deber ser conocidos para tener mayores chances de xito. Lo que sigue es un eq uivalente a un estudio anatmico, un sumario del formato y header de archivos ejec utables PE de Win32 con tres ejemplos de cdigo fuente: un primer programa escrito en C++, despus un rudimentario programa Windows escrito en lenguaje Assembly y f inalmente un listado desensamblado generado por W32DASM del programa C++. Espero que la revisin y comparacin de estos permita al reverser familiarizarse con las e structuras fundamentales y "rganos" de su target y asi estar preparado para patch ear con xito cualquier programa que le llegue. FORMATO DE ARCHIVOS PE "En un comienzo", haba slo dos tipos de archivos ejecutables: los .COM (ejecutable s de un slo segmento) y .EXE (ejecutables de varios segmentos). Debido a que los archivos .COM ocupan un slo segmento, no tenan necesidad de header y por lo tanto se cargaban en el primer segmento de memoria disponible. En cambio, los .EXE nec esitaban frecuentemente usar varios segmentos y fue preciso dotarlos con un head er (el encabezamiento del archivo) de 64 bytes para informarle al SO cuntos segme ntos seran necesarios y cmo deban ser allocados. El SO Windows fue desarrollado con la idea que los archivos ejecutables deban usa r una coleccin de funciones provistas por el ncleo del SO, llamadas API. Como el p rograma no deba ya manejar cosas tales como entrada desde teclado, seguimiento de l mouse y salida a pantalla, y como se esperaba que un programa comparta la memo ria con varios otros programas corriendo en forma simultnea, fue preciso suminist rarle al SO mayor cantidad de informacin para que la comunicacin entre SO y progra ma sea eficiente y completa (en contrapartida con los programas DOS que frecuent emente ignoraban por completo al sistema operativo). Fue asi que se crearon los tipos de archivos ejecutable NE, LZ y PE (y sus headers): el formato de archivo impone una estructura al archivo ejecutable y el header del archvo diagrama esa estructura. Mediante el conocimiento del formato y header de archivos PE, se pue den hacer un sorprendente nmero de cambios en el archivo PE contando solamente co n un editor hexa (mejor si es uno que interpreta el header de los archivos PE co mo el Hiew 5.66) El header de un PE comienza con el header del DOS (MZ) MZ Header WORD e_magic nmero mgico WORD e_cblp

Bytes en la ltima pgina del archivo WORD e_cp Cantidad de pginas del archivo WORD e_crlc Relocaciones WORD e_cparhdr Longitud del header en pargrafos WORD e_minalloc Minimo de pargrafos extra necesarios WORD e_maxalloc Maximo de pargrafos extra necesarios WORD e_ss Valor inicial (relativo) de SS WORD e_sp Valor inicial de SP WORD

e_csum Checksum WORD e_ip Valor inicial de IP WORD e_cs Valor inicial (relativo) de CS WORD e_lfarlc Direccin de la tabla de relocacin WORD e_ovno Nmero de overlays WORD e_res[4] Palabras reservadas WORD e_oemid Identificador de OEM (e_oeminfo) WORD e_oeminfo

Informacin de OEM (e_oemid) WORD e_res2[10] Reservadas DWORD e_lfanew Direccin del nuevo header exe Esto es seguido por un programa "stub" (tal como winstub.exe) que es ejecutado s i el programa PE es corrido fuera del ambiente Windows; usualmente esto escribe en la pantalla el mensaje: "este programa requiere MS-Windows para correr", pero puede ser modificado por el programador para que diga cualquier otra cosa, o ev entualmente hacer correr una segunda versin (DOS) del programa como para hacerlo ms portable (parece gracioso, pero nadie parece haberse tomado el tiempo como par a hacerlo hasta ahora). Despus del stub, viene la firma 00004550 ("PE",0,0), y lu ego el header PE: Estos ejemplos de header de archivo PE son del Notepad.exe) WORD Tipo_ de_ Mquina 014C WORD Nmero_ de_ Secciones 0006 DWORD Time/Date_ Stamp 2FF3548D DWORD Puntero_ a_ la_ Symbol_ Table

00000000 DWORD Nmero_ de_ Smbolos 00000000 WORD Longitud_ del_ Optional_ Header 00E0 WORD Caractersticas 010E PE Optional Header WORD Magic 010B BYTE MajorLinkerVersion 02 BYTE MinorLinkerVersion 32 DWORD SizeOfCode 00003A00

DWORD SizeOfInitializedData 00004800 DWORD SizeOfUninitializedData 00000600 DWORD AddressOfEntryPoint 00001000 DWORD BaseOfCode 00001000 DWORD BaseOfData 00005000 ----Campos opcionales para NT (slo para Windows NT)---DWORD ImageBase; DWORD SectionAlignment; DWORD FileAlignment; WORD

MajorOperatingSystemVersion; WORD MinorOperatingSystemVersion; WORD MajorImageVersion; WORD MinorImageVersion; WORD MajorSubsystemVersion; WORD MinorSubsystemVersion; DWORD Reserved1; DWORD SizeOfImage; DWORD SizeOfHeaders; DWORD CheckSum; WORD Subsystem; WORD DllCharacteristics; DWORD

SizeOfStackReserve; DWORD SizeOfStackCommit; DWORD SizeOfHeapReserve; DWORD SizeOfHeapCommit; DWORD LoaderFlags; DWORD NumberOfRvaAndSizes; Inmediatamente despus del header del archivo, vienen los Section Headers Section Header BYTE Name[IMAGE_SIZEOF_SHORT_NAME]; DWORD PhysicalAddress; DWORD VirtualSize; DWORD VirtualAddress; DWORD SizeOfRawData; DWORD

PointerToRawData; DWORD PointerToRelocations; DWORD PointerToLinenumbers; WORD NumberOfRelocations; WORD NumberOfLinenumbers; DWORD Characteristics; Advirtase que hay un Header Section por seccin; asi, de acuerdo con el PE Header d el Notepad, habr 6 Section Headers. Cada seccin contiene su propio nombre en un st ring ASCII (por ejempo, ".text") y un puntero a su ubicacin dentro del archivo; e stos headers son de una longitud de 40 bytes y no estn previstos bytes de relleno entre ellos. Las secciones que normalmente estn presentes en un ejecutable son: .text (seccin de cdigo ejecutable) .data (seccin de datos, tambin puede haber .rdata o .bss) .rsrc (seccin de recursos) .edata (seccin de datos exportados) .idata (seccin de datos importados)

.debug (seccin de informacin sobre depuracin) Advierta que no todas estas secciones deben necesariamente estar presentes. Cuan do se busca una seccin especfica, a veces conviene saltearse el header completo y buscar directamente el nombre ASCII de la seccin en el editor hexa. Seccin de cdigo ejecutable .TEXT Esta seccin contiene el cdigo del programa y la tabla de saltos fixup. Esta seccin no tiene un formato especfico. Seccin de datos: .data, .rdata, .bss Hay tres tipos de secciones de datos: .bss contiene datos sin inicializar (inclu yendo todas las variables declaradas como static); .rdata contiene datos de slo-l ectura, tales como strings y constantes; .data contiene variables globales para el programa. Tampoco tiene estructura. Seccin de recursos: .rsrc Esta seccin contiene todos los recursos para la aplicacin. Los primeros 16 bytes c ontienen el Resource Directory Header, que se estructura como sigue: Resource Directory DWORD Characteristics; DWORD TimeDateStamp; WORD MajorVersion; WORD MinorVersion; WORD NumberOfNamedEntries; WORD NumberOfIdEntries;

Es inmediatamente seguido por el nmero de Directory Entries especificado en Numbe rOfNamedEntries + NumberOfIdEntries: Resource Directory Entry DWORD Name; DWORD OffsetToData; El campo Name de una Directory Entry determina el tipo del recurso (como se lo d efine en winuser.h), mientras que el offset apunta o bien a otra Directory Entry (la estructura usual es 1 Resource Directory conteniendo el tipo de recurso apu ntando a un Resource Directory (o subdirectory) conteniendo el Resource ID# y un puntero a Resource Data Entry), o bien a un Resource Data Entry. Resource Data Entry DWORD OffsetToData; DWORD Size; DWORD CodePage; DWORD Reserved; Una Resource Data Entry contiene el tamao y offset del dato de recurso real, el c ual ser una lista de strings unicode (para una tabla de strings), una imagen bina ria (para un bitmap), o una lista de valores y strings (para un dialog box). En el documento "Win32 binary resource formats" publicado por Micro$oft se puede en contrar informacin sobre el formato del contenido de un recurso binario. Seccin Export Data: .edata La seccin .edata contiene los datos exportados y funciones para una aplicacin o li brera (.DLL). La seccin comienza con el Export Directory. Export Directory DWORD Characteristics; DWORD TimeDateStamp; WORD MajorVersion; WORD MinorVersion; DWORD Name; DWORD

Base; DWORD NumberOfFunctions; DWORD NumberOfNames; DWORD *AddressOfFunctions; DWORD *AddressOfNames; WORD *AddressOfNameOrdinals; Los ltimos tres campos contienen punteros a una lista de puntos de entrada de fun ciones exportadas, una lista que contiene los nombres de las funciones separadas por caracteres NULL, y una lista de valores ordinales de las funciones. Note qu e esos punteros asumen que el programa est cargado; para encontrar las listas den tro del archivo, uno debe restar la direccin virtual del Section Header del campo AddressOf... y luego sumar la direccin del PointerToRawData. Seccin datos importados: .idata Esta seccin contiene las listas de las funciones importadas por el programa. Comi enza con el Import Directory: Import Directory DWORD dwRVAFunctionNameList; DWORD dwUseless1; DWORD dwUseless2; DWORD

dwRVAModuleName; DWORD dwRVAFunctionAddressList; Los dos ltimos campos estn repetidos para cada aplicacin o librera desde la que impo rta el programa; con un editor hexa se puede ver que el orden es un poco extrao: el nombre de la primera funcin importada desde un mdulo dado, luego el nombre del mdulo, luego cualquier otra funcin importada desde ese mdulo. El listado se repite hasta encontrar una entrada null. Seccin informacin de depuracin: .debug Esta seccin contiene la informacin de depuracin del programa, si es que el compilad or fue instrudo para incluirla. Comienza con un Debug Directory: Debug Directory DWORD Characteristics; DWORD TimeDateStamp; WORD MajorVersion; WORD MinorVersion; DWORD Type; DWORD SizeOfData; DWORD AddressOfRawData; DWORD

PointerToRawData; Los diferentes tipos de informacin de debug estn definidos en el archivo winuser.h ; cualquier otra estructura impuesta en cada tipo de informacin de depuracin est ta mbin definida aqui. Modificacin de un Header de archivo PE Desde que un header de PE da la direccin de arranque y longitud de cada una de su s secciones (y, como en el caso de la seccin .rsrc, la longitud real de los datos ), es bastante simple aunque tedioso modificar el contenido de un header de PE, cambiando su tamao original mediante el ajuste de los campos offset de cada seccin segn las modificaciones introducidad. Para agregar cdigo adicional uno debe exten der la seccin .text y reparar cada seccin posterior. Para agregar o modificar recu rsos, se debe modificar cada subdirectorio de la seccin .rsrc y reparar cada secc in subsiguiente (esta es la manera en que operan BRW y Resource Studio). Puede co nvenir que para cambiar cualquier seccin sea mejor mover su direccin virtual al fi nal del archivo PR y extender la seccin anterior a esta para cubrir el vaco result ante el cual, por cierto debe llenarcos con bytes 00. Advirtase que esto es algo azaroso especialmente con las secciones .text y .idata y que la longitud del eje cutable se incrementa un poco. No obstante es el mtodo ms rpido y fcil en muchos cas os, ya que slo es necesario reparar dos secciones (la modificada y la anterior a esta). Como alternativa, si la informacin agregada son datos referenciados direct amente por el programa (y esto puede hacer deseable ubicar el cdigo ejecutable en directorios Data, y referirse a ellos por su offset dentro del programa e inser tarlo dentro del ejecutable), es agregar los datos a la ltima seccin y extender es a seccin hasta comprender todos los datos adicionados. Mammon_

You might also like