我需要使可执行ELF的.text段可写。 我需要修改的程序是用C编写的,我可以编译它。有任何想法吗?
非常感谢。
答案 0 :(得分:9)
对于下面的答案,我将使用此测试程序:
#include <stdio.h>
#include <stdlib.h>
int
main (int argc, char **argv)
{
printf ("Hello world\n");
void *m = main;
*((char *) m) = 0;
exit (0);
}
编译:
$ gcc -g -o test test.c
正如所料:
$ 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)
这里显而易见的路线是使用-Wl
标记gcc
将-N
或(又名--omagic
)传递给链接器,即gcc ... -Wl,--omagic ...
,虽然这可能有其他不良结果(例如禁用共享库)。从手册页:
-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.
让我们一起去:
$ gcc --static -g -Wl,--omagic -o test test.c
$ ./test
Hello world
$
这很好,但是你失去了动态库支持。
为了保持动态库支持并保留可写文本段,您应该能够使用:
objcopy --writable-text ...
从手册页:
--writable-text
Mark the output text as writable. This option isn't meaningful for all object file
formats.
这应该有效,但不会,因为objdump
会验证。所以这里有一个比--writable-text
更进一步的解决方案,正如OP在评论中所说的那样,似乎没有按照它在tin ^ Wmanpage上所说的那样做。
让我们看看这些部分是如何标记的:
$ gcc -g -o test test.
$ objdump -h test | fgrep -A1 .text
12 .text 00000192 0000000000400490 0000000000400490 00000490 2**4
CONTENTS, ALLOC, LOAD, READONLY, CODE
现在让我们摆脱那个READONLY
标志:
$ 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
现在READONLY
已根据要求消失了。
可是:
$ 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)
我怀疑这里的问题是除了ELF部分名称之外的其他内容在实际加载时使该部分为只读。这可能是人们建议您使用mprotect
的原因。很抱歉没有得到更多的帮助。