Android API30+下FindLibrary返回0,libsamp.so找不到libGTASA.so
问题解决:Android API30+下libsamp.so无法找到libGTASA.so地址
核心原因
Android 11(API Level 30)及以上版本对/proc/[pid]/maps文件的访问权限做了严格限制,第三方应用无法读取到所有已加载共享库的完整条目,导致原通过扫描/proc/maps查找库基地址的方法失效。
解决方案:用dl_iterate_phdr替代/proc/maps扫描
dl_iterate_phdr是Android NDK提供的官方API,用于遍历当前进程已加载的共享库,不受API30+权限限制,是获取库基地址的可靠方式。
替换FindLibrary实现
将原FindLibrary函数替换为以下代码:
#include <link.h> #include <string.h> struct LibraryFindInfo { const char* target_name; uintptr_t base_address; }; static int phdr_iterate_callback(struct dl_phdr_info* info, size_t size, void* data) { LibraryFindInfo* find_data = reinterpret_cast<LibraryFindInfo*>(data); // 从完整路径中提取库文件名 const char* lib_filename = strrchr(info->dlpi_name, '/'); lib_filename = lib_filename ? lib_filename + 1 : info->dlpi_name; // 匹配目标库名 if (strcmp(lib_filename, find_data->target_name) == 0) { find_data->base_address = info->dlpi_addr; return 1; // 找到后终止遍历 } return 0; } uintptr_t FindLibrary(const char* library) { LibraryFindInfo find_data = {library, 0}; dl_iterate_phdr(phdr_iterate_callback, &find_data); return find_data.base_address; }
代码说明
dl_iterate_phdr会遍历进程内所有已加载的共享库,逐个调用回调函数处理库信息- 回调函数从
dlpi_name中提取纯库文件名,与目标名称匹配 - 匹配成功后,
dlpi_addr即为该库加载到内存的基地址
额外验证点
- 确认加载顺序:从日志看Java层先加载libGTASA.so再加载libsamp.so,且libGTASA的JNI_OnLoad已执行,加载时机无问题
- 核对库名拼写:确保
libGTASA.so的大小写、后缀与实际加载的库完全一致
内容的提问来源于stack exchange,提问作者Daniil Solodkov
相关产品推荐
相关产品推荐

