Wie kann ich GCC dazu bringen, den .text-Abschnitt in einer ELF-Binärdatei als beschreibbar zu kompilieren?

Lesezeit: 3 Minuten

Ich möchte in der Lage sein, den ausführbaren Code innerhalb einer von mir verwendeten Bibliothek dynamisch zu ändern. Im Wesentlichen möchte ich bestimmte Funktionen dynamisch NOPen, wenn sie nicht benötigt werden.

Der .text-Abschnitt der von mir verwendeten Bibliothek ist jedoch nicht beschreibbar (wie es bei den meisten Programmen der Fall ist). Ich habe den Quellcode der Bibliothek und möchte ihn daher mit GCC als beschreibbar kompilieren.

Gibt es eine Möglichkeit, dies zu tun?

  • Was ist der praktische Grund dafür?

    – Kategorie

    9. Januar 12 um 21:43 Uhr

Im allgemeinen Sinne, mprotect ist die bevorzugte Wahl (auf POSIX-konformen Systemen) unter sys/mman.h (überprüfen http://linux.die.net/man/2/mprotect). Holen Sie sich einfach die Adresse und die Anzahl der Systemseiten des ausführbaren Abschnitts Ihres Prozesses und rufen Sie ihn auf mprotect um Berechtigungen anzufordern; schreibe ihm; Dann ruf an mprotect erneut, um die Schreibberechtigung freizugeben.

Wenn dies jedoch für Low-Level-Routinen gedacht ist, bei denen Geschwindigkeit von absoluter Bedeutung ist (bzw mprotect ist nicht verfügbar), dann möchten Sie die Bibliothek mit ihrer kompilieren .text Abschnitt beschreibbar als Aufruf mprotect höchstwahrscheinlich wird ein TLB-Flush (Translation Lookaside Buffer) ausgegeben, der (insbesondere in einer Umgebung mit mehreren Prozessoren) einen Engpass verursachen kann und wird. Wenn das spezifische System Hardwareschutz über Paging verwendet (was jetzt fast alle sind), besteht die einzige Möglichkeit, den Schutz zu ändern, darin, einen TLB-Flush durchzuführen, der auf jeder referenzierten Seite, referenzierten Seitentabelle (Gruppe von Seiten) ausgeführt werden muss Seitenverzeichnis (Gruppe von Seitentabellen) und jedem Prozessor. Um das Ganze abzurunden, muss dies in Ring 0 ausgeführt werden, was einen Syscall erfordert, der nur das Sahnehäubchen auf den Overhead setzt.

Im letzteren Fall wäre die einfachste Lösung, die Bibliothek normal und dann zu kompilieren objcopy es mit --writable-text (wie von ggiroux erwähnt).

Eine andere Lösung wäre, die Linker-Map-Datei zu definieren linker.ld du selber. Dann können Sie Berechtigungen für jeden Abschnitt explizit angeben. Es ist nicht zu kompliziert; falls systemabhängig. Siehe Dokumentation unter http://www.math.utah.edu/docs/info/ld_3.html. Sie können sich auch Ihr bereitgestelltes System ansehen linker.ld Datei und ändere sie von dort aus. Vorbeigehen -Wl,--verbose to gcc weist den Linker an, alle relevanten Dateien (einschließlich seiner Standarddatei linker.ld) auszuspucken, in denen Sie dann die Berechtigungen des .text-Abschnitts ändern und die Bibliothek (für immer) mit der neuen neu kompilieren können linker.ld Datei.

Zusammenfassend würde ich empfehlen, wie im letzten Absatz beschrieben vorzugehen und Ihre Bibliothek mit einem leicht modifizierten Linker-Skript zu kompilieren.

Wie kann ich GCC dazu bringen den text Abschnitt in einer
ggiroux

Versuchen objcopy --writable-text in der kompilierten Bibliothek, laut Dokumentation sollte es .text beschreibbar machen.

Der einfachste Weg, den ich gefunden habe (binutils 2.22), besteht darin, mit -N zu verknüpfen. Das kann mit gcc -XN an gcc übergeben werden

  • Die Langform dieser Optionen ist --omagic. Und ja, es macht .text lesbar + schreibbar, wie .data.

    – Peter Cordes

    3. April 20 um 14:43 Uhr

Der wahrscheinlich beste Ansatz besteht darin, die systemspezifische API zu verwenden, um die Beschreibbarkeit des Speichers zu ändern, den Sie ändern möchten, ihn zu ändern und ihn dann zurück zu ändern.

Auf Systemen der Unix-Familie möchten Sie sich das ansehen mprotect. Denken Sie nur daran, dass es sich um Blöcke handelt, die ein Vielfaches von sind Seitengröße Ihres Systems. Wahrscheinlich 4096, daher ist wahrscheinlich eine Rundung erforderlich.

.

675900cookie-checkWie kann ich GCC dazu bringen, den .text-Abschnitt in einer ELF-Binärdatei als beschreibbar zu kompilieren?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy