For the answer below, I am 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 for gcc to pass -N or (aka --omagic ) to the linker, i.e. gcc ... -Wl,--omagic ... , although this may have other undesirable results (for example, disabling shared libraries). On 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 us give a go:
$ gcc --static -g -Wl,--omagic -o test test.c $ ./test Hello world $
This works great, but you have lost support for the dynamic library.
In order to maintain a dynamic library and keep the text segment writable, you should be able to use:
objcopy --writable-text ...
On the man page:
This should work, but not in the way objdump checks. So here is a solution that is slightly larger than --writable-text , which, as pointed out in the comments on the OP, does not seem to do what it says on the tin's Wanpage page.
See how 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 get rid of this 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 gone, as required.
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 problem is that something other than the ELF section name makes the section read-only on actual boot. This is probably why people suggest using mprotect . Sorry for not helping anymore.