¿Qué partes de un ejecutable ELF se cargan en la memoria y dónde?


10

Lo que ya sé:

Un ejecutable ELF tiene varias secciones, obviamente las secciones .text y .data se cargan en la memoria, ya que estas son las partes principales del programa. Pero para que un programa funcione, necesita más información, especialmente cuando está vinculado dinámicamente.

Lo que me interesa son secciones como .plt, .got, .dynamic, .dynsym, .dynstr, etcétera. Las partes del ELF que son responsables de la vinculación de funciones a direcciones.

Por lo que he podido descubrir hasta ahora, es que cosas como .symtab y .strtab no se cargan (o no permanecen) en la memoria. ¿Pero son los .dynsym y .dynstr utilizados por el enlazador? ¿Se quedan en la memoria? ¿Puedo acceder a ellos desde el código del programa?

¿Y hay partes de un ejecutable que residen en la memoria del núcleo?

Mi interés en esto es principalmente forense, pero cualquier información sobre este tema me ayudará. Los recursos que he leído sobre estas tablas y enlaces dinámicos son de más alto nivel, solo explican el funcionamiento, no nada práctico sobre los contenidos en la memoria.

Avíseme si hay algo que no esté claro sobre mi pregunta.

Respuestas:


12

La siguiente es una muy buena referencia: http://www.ibm.com/developerworks/linux/library/l-dynamic-libraries/ . Contiene una bibliografía al final de una variedad de referencias diferentes en diferentes niveles. Si desea conocer cada detalle sangriento, puede ir directamente a la fuente: http://www.akkadia.org/drepper/dsohowto.pdf . (Ulrich Drepper escribió el enlazador dinámico de Linux).

Puede obtener una visión general realmente buena de todas las secciones en su ejecutable ejecutando un comando como "objdump -h myexe" o "readelf -S myexe".

La sección .interp contiene el nombre del cargador dinámico que se utilizará para vincular dinámicamente los símbolos en este objeto. La sección .dynamic es una destilación del encabezado del programa que está formateada para que sea fácil de leer para el cargador dinámico. (Por lo tanto, tiene punteros a todas las otras secciones).

El .got (Tabla de compensación global) y .plt (Tabla de vinculación de procedimientos) son las dos estructuras principales que son manipuladas por el vinculador dinámico. .Got es una tabla de indirección para variables y .plt es una tabla de indirección para funciones. Cada ejecutable o biblioteca (que se denominan "objetos compartidos") tiene sus propios .got y .plt y estas son tablas de los símbolos a los que hace referencia ese objeto compartido que están realmente contenidos en algún otro objeto compartido.

El .dynsyn contiene toda la información sobre los símbolos en su objeto compartido (tanto los que define como los externos a los que necesita hacer referencia). El .dynsyn no contiene los nombres de símbolos reales. Estos están contenidos en .dynstr y .dynsyn tiene punteros en .dynstr. .gnu.hash es una tabla hash utilizada para la búsqueda rápida de símbolos por nombre. También contiene solo punteros (punteros en .dynstr y punteros utilizados para hacer cadenas de cubos).

Cuando su objeto compartido hace referencia a algún símbolo "foo", el enlazador dinámico tiene que buscar "foo" en todos los objetos dinámicos con los que está vinculado para averiguar cuál contiene el "foo" que está buscando (y luego cuál es la relación la dirección de "foo" está dentro de ese objeto compartido.) El enlazador dinámico hace esto buscando en la sección .gnu.hash de todos los objetos compartidos vinculados (o en la sección .hash para objetos compartidos antiguos que no tienen un .gnu. sección hash.) Una vez que encuentra la dirección correcta en el objeto compartido vinculado, la coloca en el .got o .plt de su objeto compartido.


Gracias, sus enlaces me llevan un paso más allá para descubrir las asignaciones virtuales de las secciones que necesito. Como mi interés en esto es forense, "cargado en DRAM" sigue siendo relevante para mí. Si una sección está asignada pero nunca cargada, no podré encontrarla en un volcado de memoria :)
Dutchy

Tienes razón. Cuando realice el volcado de memoria, obtendrá una copia de cada página asignada, por lo que mi distinción entre "mapeado en vm" y "cargado en DRAM" fue irrelevante. Eliminé esa oración y la respuesta mejoró. ¡Gracias!
Wandering Logic

Marqué su respuesta como la respuesta, porque es tanta información como voy a obtener :) tendré que hacer el resto yo mismo, es mi investigación después de todo.
Dutchy

Entonces, sí .dynsym y .dynstr (y otros) son utilizados por el enlazador dinámico y se cargan en la memoria del programa (en el segmento de texto) y su programa podría usarlos en tiempo de ejecución.
ysdx
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.