I need to make .text segment of an executable ELF writable. The program i need to modify is written in C and i can compile it. Any ideas?
Thanks A lot.
For the answer below, I'm going to use this test program:
#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 with:
$ gcc -g -o test test.c
As expected:
$ 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)
The obvious route here is to use the -Wl flag to gcc to pass -N or (aka --omagic) to the linker, i.e. gcc ... -Wl,--omagic ..., though this may have other undesirable results (e.g. disabling shared libraries). From the man page:
-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.
Let's give that a go:
$ gcc --static -g -Wl,--omagic -o test test.c
$ ./test
Hello world
$
That works fine, but you've lost dynamic library support.
To keep dynamic library support, and retain a writable text segment, you should be able to use:
objcopy --writable-text ...
From the man page:
--writable-text
Mark the output text as writable. This option isn't meaningful for all object file
formats.
This ought to work, but doesn't, as objdump will verify. So here's a solution that gets a bit further than --writable-text which as OP has stated in the comments does not appear to do what it says on the tin^Wmanpage.
Let's see how the sections are marked:
$ gcc -g -o test test.
$ objdump -h test | fgrep -A1 .text
12 .text 00000192 0000000000400490 0000000000400490 00000490 2**4
CONTENTS, ALLOC, LOAD, READONLY, CODE
Now let's get rid of that READONLY flag:
$ 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
and now READONLY has gone, as requested.
But:
$ 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)
I suspect the issue here is that something else other than the ELF section name is making the section read-only when actually loaded. Which is probably why people are suggesting you use mprotect. Sorry not to have been more help.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With