2017-02-04 3 views
2

Pour une raison particulière, j'ai besoin de placer la section .text à la fin de mon fichier ELF.Placez la section .text à la toute fin de ELF

J'ai essayé d'y parvenir ainsi:

Je pris par défaut grand script linker et déplacé .text section à la fin de SECTIONS { ... } partie.

$ readelf -S beronew 

[ #] Name    Type   Address   Offset 
    Size    Size.Ent   Flags  -  - Alignment 
[ 0]     NULL    0000000000000000 00000000 
    0000000000000000 0000000000000000   0  0  0 
[ 1] .data    PROGBITS   00000000006000b0 000000b0 
    000000000000003b 0000000000000000 WA  0  0  1 
[ 2] .text    PROGBITS   0000000000a000f0 000000f0 
    00000000000003e9 0000000000000000 AX  0  0  1 
[ 3] .shstrtab   STRTAB   0000000000000000 000004d9 
    0000000000000027 0000000000000000   0  0  1 
[ 4] .symtab   SYMTAB   0000000000000000 00000680 
    0000000000000438 0000000000000018   5 41  8 
[ 5] .strtab   STRTAB   0000000000000000 00000ab8 
    0000000000000258 0000000000000000   0  0  1 

Ce que je vois est que ld ajouté des sections supplémentaires après ma section "fin". Pour les remplacer, j'ai utilisé l'option linker -nostdlib -s (pour ne pas utiliser stdlib (juste au cas où) et omettre toutes les informations sur les symboles).

Run $ readelf -S beronew une fois de plus:

[ #] Name    Type   Address   Offset 
    Size    Size.Ent   Flags  -  - Alignment 
[ 0]     NULL    0000000000000000 00000000 
    0000000000000000 0000000000000000   0  0  0 
[ 1] .data    PROGBITS   00000000006000b0 000000b0 
    000000000000003b 0000000000000000 WA  0  0  1 
[ 2] .text    PROGBITS   0000000000a000f0 000000f0 
    00000000000003e9 0000000000000000 AX  0  0  1 
[ 3] .shstrtab   STRTAB   0000000000000000 000004d9 
    0000000000000017 0000000000000000   0  0  1 

Section table chaîne d'en-tête est toujours là. J'ai essayé $strip -R .shstrtab beronew. Cela n'a eu aucun effet, la section est toujours là.

Cette section n'a que 0x17 octets de long mais je n'ai pas pu atteindre mon objectif. Puis j'ai regardé hexdump de mon fichier:

$ hexdump beronew 

... 
00004d0 0060 c748 bfc6 6000 0000 732e 7368 7274 
00004e0 6174 0062 642e 7461 0061 742e 7865 0074 
00004f0 0000 0000 0000 0000 0000 0000 0000 0000 
* 
0000530 000b 0000 0001 0000 0003 0000 0000 0000 
0000540 00b0 0060 0000 0000 00b0 0000 0000 0000 
0000550 003b 0000 0000 0000 0000 0000 0000 0000 
... 

Ce que je vois est qu'il existe un autre code après la partie sections. Selon la structure ELF, il est Section header table à la fin du fichier. Donc, même si je supprime en quelque sorte la section .shstrtab, il y aura toujours cet en-tête à la fin.

Donc, ma question est comment puis-je placer ma section .text en toute fin de fichier? Je n'ai pas vraiment besoin d'enlever toutes les sections et en-têtes donc si vous connaissez un (meilleur) moyen d'y parvenir, il sera très apprécié.

.

.

P.S. Pour ceux qui se demandent pourquoi ai-je besoin de ceci:

Ce fichier ELF (beronew) contient la bibliothèque rutime. Il sera utilisé comme "en-tête" pour un autre fichier qui génère des instructions asm avec une certaine logique sous forme d'opcode. Cet opcode sera ajouté à la fin de beronew. Ensuite, je vais coller le champ sh_size dans l'en-tête de la section .text pour pouvoir exécuter mon 'code' récemment ajouté.

(Une autre question: section Est-ce tout ce que je besoin de patcher en cas « texte » est le dernier dans le fichier?)

P.P.S. Je sais que c'est une mauvaise architecture mais c'est mon projet de cours - porter une application qui a été construite de cette façon dans Win32 à Linux64, et maintenant je suis coincé au point où je fusionne la bibliothèque d'exécution "en-tête" et "logique" partie parce que je ne peux pas placer la section .text à la fin de ELF.

Merci encore une fois!

.

UPD:

Basé sur le commentaire de fuz j'ai essayé d'ajouter PHDRS au script simple éditeur de liens comme ceci:

PHDRS 
{ 
    headers PT_PHDR PHDRS ; 
    data PT_LOAD ; 
    bss PT_LOAD ; 
    text PT_LOAD ; 
} 

SECTIONS 
{ 
    . = 0x200000; 
    .data : { *(.data) *(COMMON) } :data 
    .bss : { *(.bss) } :bss 
    .text : { *(.text) } :text 
} 

mais il ne semble pas fonctionner maintenant.

+2

Notez que le chargeur ne se soucie pas des sections, il se soucie uniquement des en-têtes de programme, donc le patch 'sh_size' est inefficace. Peut-être serait-il plus facile d'ajouter un en-tête de programme supplémentaire (vide) pour votre programme? – fuz

+0

@fuz Peut-être que je ne vous ai pas compris, voulez-vous dire que je devrais patcher l'en-tête du programme (je ne vois pas d'utilité pour moi ou les champs liés à la section) au lieu de l'en-tête de section? ou ajouter un en-tête de programme supplémentaire (n'avez jamais entendu parler des en-têtes 2)? –

