GNU/Linux >> Tutoriels Linux >  >> Linux

En-têtes de fichiers ELF

Je ne connais pas les commandes de script de l'éditeur de liens qui peuvent le faire, mais vous pouvez le faire après le lien en utilisant le objcopy commande. La section --add-section L'option peut être utilisée pour ajouter une section contenant des données arbitraires au fichier ELF. Si l'en-tête ELF ne contient pas les champs souhaités, créez simplement une nouvelle section et ajoutez-les ici.


Ce lien (binaire teensy elf) était la réponse de quelqu'un à une autre question, mais il aborde en détail les subtilités d'un en-tête ELF.


Vous pouvez créer un fichier objet avec des champs informatifs comme un numéro de version et lier ce fichier de sorte qu'ils soient inclus dans le binaire ELF résultant.

Identifier

Par exemple, dans le cadre de votre processus de construction, vous pouvez générer - disons - info.c qui contient un ou plusieurs #ident instructions :

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

Compilez-le :

$ gcc -c info.c

Vérifiez si les informations sont incluses :

$ 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)

Alternativement, vous pouvez utiliser objdump -s --section .comment info.o . Notez que GCC écrit également son propre commentaire, par défaut.

Vérifiez les informations après avoir lié un exécutable 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

Section des commentaires

Utilisation de #ident dans une unité de traduction C est fondamentalement équivalent à créer un .comment section dans un fichier assembleur. Exemple :

$ 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

L'utilisation d'un nom de section inhabituel fonctionne également (par exemple, .section .blahblah ). Mais .comment est utilisé et compris par d'autres outils. GNU comprend également le .ident directive, et c'est ce que GCC traduit #ident à.

Avec symboles

Pour les données auxquelles vous souhaitez également accéder à partir de l'exécutable ELF lui-même, vous devez créer des symboles.

Objcopy

Supposons que vous souhaitiez inclure des octets magiques stockés dans un fichier de données :

$ cat magic.bin 
2342

Convertir en fichier objet avec GNU objcopy :

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

Vérifiez les symboles :

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

Exemple d'utilisation :

#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;
}

Reliez le tout :

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

Ld GNU

GNU ld est également capable de transformer des fichiers de données en fichiers objets en utilisant un schéma de nommage compatible avec objcopy :

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

Contrairement à objcopy, il place les symboles dans le .data au lieu du .rodata cependant (cf. objdump -h magic.o ).

incbin

Dans le cas où GNU objcopy n'est pas disponible, on peut utiliser le GNU comme .incbin directive pour créer le fichier objet (assembler avec 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

xxj

Une alternative plus portable qui ne nécessite pas GNU objcopy ni GNU comme c'est le cas pour créer un fichier C intermédiaire et le compiler et le lier. Par exemple avec 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. Linux - Tout est un fichier ?

  2. Exécuter un fichier binaire plat sous Linux

  3. C ouvert vs ouvert

  4. Comment extraire uniquement le contenu brut d'une section ELF ?

  5. Quelle est la différence entre la section et le segment au format de fichier ELF

Éditeur VIM

Outil pour modifier la section dynamique d'un binaire ELF

Lecture d'un fichier en assembleur

glibc :fichier elf OS ABI invalide

Écrire dans le fichier .txt ?

un programme peut-il lire sa propre section elf ?