Make text segment writable, ELF [duplicate]

时间秒杀一切 提交于 2019-12-07 03:07:53

问题


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.


回答1:


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.



来源:https://stackoverflow.com/questions/27581279/make-text-segment-writable-elf

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!