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