如何拦截MIPS Linux下动态库调用主程序静态导出的API函数
主程序导出符号拦截方案
LD_PRELOAD在此场景失效的核心原因是:Linux动态链接器的默认符号解析规则中,主程序的全局导出符号优先级高于所有动态库(包括预加载库)的同名符号,因此你在预加载库中定义的IMP_ISP_Open不会被优先解析。
可采用以下两种兼容旧MIPS uClibc环境的方案实现拦截:
- 方案1:Patch动态库依赖项
使用patchelf工具为libhyCoreSdk.so添加对你的拦截库的依赖:
此时动态链接器解析patchelf --add-needed libyour_hook.so libhyCoreSdk.solibhyCoreSdk.so的未定义符号IMP_ISP_Open时,会优先搜索其直接依赖的libyour_hook.so,你只需要在拦截库中导出IMP_ISP_Open即可命中拦截,原函数可以通过直接打开主程序句柄的方式调用。 - 方案2:主程序函数入口插桩
你已经通过Ghidra获取到IMP_ISP_Open在主程序中的虚拟地址,直接在该函数入口写入MIPS跳转指令,跳转到你的拦截函数执行参数获取逻辑,完成后再跳回原函数后续地址执行即可。该方案完全不依赖动态链接规则,兼容性最高。
重命名符号后dlsym返回NULL问题修复
该问题是旧版本uClibc动态链接器的实现缺陷:RTLD_DEFAULT的搜索范围不会包含主程序的全局导出符号,因此无法直接搜索到你重命名后的XMP_前缀符号。
采用以下方式即可正常获取符号地址:
#include <dlfcn.h> // 先打开当前进程的可执行文件获取句柄 void* app_handle = dlopen("/proc/self/exe", RTLD_LAZY); if (app_handle) { // 从主程序句柄中搜索对应符号 void* xmp_func = dlsym(app_handle, "XMP_ISP_DisableSensor"); // 后续执行原函数调用即可 dlclose(app_handle); }
编译拦截库时记得加上-ldl链接选项。
内容的提问来源于stack exchange,提问作者wd40bomber7
相关产品推荐
相关产品推荐

