我希望能够动态更改我正在使用的库中的可执行代码。本质上,我想动态地 NOP 掉某些不需要的函数。
但是,我正在使用的库的 .text 部分是不可写的(大多数程序都是如此)。我有该库的源代码,因此想使用 GCC 将其编译为可写。
有没有办法做到这一点?
从一般意义上来说,mprotect
是首选(在符合 POSIX 的系统上)sys/mman.h
(check http://linux.die.net/man/2/mprotect http://linux.die.net/man/2/mprotect)。只需获取进程可执行部分的地址和系统页数并调用mprotect
请求许可权限;写信给它;然后,打电话mprotect
再次释放写权限。
然而,如果这意味着速度是绝对重要的低级例程(或mprotect
不可用)那么你需要用它的编译库.text
调用时可写的部分mprotect
最有可能的问题是转换后备缓冲区 (TLB) 刷新(特别是在多处理器环境中)可能并且将会导致瓶颈。如果特定系统通过分页使用硬件保护(现在几乎都是这样),那么更改保护的唯一方法是执行 TLB 刷新,该刷新必须在每个引用的页、引用的页表(页组)、引用的页上执行。页目录(页表组)和每个处理器。最重要的是,这必须在环 0 中执行,这需要一个系统调用,该系统调用只是将樱桃放在顶部以增加开销。
在后一种情况下,最简单的解决方案是正常编译库,然后objcopy
它与--writable-text
(正如 ggiroux 所提到的)。
另一种解决方案是定义链接器映射文件linker.ld
你自己。然后您可以明确指定任何部分的权限。它不太复杂;如果依赖于系统。请参阅文档:http://www.math.utah.edu/docs/info/ld_3.html http://www.math.utah.edu/docs/info/ld_3.html。您还可以查看您提供的系统linker.ld
文件并从那里修改它。通过-Wl,--verbose
to gcc 将指示链接器吐出所有相关文件(包括其默认的 linker.ld),然后您可以在其中修改 .text 部分的权限并使用新的重新编译库(永远)linker.ld
file.
总而言之,我的建议是按照最后一段所述进行操作,并使用稍作修改的链接器脚本来编译您的库。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)