首页
社区
课程
招聘
[原创]改一个参数即可绕过 Android N 的私有 API 链接限制
发表于: 2017-5-26 14:28 14798

[原创]改一个参数即可绕过 Android N 的私有 API 链接限制

2017-5-26 14:28
14798

从 Android N 开始,对 NDK 调用私有 API 的行为做了限制。在 Android 7.0 行为变更中明确提到:

通常使用私有 API 的做法是,使用 dlopen 加载 API 所在的动态库,然后通过 dlsym 获取函数地址并调用之。例如如下代码通过不被 NDK 推荐的方式,解析私有函数 JNI_GetCreatedJavaVMs 获取 jvm 实例:

Android N 对此的处理方式是,使用 classloader-namespace 限制了 dlopen 参数允许加载的路径。对于 NDK 公开可用的链接库 (如 libandroid, libc, libcamera2ndk, libdl, libGLES, libjnigraphics, liblog, libm, libmediandk, libOpenMAXAL, libOpenSLES, libstdc++, libvulkan, libz 等),以及 apk 自带的 libs 下的共享对象,可以自由地加载。但尝试 dlopen 其他路径的文件则会返回 null 并在 logcat 中打印类似这样的错误:

为了兼容性,在应用的 target API level 小于 24 时,linker 输出一个警告并弹出 toast。

如果 target API level 为 Android N 甚至更高版本,那么 dlopen 将返回 null,并可能抛出 java.lang.UnsatisfiedLinkError:


Android 的链接器源码在 platform/bionic/linker/linker.cpp 实现。执行 C 标准库的 dlopen 函数时,在内部函数 load_library 中加入了对链接库合法性的判断:

https://android.googlesource.com/platform/bionic/+/master/linker/linker.cpp#1210


小于 API Level 24 时允许加载的“灰名单”如下:


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 1
支持
分享
最新回复 (4)
雪    币: 43
活跃值: (388)
能力值: ( LV9,RANK:140 )
在线值:
发帖
回帖
粉丝
2
其实也简单,搞个内存补丁,或者自定义linker都可以
2017-5-26 16:52
0
雪    币: 312
活跃值: (123)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
3
感觉这么做意义不大,就是憧憬一下罢了
2017-5-27 03:19
0
雪    币: 2039
活跃值: (1468)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
4
这种方式在个别手机上不行,无法通用。
2017-7-13 10:12
0
雪    币: 55
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
https://github.com/rrrfff/ndk_dlopen
2018-1-23 16:51
0
游客
登录 | 注册 方可回帖
返回
//