如何使GCC编译.text节在ELF二进制文件中是可写的? [英] How can I make GCC compile the .text section as writable in an ELF binary?

查看:233
本文介绍了如何使GCC编译.text节在ELF二进制文件中是可写的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想能够动态更改我正在使用的库中的可执行代码。基本上,我想动态NOP某些功能,如果他们不需要。

I would like to be able to dynamically change the executable code within a library I am using. Essentially, I would like to dynamically NOP out certain functions if they are not needed.

但是,我使用的库的.text部分是不可写的(大多数程序都是这样)。我有库的源代码,因此希望使用GCC将其编译为可写。

However, the .text section of the library I am using is not-writable (as is the case for most programs). I have the source code of the library and so would like to use GCC to compile it as writable.

有办法吗?

推荐答案

一般意义上, mprotect sys / mman.h 下的选择(在POSIX符合系统上) href =http://linux.die.net/man/2/mprotect> http://linux.die.net/man/2/mprotect )。只需获取进程可执行部分的地址和系统页计数,并调用 mprotect 即可申请权限;写到它;然后,再次调用 mprotect 以释放写入权限。

In the general sense, mprotect is the perferred choice (on POSIX conforming systems) under sys/mman.h (check http://linux.die.net/man/2/mprotect). Simply get the address and system page count of the executable section of your process and call mprotect to request permission permissions; write to it; then, call mprotect again to release write permission.

但是,如果这意味着是低级如果速度是绝对重要的(或者 mprotect 不可用),那么你需要使用 .text section可写为调用 mprotect 很可能发生翻译后备缓冲区(TLB)刷新(特别是在多处理器环境中)可能并将导致瓶颈。如果特定系统通过分页使用硬件保护(几乎所有现在都是),则改变保护的唯一方式是通过进行必须在每个被引用页面(被引用的页表(页组))上执行的TLB刷新,引用页目录(页表组)和每个处理器。为了使它更好,这必须在环0中执行,这需要一个系统调用,只是把樱桃顶上的开销。

However, if this is meant to be on low-level routines where speed is of absolute importance (or mprotect is not available) then you'll want to compile the library with its .text section writable as calling mprotect most likely issues a Translation Lookaside Buffer (TLB) flush that (especially in a multi-processor environment) can and will cause a bottleneck. If the specific system is using hardware protection via paging (which nearly all are now) then the only way to change the protection is by doing a TLB flush which must be executed on every referenced page, referenced page table (group of pages), referenced page directory (group of page tables) and every processor. To top it off, this must be executed in ring 0 which requires a syscall which just puts the cherry on top for overhead.

在后一种情况下,最简单的解决方案是通常的编译库,然后 objcopy 它与 - 可写文本(由ggiroux提到)。

In the latter case, the easiest solution would be to compile the library normally and then objcopy it with --writable-text (as mentioned by ggiroux).

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

Another solution would be to define the linker map file linker.ld yourself. Then you may specify permissions of any section explicitly. Its not too complicated; if system-dependent. Refer to documentation at http://www.math.utah.edu/docs/info/ld_3.html. You could also look at your system provided linker.ld file and modify it from there. Passing -Wl,--verbose to gcc will instruct the linker to spit out all relevant files (including its default linker.ld) in which you could then modify the permissions of the .text section and recompile the library (forevermore) using the new linker.ld file.

建议是最后一个段落,并用稍微修改的链接描述文件来编译你的库。

To summarize, my recommendation would be to do as the last paragraph states and compile your library with a slightly modified linker script.

这篇关于如何使GCC编译.text节在ELF二进制文件中是可写的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