Análisis de formato de archivo ejecutable de la plataforma UNIX /LINUX

  
 

Este artículo describe tres formatos principales de archivos ejecutables para la plataforma UNIX /LINUX: a.out (salida de ensamblador y editor de enlaces, salida de editor de enlaces), COFF (Formato de archivo de objeto común) , ELF (ejecutable y formato de enlace ejecutable y formato de enlace). El primero es una descripción general del formato de archivo ejecutable y describe la relación entre el contenido del archivo ejecutable y la operación de ejecución de carga al describir el proceso de carga de archivos ELF. Los tres formatos de archivo se discutieron de esta manera, y el mecanismo de conexión dinámica de los archivos ELF y la evaluación de las ventajas y desventajas de varios formatos de archivo se intercalaron. Finalmente, hay un breve resumen de los tres formatos de archivo ejecutable, y se presentan algunos comentarios sobre la evaluación del autor del formato de archivo.

Referencias 17) Las habilidades de escritura son un ejemplo práctico de romper esta protección.

2: El kernel analiza el nombre del conector dinámico correspondiente al segmento del archivo ELF marcado PT_INTERP y carga el conector dinámico. El enlazador dinámico para los sistemas LINUX modernos suele ser /lib/ld-linux.so.2, y los detalles se describen en detalle más adelante.

3: El kernel establece algunos pares etiqueta-valor en la pila del nuevo proceso para indicar las operaciones relevantes del enlazador dinámico.

4: El kernel pasa el control al conector dinámico.

5: Dynamic Connector comprueba las dependencias del programa en archivos externos (bibliotecas compartidas) y las carga según sea necesario.

6: El enlazador dinámico reubica la referencia externa del programa. En términos simples, le dice al programa la dirección de la variable /función externa a la que hace referencia. Esta dirección se encuentra en el intervalo en el que se carga la biblioteca compartida en la memoria. La vinculación dinámica también tiene una función de posicionamiento lento que se reubica solo cuando "verdadero" requiere un símbolo de referencia, lo que mejora considerablemente la eficiencia del programa.

7: El enlazador dinámico ejecuta el código de la sección marcada como .init en el archivo ELF para inicializar la ejecución del programa. En los sistemas anteriores, el código de inicialización corresponde a la función _init (void) (el nombre de la función debe ser fijo). En los sistemas modernos, la forma correspondiente es void__attribute ((constructor)) init_function (void) {… …}

donde el nombre de la función es arbitrario.

8: El enlazador dinámico pasa el control al programa y se ejecuta desde el punto de entrada del programa definido en el encabezado del archivo ELF. En el formato a.out y el formato ELF, el valor del punto de entrada del programa está presente explícitamente, y en el formato COFF está implícitamente definido por la especificación.

Como puede ver en la descripción anterior, lo más importante para cargar un archivo es hacer dos cosas: cargar el segmento del programa y el segmento de datos en la memoria, realizar la reubicación del símbolo definido externamente. La reubicación es un concepto importante en la vinculación de programas. Sabemos que un programa ejecutable generalmente consiste en un archivo de programa principal que contiene main (), varios archivos de objeto y varias bibliotecas compartidas (bibliotecas compartidas).
(Nota: con algunos trucos especiales, también puede escribir programas sin la función principal, consulte la Referencia 2) Un programa en C puede hacer referencia a variables o funciones definidas por bibliotecas compartidas. En otras palabras, estas variables /funciones deben ser conocidas en tiempo de ejecución. Direccion En una conexión estática, todas las definiciones externas que el programa necesita usar están completamente contenidas en el programa ejecutable, mientras que las conexiones dinámicas solo establecen cierta información de referencia sobre la definición externa en el archivo ejecutable. La reubicación real es cuando el programa se está ejecutando. . Hay dos grandes problemas con las conexiones estáticas: si hay cambios en las variables o funciones en la biblioteca, debe volver a compilar el enlazador, si varios programas hacen referencia a la misma variable /función, la variable /función aparecerá varias veces en el archivo /memoria. , desperdiciando disco duro /espacio de memoria. Comparando el tamaño de los archivos ejecutables generados por los dos métodos de conexión, se puede ver que hay una clara diferencia.




