dlopen()
在API-23上正常运行,但对于Android-N,当我尝试使用dlopen
打开任何sofile时,它会返回soinfo
结构类型指针。但当我试图访问此结构的任何变量时,应用程序崩溃。
si = (soinfo*) dlopen("/data/app/com.xxx.xxx.sampleapp.android-1/lib/x86/libtest.so", RTLD_GLOBAL);
if (si == NULL)
return;
LOGI("value of dlopen [%d]", si->size);
Android-N的dlopen()
功能是否有任何变化
答案 0 :(得分:8)
dlopen()
不返回指向某个soinfo
结构的指针,它返回void*
,标准Linux手册页对此非常具体:
函数dlopen()加载由以null结尾的字符串文件名命名的动态共享对象(共享库)文件,并为加载的对象返回不透明的“句柄”。此句柄与dlopen API中的其他函数一起使用,例如dlsym(3),dladdr(3),dlinfo(3)和dlclose()。
因此,您可以通过某种方式解释返回值的事实是非标准的,现在Google只是使用this change强制执行此操作:
commit ae74e8750b9dae51b24a22fdb4b0e0a2d84f37b9
author Dimitry Ivanov <dimitry@google.com>
...
linker: hide the pointer to soinfo
Handle no longer is a pointer to soinfo of
a corresponding library. This is done to
prevent access to linker internal fields.
Bug: http://b/25593965
Change-Id: I62bff0d0e5b2dc842e6bf0babb30fcc4c000be24
(cherry picked from commit d88e1f350111b3dfd71c6492321f0503cb5540db)
因此,除非您的应用程序针对的是SDK版本23或更低版本(请参阅soinfo::to_handle()
),否则您现在只能使用内部仿生{{1}获取只能转换回soinfo*
的句柄。 }。
答案 1 :(得分:2)
从developer documentation(强调添加):
从Android 7.0开始,系统会阻止应用动态链接非NDK库,这可能会导致您的应用崩溃。这种行为变化旨在跨平台更新和不同设备创建一致的应用体验 ...
所有应用程序在调用既不公开也不可临时访问的API时会生成运行时错误。 结果是System.loadLibrary和dlopen(3)都返回NULL ,并可能导致您的应用崩溃。
答案 2 :(得分:0)
以下是Google对隐藏soinfo以防止访问链接器内部字段的更改。
https://android.googlesource.com/platform/bionic/+/d88e1f350111b3dfd71c6492321f0503cb5540db
链接器:隐藏指向soinfo的指针
句柄不再是指向soinfo的指针 相应的图书馆。这样就完成了 阻止访问链接器内部字段。