GNU/Linux >> Tutoriales Linux >  >> Linux

Encabezados de archivos ELF

No conozco comandos de secuencias de comandos del enlazador que puedan hacer esto, pero puede hacerlo después del enlace usando objcopy dominio. La --agregar-sección La opción se puede usar para agregar una sección que contenga datos arbitrarios al archivo ELF. Si el encabezado ELF no contiene los campos que desea, simplemente cree una nueva sección y agréguelos allí.


Este enlace (binario elfo adolescente) fue la respuesta de alguien a otra pregunta, pero entra en las complejidades de un encabezado ELF con cierto detalle.


Puede crear un archivo de objeto con campos informativos como un número de versión y vincular ese archivo para que se incluyan en el binario ELF resultante.

Identificación

Por ejemplo, como parte de su proceso de compilación, puede generar, digamos, info.c que contiene uno o más #ident directivas:

#ident "Build: 1.2.3 (Halloween)"
#ident "Environment: example.org"

Compílalo:

$ gcc -c info.c

Compruebe si la información está incluida:

$ readelf -p .comment info.o
String dump of section '.comment':
  [     1]  Build: 1.2.3 (Halloween)
  [    1a]  Environment: example.org
  [    33]  GCC: (GNU) 7.2.1 20170915 (Red Hat 7.2.1-2)

Alternativamente, puede usar objdump -s --section .comment info.o . Tenga en cuenta que GCC también escribe su propio comentario, de forma predeterminada.

Verifique la información después de vincular un ejecutable ELF:

$ gcc -o main main.o info.o
$ readelf -p .comment main 
String dump of section '.comment':
  [     0]  GCC: (GNU) 7.2.1 20170915 (Red Hat 7.2.1-2)
  [    2c]  Build: 1.2.3 (Halloween)
  [    45]  Environment: example.org

Sección de comentarios

Usando #ident en una unidad de traducción de C es básicamente equivalente a crear un .comment sección en un archivo ensamblador. Ejemplo:

$ cat info.s
.section .comment
.string "Build: 1.2.3 (Halloween)"
.string "Environment: example.org"
$ gcc -c info.s
$ readelf -p .comment info.o
String dump of section '.comment':
  [     0]  Build: 1.2.3 (Halloween)
  [    19]  Environment: example.org

El uso de un nombre de sección poco común también funciona (por ejemplo, .section .blahblah ). Pero .comment es utilizado y entendido por otras herramientas. GNU como también entiende el .ident directiva, y esto es lo que GCC traduce #ident a.

Con Símbolos

Para los datos a los que también desea acceder desde el ejecutable ELF, debe crear símbolos.

Objcopia

Digamos que desea incluir algunos bytes mágicos almacenados en un archivo de datos:

$ cat magic.bin 
2342

Convertir en un archivo de objeto con GNU objcopy:

$ objcopy -I binary -O elf64-x86-64 -B i386 \
    --rename-section .data=.rodata,alloc,load,readonly,data,contents \
    magic.bin magic.o

Compruebe los símbolos:

$ nm  magic.o  
0000000000000005 R _binary_magic_bin_end
0000000000000005 A _binary_magic_bin_size
0000000000000000 R _binary_magic_bin_start

Ejemplo de uso:

#include <stdio.h>
#include <string.h>
#include <inttypes.h>

extern const char _binary_magic_bin_start[];
extern const char _binary_magic_bin_end[];
extern const unsigned char _binary_magic_bin_size;
static const size_t magic_bin_size = (uintptr_t) &_binary_magic_bin_size;

int main()
{
  char s[23];
  memcpy(s, _binary_magic_bin_start,
      _binary_magic_bin_end - _binary_magic_bin_start);
  s[magic_bin_size] = 0;
  puts(s);
  return 0;
}

Vincula todo junto:

$ gcc -g -o main_magic main_magic.c magic.o

GNU ld

GNU ld también puede convertir archivos de datos en archivos de objetos utilizando un esquema de nombres compatible con objcopy:

$ ld -r -b binary magic.bin -o magic-ld.o

A diferencia de objcopy, coloca los símbolos en el .data en lugar del .rodata sección, sin embargo (cf. objdump -h magic.o ).

incbin

En caso de que GNU objcopy no esté disponible, se puede usar GNU como .incbin directiva para crear el archivo de objeto (ensamblar con gcc -c incbin.s ):

    .section .rodata

    .global _binary_magic_bin_start
    .type _binary_magic_bin_start, @object
_binary_magic_bin_start:
    .incbin "magic.bin"
    .size _binary_magic_bin_start, . - _binary_magic_bin_start

    .global _binary_magic_bin_size
    .type _binary_magic_bin_size, @object
    .set _binary_magic_bin_size, . - _binary_magic_bin_start

    .global _binary_magic_bin_end
    .type _binary_magic_bin_end, @object
    .set _binary_magic_bin_end, _binary_magic_bin_start + _binary_magic_bin_size
    ; an alternate  way to include the size    
    .global _binary_magic_bin_len
    .type _binary_magic_bin_len, @object
    .size _binary_magic_bin_len, 8
_binary_magic_bin_len:
    .quad _binary_magic_bin_size

xxd

Una alternativa más portátil que no requiere GNU objcopy ni GNU como es crear un archivo C intermedio y compilarlo y vincularlo. Por ejemplo con xxd:

$ xxd -i magic.bin | sed 's/\(unsigned\)/const \1/' > magic.c
$ gcc -c magic.c
$ nm magic.o
0000000000000000 R magic_bin
0000000000000008 R magic_bin_len
$ cat magic.c
const unsigned char magic_bin[] = {
  0x32, 0x33, 0x34, 0x32, 0x0a
};
const unsigned int magic_bin_len = 5;

Linux
  1. ¿Orden de redirecciones?

  2. Linux – ¿Todo es un archivo?

  3. ¿Ordenar parte de un archivo?

  4. Ejecutar un archivo binario plano bajo Linux

  5. a.out reemplazado por el formato de archivo ELF?

Editor VIM

Herramienta para modificar la sección dinámica de un binario ELF

glibc:archivo elf OS ABI inválido

¿Escribir en un archivo .txt?

¿Cuál es la diferencia de sección y segmento en formato de archivo ELF?

cp -L frente a cp -H