Volver al principio


Referencias 16 y lectura de la referencia 15 Profundización del código fuente Una comprensión del formato a.out. La referencia 12 explica cómo ejecutar archivos de formato a.out en " moderno " Red Hat Linux.




Volver al principio


Referencia 18, algunos sistemas UNIX también tienen COFF El formato se ha extendido, como el formato XCOFF (formato de archivo de objeto común extendido), que admite conexiones dinámicas, consulte la referencia 5.

El encabezado del archivo es opcional. La especificación de formato de archivo COFF especifica que la longitud del encabezado opcional puede ser 0, pero el encabezado opcional debe existir en el sistema LINUX. La siguiente es la estructura de datos del encabezado opcional bajo LINUX: typedef struct {char magic [2]; /* número mágico * /char vstamp [2]; /* número de versión * /char tsize [4]; /​​* longitud del segmento de texto * /char dsize [4]; /​​* longitud del segmento de datos inicializado * /char bsize [4]; /​​* longitud del segmento de datos sin inicializar * /entrada de caracteres [4]; /​​* punto de entrada del programa * /char text_start [4]; /* dirección base del segmento de texto * /char data_start [4]; /​​* dirección base del segmento de datos * /} COFF_AOUTHDR;

Cuando el campo magic es 0413, el archivo COFF es ejecutable y se anota el encabezado opcional. El punto de entrada del programa se define explícitamente en la sección. El archivo COFF estándar no define explícitamente el valor del punto de entrada del programa, generalmente a partir de la sección .text, pero este diseño no es bueno.

Antes de que mencionáramos que el formato COFF tiene una tabla de segmentos más que el formato a.out, una entrada de encabezado de sección describe los detalles de los datos de una sección, por lo que el formato COFF puede contener más secciones, o puede basarse en La necesidad real de agregar una sección específica, específicamente en la definición del formato COFF en sí y la extensión de formato COFF mencionada anteriormente. Personalmente, creo que la apariencia de una tabla de segmentos puede ser la mejora más grande en el formato COFF en relación con el formato a.out. A continuación, describiremos brevemente la estructura de datos de la sección en el archivo COFF, porque el significado de la sección se refleja más en la compilación y conexión del programa, por lo que este artículo no lo describe más. Además, el formato ELF y el formato COFF definen las secciones de manera muy similar, y omitiremos la discusión en el análisis del formato ELF posterior. Struct COFF_scnhdr {char s_name [8]; /* nombre de sección * /char s_paddr [4]; /​​* dirección física * /char s_vaddr [4]; /​​* dirección virtual * /char s_size [4]; /​​* longitud de sección * /char s_scnptr [4]; /​​* El desplazamiento de los datos de la sección en relación con el archivo * /char s_relptr [4]; /​​* desplazamiento de la información de reubicación de la sección * /char s_lnnoptr [4]; /​​* desplazamiento de la información de la sección * /char s_nreloc [2]; /* número de entradas de reubicación de la sección * /char s_nlnno [2]; /* número de elementos de información de la sección * /char s_flags [4]; /​​* marca de sección * /};
< Hay un punto a tener en cuenta: el comentario en el campo s_paddr en el archivo de cabecera coff.h en el sistema Linux es "dirección física", pero parece entenderse como la cantidad de espacio ocupado por la sección "carga" en la memoria ". El campo s_flags marca el tipo de la sección, como un segmento de texto, un segmento de datos, un segmento de BSS y similares. La información de línea también aparece en la sección COFF. La información de línea describe la asignación entre el código binario y el número de línea del código fuente, que es útil durante la depuración.

Referencias 19 es una descripción detallada en chino del formato COFF. Para más detalles, consulte la Referencia 20.




Volver al principio


El autor de la referencia 1 habla sobre el encabezado de la sección Todos los datos se establecen en 0, el programa también puede ejecutarse correctamente! El encabezado ELF es una hoja de ruta de este documento que describe la estructura del archivo en su totalidad. La siguiente es la estructura de datos del encabezado ELF:

Copyright © Conocimiento de Windows All Rights Reserved