Python 3.6中ctypes.CDLL(None)加载LD_PRELOAD符号失败的解决办法
Python 3.6中
ctypes.CDLL(None)无法找到LD_PRELOAD符号的解决方法 问题原因
Python 3.6的ctypes.CDLL(None)默认仅搜索主可执行文件(python3)自身的符号表,而Python 2.7和3.11的实现会遍历进程中所有已加载的共享库符号。另外,部分发行版的Python 3.6编译时启用了符号隐藏选项,进一步限制了符号可见范围,导致LD_PRELOAD加载的库符号无法被检测到。
可行解决方案
方案1:直接加载目标共享库
跳过CDLL(None),直接指定共享库路径加载,这是最直接的方式:
import ctypes # 直接加载预加载的libfoo.so lib = ctypes.CDLL("./libfoo.so") foo = lib.foo foo()
方案2:显式指定全局符号加载模式
通过设置dlopen的RTLD_GLOBAL和RTLD_NOW标志,强制让CDLL(None)搜索进程内所有全局可见的符号:
import ctypes # 定义dlopen的模式常量 RTLD_NOW = 0x00002 RTLD_GLOBAL = 0x00010 # 以全局模式加载当前进程的符号表 lib = ctypes.CDLL(None, mode=RTLD_NOW | RTLD_GLOBAL) foo = lib["foo"] foo()
运行此代码时,执行LD_PRELOAD=./libfoo.so python3.6 test.py即可正常调用foo函数。
方案3:调整Python编译选项(不推荐)
如果是自行编译Python 3.6,可移除编译时的-fvisibility=hidden等符号隐藏选项,让主可执行文件暴露所有进程符号。但此方法需要重新编译Python,成本较高,仅适合特殊场景。
内容的提问来源于stack exchange,提问作者Julien
相关产品推荐
相关产品推荐

