Del código fuente al código binario
La programación comienza con tener una idea inteligente y escribir código fuente en un lenguaje de programación de su elección, por ejemplo C, y guardar el código fuente en un archivo. Con la ayuda de un compilador adecuado, por ejemplo, GCC, su código fuente se traduce en código de objeto, primero. Finalmente, el enlazador traduce el código de objeto en un archivo binario que vincula el código de objeto con las bibliotecas referenciadas. Este archivo contiene las instrucciones únicas como código de máquina que entiende la CPU, y se ejecutan tan pronto como se ejecuta el programa compilado.
El archivo binario mencionado anteriormente sigue una estructura específica, y uno de los más comunes se llama ELF que abrevia el formato ejecutable y vinculable. Se usa ampliamente para archivos ejecutables, archivos de objetos reubicables, bibliotecas compartidas y volcados de núcleo.
Hace veinte años, en 1999, el Proyecto 86Open ha elegido ELF como el formato de archivo binario estándar para sistemas similares a UNIX y UNIX en procesadores X86. Afortunadamente, el formato ELF se había documentado previamente tanto en la interfaz binaria del sistema v como en el estándar de la interfaz de herramienta [4]. Este hecho simplificó enormemente el acuerdo sobre la estandarización entre los diferentes proveedores y desarrolladores de sistemas operativos basados en UNIX.
La razón detrás de esa decisión fue el diseño de ELF: flexibilidad, extensibilidad y soporte multiplataforma para diferentes formatos de Endian y tamaños de dirección. El diseño de ELF no se limita a un procesador, conjunto de instrucciones o arquitectura de hardware específicas. Para una comparación detallada de formatos de archivo ejecutables, eche un vistazo aquí [3].
Desde entonces, el formato ELF está en uso por varios sistemas operativos diferentes. Entre otros, esto incluye Linux, Solaris/Illumos, Free, Net y OpenBSD, QNX, Beos/Haiku y Fuchsia OS [2]. Además, lo encontrará en dispositivos móviles que ejecutan Android, Maemo o Meego OS/Sailfish OS, así como en consolas de juegos como PlayStation Portable, Dreamcast y Wii.
La especificación no aclara la extensión del nombre de archivo para archivos ELF. En uso hay una variedad de combinaciones de letras, como .hacha, .papelera, .duende, .O, .prx, .soplo, .KO, .y entonces .mod, o ninguno.
La estructura de un archivo ELF
En un terminal de Linux, el Man Man de comandos le brinda un resumen útil sobre la estructura de un archivo ELF:
Listado 1: La página de manejo de la estructura de elfos
$ hombre elfoComo puede ver en la descripción anterior, un archivo ELF consta de dos secciones: un encabezado ELF y datos de archivo. La sección de datos del archivo puede consistir en una tabla de encabezado del programa que describe cero o más segmentos, una tabla de encabezado de sección que describe cero o más secciones, que es seguido por los datos mencionados por las entradas desde la tabla de encabezado del programa y la tabla de encabezado de sección. Cada segmento contiene información que es necesaria para la ejecución en tiempo de ejecución del archivo, mientras que las secciones contienen datos importantes para vincular y reubicar. La Figura 1 ilustra este esquemáticamente.
El encabezado elfo
El encabezado ELF tiene 32 bytes de largo e identifica el formato del archivo. Comienza con una secuencia de cuatro bytes únicos que son 0x7f seguidos de 0x45, 0x4c y 0x46 que se traduce en las tres letras E, L y F. Entre otros valores, el encabezado también indica si se trata de un archivo ELF para formato de 32 o 64 bits, utiliza poca o gran endianness, muestra la versión ELF y para el cual se compiló el sistema operativo para interpererar con el Interfaz binaria de aplicación correcta (ABI) y Conjunto de instrucciones de CPU.
El hexdump del archivo binario se ve de la siguiente manera:
.Listado 2: el hexdump del archivo binario
$ HD/usr/bin/touch | Cabeza -5Debian GNU/Linux ofrece el comando Readelf que se proporciona en el paquete de GNU 'binutils'. Acompañado por el switch -h (versión corta para "-file-header") Muestra muy bien el encabezado de un archivo ELF. El listado 3 ilustra esto para el toque de comando.
.Listado 3: Mostrar el encabezado de un archivo ELF
$ readelf -h/usr/bin/touchEl encabezado del programa
El encabezado del programa muestra los segmentos utilizados en tiempo de ejecución y le dice al sistema cómo crear una imagen de proceso. El encabezado del Listado 2 muestra que el archivo ELF consta de 9 encabezados del programa que tienen un tamaño de 56 bytes cada uno, y el primer encabezado comienza en Byte 64.
Nuevamente, el comando Readelf ayuda a extraer la información del archivo ELF. El interruptor -l (abreviatura de -program -headers o -segments) revela más detalles como se muestra en el Listado 4.
.Listado 4: Mostrar información sobre los encabezados del programa
$ readelf -l/usr/bin/touchEl encabezado de la sección
La tercera parte de la estructura de elfo es el encabezado de sección. Está destinado a enumerar las secciones únicas del binario. El interruptor -s (abreviatura de -sesion -headers o -sections) enumera los diferentes encabezados. En cuanto al comando touch, hay 27 encabezados de sección, y el listado 5 muestra los primeros cuatro más el último, solo. Cada línea cubre el tamaño de la sección, el tipo de sección, así como su dirección y compensación de memoria.
.Listado 5: Detalles de la sección revelados por Readelf
$ readelf -s/usr/bin/touchHerramientas para analizar un archivo ELF
Como puede haber señalado en los ejemplos anteriores, GNU/Linux se desarrolla con una serie de herramientas útiles que lo ayudan a analizar un archivo ELF. El primer candidato que veremos es la utilidad de los archivos.
El archivo muestra información básica sobre los archivos ELF, incluida la arquitectura del conjunto de instrucciones para la cual está previsto el código en un archivo de objeto reubicable, ejecutable o compartido. En el Listado 6 le indica que/bin/touch es un archivo ejecutable de 64 bits que sigue a la base estándar de Linux (LSB), vinculada dinámicamente y creada para la versión 2 de Kernel GNU/Linux.6.32.
.Listado 6: Información básica utilizando el archivo
$ archivo /bin /touchEl segundo candidato es el lectura. Muestra información detallada sobre un archivo ELF. La lista de interruptores es comparablemente larga y cubre todos los aspectos del formato Elfo. Usando el Listado 7 -N (abreviatura de -notes), muestra las secciones de nota, solo que existen en el archivo touch: la etiqueta de versión ABI y la bitstring de ID de compilación.
.Listado 7: Muestra secciones seleccionadas de un archivo ELF
$ readelf -n/usr/bin/touchTenga en cuenta que bajo Solaris y FreeBSD, la utilidad Elfdump [7] se corresponde con Readelf. A partir de 2019, no ha habido una nueva versión o actualización desde 2003.
El número tres es el paquete llamado Elfutils [6] que está puramente disponible para Linux. Proporciona herramientas alternativas para los binutilos GNU, y también permite validar archivos ELF. Tenga en cuenta que todos los nombres de las utilidades proporcionadas en el paquete comienzan con la UE para 'Elf Utils'.
Por último, pero no menos importante, mencionaremos Objdump. Esta herramienta es similar a la lectura pero se enfoca en archivos de objetos. Proporciona una gama similar de información sobre los archivos ELF y otros formatos de objetos.
.Listado 8: Información del archivo extraída por OBJDUMP
$ objdump -f /bin /touchTambién hay un paquete de software llamado 'Elfkickers' [9] que contiene herramientas para leer el contenido de un archivo ELF, así como manipularlo. Desafortunadamente, el número de lanzamientos es bastante bajo, y es por eso que lo mencionamos y no mostramos más ejemplos.
Como desarrollador, puede echar un vistazo a 'Pax-Utils' [10,11], en su lugar. Este conjunto de utilidades proporciona una serie de herramientas que ayudan a validar los archivos ELF. Como ejemplo, Dumpelf analiza el archivo ELF y devuelve un archivo de encabezado C que contiene los detalles; consulte la Figura 2.
Gracias a una combinación de diseño inteligente y excelente documentación, el formato de elfo funciona muy bien, y todavía está en uso después de 20 años. Las utilidades que se muestran arriba le permiten una vista de información sobre un archivo ELF y le permiten averiguar qué está haciendo un programa. Estos son los primeros pasos para analizar el software: Happy Hacking!
El escritor desea agradecer a Axel Beckert por su apoyo con respecto a la preparación de este artículo.