2012-01-09 110 views
7

我希望能够动态更改我正在使用的库内的可执行代码。从本质上讲,如果不需要,我想动态地NOP出某些功能。如何让GCC编译.text段作为ELF二进制文件可写?

不过,我现在用的是图书馆的.text段是不写的(这是大多数程序的情况下)。我有库的源代码,所以想使用GCC将其编译为可写。

有没有办法做到这一点?

+0

什么是这样做的实际原因GCC来链接? – cateof 2012-01-09 21:43:24

回答

1

也许最好的方法是使用系统特定的API来改变你要修改的内存可写,修改,再改回来。

在Unix家族系统,你会想看看mprotect。请记住,它处理的是您系统的页面大小的倍数的块。可能是4096,所以可能需要四舍五入。

+0

那么我正在使用Genode操作系统,并试图重写动态链接器的map_object()函数。 mprotect()是否适用于程序的加载阶段? – samoz 2012-01-09 20:39:07

5

尝试objcopy --writable-text在编译库,按照它应该的.text写的文档。

+1

这是一个问题或答案? – 2012-01-09 22:38:23

7

从一般意义上说,mprotect是在sys/mman.h(检查http://linux.die.net/man/2/mprotect)下的推荐选择(在符合POSIX的系统上)。只需获取进程的可执行部分的地址和系统页数,然后致电mprotect以请求权限;写信给它;然后再次拨打mprotect以释放写入权限。

然而,如果这意味着要在低级别的程序,其中速度是绝对重要的(或mprotect不可用),那么你会希望其.text部分写编译库作为主叫mprotect最有可能的问题翻译后备缓冲区(TLB)刷新(特别是在多处理器环境中)可能并会造成瓶颈。如果特定的系统是通过分页使用硬件保护(其中几乎所有的现在),然后改变其保护的唯一方法是做一个TLB冲洗,必须每个被引用页面上执行,引用页表(一组页),引用页面目录(一组页表)和每个处理器。最重要的是,这必须在环0中执行,这需要一个系统调用,它只是将顶部的樱桃放在顶部。

在后一种情况下,最简单的解决方案将是正常编译库,然后用--writable-textobjcopy它(如通过ggiroux提到的)。

另一个解决办法是自己定义的链接映射文件linker.ld。然后您可以明确指定任何部分的权限。它不太复杂;如果系统依赖。请参阅文档http://www.math.utah.edu/docs/info/ld_3.html。你也可以看看你的系统提供的linker.ld文件并从那里修改它。传递-Wl,--verbose到GCC将指示链接吐出所有相关文件(包括其默认linker.ld),其中你可以再修改.text段的权限,并重新编译库(永远)使用新的linker.ld文件。

总之,我的建议是做的最后一段的状态和带稍微修改链接脚本编译库。

2

,我发现(binutils的2.22),最简单的方法是-N 这可以是传球用gcc-XN

相关问题