能否覆盖动态链接可执行文件非动态段中的符号?
覆盖动态链接ELF非动态段符号的问题解答
核心结论
LD_PRELOAD无法直接覆盖动态链接可执行文件非动态段(比如.text、.rodata)中的符号——这些段里的函数、数据是直接编译进可执行文件本身的,并非通过动态链接表引用的外部共享库符号,不在LD_PRELOAD的劫持范围内。
为什么LD_PRELOAD做不到?
根据LD_PRELOAD的官方定义:
LD_PRELOAD 是用户指定的额外ELF共享对象列表,会先于其他所有对象加载。该特性可用于选择性覆盖其他共享对象中的函数。
LD_PRELOAD的核心逻辑是劫持动态链接器对共享库符号的解析流程:当可执行文件调用外部共享库的函数时,动态链接器会优先从LD_PRELOAD指定的库中查找对应符号。但对于主程序.text段里直接编译的静态函数、硬编码数据,动态链接器根本不会触发外部符号解析,自然无法被劫持。
至于你看到Stack Overflow提到的“覆盖静态链接的函数”,实际指的是静态链接到共享库中的函数,而非主可执行文件自身.text段的静态函数。比如某个共享库内部的静态函数被其他共享库引用时,LD_PRELOAD可以通过符号劫持覆盖它,但主程序自带的静态函数不在此场景内。
可行的替代方案
如果要修改主可执行文件非动态段的符号,可使用以下工具:
- 二进制补丁工具:比如
objcopy、patch,直接修改ELF文件的.text或.rodata段内容,适合修改固定常量或简单指令序列。 - 动态插桩工具:比如
frida、gdb,在程序运行时动态修改内存中的指令或数据。例如用Frida的Interceptor.replace()可以直接替换内存中的函数实现,无论目标函数在主程序还是共享库中。 - 重编译源码:如果能获取程序源码,直接修改对应函数或数据后重新编译,这是最稳定可靠的方式。
内容的提问来源于stack exchange,提问作者Bananach
相关产品推荐
相关产品推荐

