2014-12-20 16 views
5

Ich muss .TEXT Segment einer ausführbaren ELF schreibbar machen. Das Programm, das ich ändern muss, ist in C geschrieben und ich kann es kompilieren. Irgendwelche Ideen?Machen Sie Textsegment beschreibbar, ELF

Vielen Dank.

+0

Nicht klar genug. .text ist in der Regel Code. Wo ist deine Software/Firmware? – LPs

+0

Vielleicht ist es ein Duplikat, aber in der anderen Frage haben sie Lösungen geteilt, die nicht funktionieren. – Cronovirus

+1

Ja, ich muss den Code zur Laufzeit ändern, so dass der Textabschnitt beschreibbar sein muss. – Cronovirus

Antwort

8

Für die Antwort unten, ich werde dieses Testprogramm verwenden:

#include <stdio.h> 
#include <stdlib.h> 

int 
main (int argc, char **argv) 
{ 
    printf ("Hello world\n"); 
    void *m = main; 
    *((char *) m) = 0; 
    exit (0); 
} 

Compile mit:

$ gcc -g -o test test.c 

Wie erwartet:

$ gdb test 
... 
(gdb) run 
Starting program: /home/amb/so/test 
Hello world 

Program received signal SIGSEGV, Segmentation fault. 
0x00000000004005a2 in main (argc=1, argv=0x7fffffffe628) at test.c:9 
9  *((char *)m) = 0; 
(gdb) 

Offensichtliche Strecke hier ist es, die -Wl Flagge zu gcc-N oder (aka) zu übergeben) an den Linker, d.h. gcc ... -Wl,--omagic ..., obwohl dies andere unerwünschte Ergebnisse (z.B. Shared Libraries deaktivieren). Aus der Manpage:

-N 
    --omagic 
     Set the text and data sections to be readable and writable. Also, do not page-align the 
     data segment, and disable linking against shared libraries. If the output format 
     supports Unix style magic numbers, mark the output as "OMAGIC". Note: Although a 
     writable text section is allowed for PE-COFF targets, it does not conform to the format 
     specification published by Microsoft. 

ist, dass ein Go geben lassen:

$ gcc --static -g -Wl,--omagic -o test test.c 
$ ./test 
Hello world 
$ 

Das funktioniert gut, aber Sie haben dynamische Bibliothek Unterstützung verloren.

dynamische Bibliothek Unterstützung halten, und eine beschreibbare Textsegment erhalten, sollten Sie verwenden können:

objcopy --writable-text ... 

Aus der Manpage:

--writable-text 
     Mark the output text as writable. This option isn't meaningful for all object file 
     formats. 

Dies sollte arbeiten, aber doesn t, wie objdump wird verifizieren. Also hier ist eine Lösung, die ein bisschen weiter geht als --writable-text, die als OP in den Kommentaren angegeben hat scheint nicht zu tun, was es auf der Zinn^Wmanpage sagt.

Mal sehen, wie die Abschnitte gekennzeichnet sind:

$ gcc -g -o test test. 
$ objdump -h test | fgrep -A1 .text 
    12 .text   00000192 0000000000400490 0000000000400490 00000490 2**4 
        CONTENTS, ALLOC, LOAD, READONLY, CODE 

Nun wollen wir dieses READONLY Flagge loszuwerden:

$ objcopy --set-section-flags .text=contents,alloc,load,code test test1 
$ objdump -h test1 | fgrep -A1 .text 
12 .text   00000192 0000000000400490 0000000000400490 00000490 2**4 
        CONTENTS, ALLOC, LOAD, CODE 

und jetzt READONLY gegangen ist, wie gewünscht.

Aber:

$ gdb test1 
... 
(gdb) run 
Starting program: /home/amb/so/test1 
Hello world 

Program received signal SIGSEGV, Segmentation fault. 
0x00000000004005a2 in main (argc=1, argv=0x7fffffffe628) at test.c:9 
9  *((char *)m) = 0; 
(gdb) 

Ich vermute, das hier Problem ist, dass etwas anderes als die ELF Abschnittsnamen machen den Abschnitt schreibgeschützt, wenn tatsächlich geladen. Das ist wahrscheinlich der Grund, warum Leute vorschlagen, dass Sie mprotect verwenden. Tut mir leid, dass ich nicht mehr Hilfe war.

+0

Danke für Ihre Antwort zuerst. Aber objcopy funktioniert nicht und die Option -XN wird von meinem gcc nicht erkannt. – Cronovirus

+0

@Cronovirus - naja, die zuverlässige Methode (offensichtlich nicht zur Verbindungszeit verfügbar) wäre, den Speicherschutz mit 'mprotect' zu ändern. Wenn Sie die Quelle nicht ändern können, verwenden Sie "LD_PRELOAD", um dies zu erreichen. – abligh

+0

Danke, ich kenne mprotect, aber ich suchte zuerst nach einer statischen Lösung. – Cronovirus