dlopen()不能用于android-n

时间:2016-09-05 07:34:09

标签: android linux dlopen android-7.0-nougat

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()功能是否有任何变化

3 个答案:

答案 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的指针 相应的图书馆。这样就完成了 阻止访问链接器内部字段。