2017-02-04 12 views
2

Aus einem bestimmten Grund muss ich .text Abschnitt am Ende meiner ELF-Datei platzieren.Platziere Textbereich ganz am Ende von ELF

Ich habe versucht, dies auf diese Weise zu erreichen:

Ich habe großen Linker-Skript Standard und bewegte .text Abschnitt bis zum Ende des SECTIONS { ... } Teils.

$ 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 

Was ich sehe, ist, dass ld zusätzliche Abschnitte nach meiner „Endung“ hinzugefügt. Um sie zu ersetzen, habe ich -nostdlib -s Linker-Option verwendet (um nicht stdlib (nur für den Fall) zu verwenden und alle Symbolinformationen wegzulassen).

Run $ readelf -S beronew ein weiteres Mal: ​​

[ #] 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 Header String-Tabelle ist immer noch da. Ich habe versucht $strip -R .shstrtab beronew. Es hatte keine Wirkung, Sektion ist immer noch da.

Dieser Abschnitt ist nur 0x17 Bytes lang, aber ich konnte mein Ziel nicht erreichen. Dann schaute ich auf hexdump meiner Datei:

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

Was ich sehe, ist, dass es einen anderen Code ist nach Abschnitten Teil. Laut ELF-Struktur ist es Section header table am Ende der Datei. Also selbst wenn ich irgendwie .shstrtab Abschnitt entferne, wird es immer noch diesen Header am Ende sein.

Also meine Frage ist Wie kann ich meine .text Abschnitt am Ende der Datei platzieren? Ich muss nicht wirklich alle Abschnitte und Header entfernen. Wenn Sie also einen (besseren) Weg kennen, wird dies sehr geschätzt.

.

.

P.S. Für diejenigen, die sich fragen, warum brauche ich das:

Diese ELF-Datei (beronew) enthält Rutime Bibliothek. Es wird als "Header" für eine andere Datei verwendet, die asm-Anweisungen mit einer gewissen Logik in Opcode-Form generiert. Dieser Opcode wird bis zum Ende von beronew hinzugefügt. Dann werde ich sh_size Feld in .text Abschnitt Kopfzeile Patch, um in der Lage zu sein, meinen kürzlich hinzugefügten "Code" ausführen.

(Noch eine Frage: Ist das alles, was ich brauche, um Patch für den Fall ‚Text‘ Abschnitt ist der letzte in der Datei?)

P.P.S. Ich weiß, dass dies eine schlechte Architektur ist, aber es ist mein Kurs-Projekt - Portieren einer App, die auf diese Weise in Win32 zu Linux64 erstellt wurde, und jetzt bin ich an dem Punkt fest, wo ich Laufzeitbibliothek "Header" -Datei und "Logik" zusammenführen Teil, weil ich .text Abschnitt am Ende von ELF nicht platzieren kann.

Noch einmal danke!

.

UPD:

Basierend auf fuz Kommentar habe ich versucht, PHDRS einfache Linker-Skript, da dies hinzuzufügen:

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 
} 

aber es scheint nicht, jetzt zu arbeiten.

+2

Beachten Sie, dass der Loader sich nicht um Sektionen kümmert, sondern nur um Programmheader, daher ist das Patchen von 'sh_size' unwirksam. Vielleicht wäre es einfacher, einen zusätzlichen (leeren) Programm-Header für Ihr Programm hinzuzufügen, um es zu patchen? – fuz

+0

@fuz Vielleicht habe ich dich nicht richtig verstanden, meinst du ich sollte Programmheader patch (ich sehe keine nützliche für mich oder abschnittsbezogene Felder dort) anstelle von Abschnitt Header? oder einen zusätzlichen Programmheader hinzufügen (habe noch nie von den zweiten Headern gehört)? –

+1

Eine ELF-Binärdatei enthält eine Reihe von Programmheadern, die dem Programmlader (im Kernel) mitteilen, wo welche Teile der Binärdatei geladen werden sollen. Das ist der einzige Teil, um den sich der Lader kümmert, er ignoriert alle anderen Header. Wenn Sie einer ELF-Binärdatei zusätzliche Daten hinzufügen möchten, können Sie dies einfach tun, indem Sie nur die Programmheader bearbeiten. Sehen Sie [hier] (https://sourceware.org/binutils/docs/ld/PHDRS.html#PHDRS), wie Sie das tun. – fuz

Antwort

0

Für jemanden, der sich fragen, wie nach allem dort ich habe es geschafft, diese Funktion zu erhalten, ist eine Antwort:

  1. ich ein Linker-Skript gemacht haben, dass Textabschnitt nach dem Datenabschnitt platziert (here is the script). Aber es gab einige Debugging-Abschnitte am Ende der Datei wie Shstrtab Abschnitt und so weiter (Bild unten). Also habe ich diese Datei Byte für Byte in eine Zeichenfolge umgewandelt.

  2. Danach bekam ich eine Elf auf einem Bild unter elf structure

in einer String-of-Bytes Form. Dann habe ich nur einige Header gelesen und herausgefunden, wo der Codeabschnitt endet (direkt vor dem Shstrtab-Abschnitt), sodass ich diese Zeichenfolge in zwei Teile aufteilen kann. Die erste enthielt Daten für den Lader. Zweite - für Linker.

  1. Dann habe ich meinen 'Extra' Code in Opcode Form umgewandelt, die auch ein Array (string) von Bytes und verkettet sie auf den ursprünglichen .text Abschnitt. Als nächstes habe ich den Endteil damit verkettet. Also habe ich eine einzige Datei mit meinem extra Code drin.

  2. diese Funktion zu erhalten I-Werte aus dem Bild unten bearbeitet haben:

enter image description here

erste Spalte ist ein Name des Feldes, das bearbeitet werden muss (es entspricht Bild von elf Struktur).

Die zweite Spalte ist ein Offset vom Anfang der Datei zum Anfang des Feldes. Lass die Funktion s(xxx) die size_of(some_header_structure) und injSize die Größe meines eingespritzten Zusatzcodes sein. Und Werte wie 0x18, 0x20, 0x28 sind die Offsets von Feldern innerhalb ihrer Strukturen (section_headers, program_headers, elf_headers).

Der dritte Wert gibt den Wert an, der den ursprünglichen Wert ersetzen sollte.

* Beachten Sie, dass Elf und ELF64 dargestellt sind, so dass sich die Breiten einiger Felder von denen von ELF32 unterscheiden.

Nachdem ich all das gemacht habe, habe ich es geschafft, diese neue Elf-Datei zu starten und es hat perfekt funktioniert! Vielleicht (sicher) ist es nicht die beste Lösung, aber es funktioniert und es war ein schönes Material für meine Forschungsarbeit.