+1

Un binaire ELF contient un certain nombre d'en-têtes de programme qui indiquent au chargeur de programme (dans le noyau) où charger quelles parties du binaire. C'est à peu près la seule partie sur laquelle le chargeur se soucie, il ignore tous les autres en-têtes. Si vous voulez ajouter des éléments supplémentaires à un binaire ELF, vous pouvez le faire facilement en manipulant uniquement les en-têtes du programme. Voir [ici] (https://sourceware.org/binutils/docs/ld/PHDRS.html#PHDRS) pour savoir comment faire. – fuz

Répondre

0

Pour quelqu'un qui me demande comment, après tout ce que j'ai réussi à obtenir ce travail il y a une réponse:

  1. J'ai fait un script linker qui a placé la section de texte après la section de données (here is the script). Mais il y avait quelques sections de débogage à la fin du fichier comme la section Shstrtab et ainsi de suite (photo ci-dessous). J'ai donc converti ce fichier octet par octet en chaîne.

  2. Après cela, je reçu un elfe sur une image ci-dessous elf structure

dans une chaîne de-octets sous forme. Ensuite, je viens de lire quelques en-têtes et j'ai découvert où la section de code se termine (juste avant la section Shstrtab), donc je pourrais diviser cette chaîne en 2 morceaux. Le premier contenait des données pour le chargeur. Deuxième - pour l'éditeur de liens.

  1. J'ai converti mon code 'extra' en forme de opcode qui est aussi un tableau (string) d'octets et concaténé à la section .text originale. Ensuite, j'ai concaténé la partie finale. J'ai donc un seul fichier avec mon code supplémentaire.

  2. Pour obtenir ce travail que j'ai édité les valeurs de la photo ci-dessous:

enter image description here

La première colonne est un nom de domaine qui doit être modifié (il correspond à l'image de la structure elfe).

La deuxième colonne est un décalage entre le début du fichier et le début du champ. Laissez la fonction s(xxx) être la size_of(some_header_structure) et injSize soit la taille de mon code supplémentaire injecté. Et des valeurs comme 0x18, 0x20, 0x28 sont les offsets de champs à l'intérieur de leurs structures (section_headers, program_headers, elf_headers).

Le troisième représente la valeur qui doit remplacer celle d'origine.

* Notez que elf est représenté et ELF64 donc les largeurs de certains champs diffèrent de celles d'ELF32.

Après avoir fait tout cela, j'ai réussi à exécuter ce nouveau fichier Elf et cela a fonctionné parfaitement! Peut-être (à coup sûr) ce n'est pas la meilleure solution mais ça marche et c'était un bon métrique pour mon travail de recherche.