据说你想在Android P上使用hide api?

前言

从 Android 9(API 级别 28)开始,此平台对应用能使用的非 SDK 接口实施了限制。只要应用引用非 SDK 接口或尝试使用反射或 JNI 来获取其句柄,这些限制就适用。这些限制旨在帮助提高用户体验和开发者体验,为用户下降应用发生崩溃的风险,同时为开发者下降紧急发布的风险java

一条消息瞬间席卷了整个开发圈子。会不会影响插件化?会不会影响热修复?好在,对这些没影响。然而,对一些很是hacker的手段,仍是有着不小的影响,好比上一篇的DNS hook libcore的方案。那么,咱们如何解决呢?linux

针对非 SDK 接口的限制

若是你们不了解这个限制,能够先去针对非 SDK 接口的限制这个文档中了解一下,这里简单的说一下。当咱们访问受限的接口时,会出现以下状况。android

那么,如何检查你的应用中是否有使用受限的接口呢。咱们可使用veridex工具进行查看。用法以下git

### Linux x64
Download veridex-linux.zip, unzip the file and run with:
> ./appcompat.sh --dex-file=test.apk
### macOS
Download veridex-mac.zip, unzip the file and run with:
> ./appcompat.sh --dex-file=test.apk
复制代码

通过检查,若是发现没有使用,那即是极好的,可是!!!若是使用了且无可替代怎么办?办他!github

解除限制的原理

很早以前,360团队就出了两篇文章。 Android P 调用隐藏API限制原理 以及 突破Android P(Preview 1)对调用隐藏API限制的方法 。这两篇文章也是咱们下面方案的原理来源。面试

方法一(不建议)

这个方法一对应的是360文章中的方法三。主要代码以下。bash

其中,fake_dlopen、fake_dlsym 使用的是Nougat_dlfunctions,主要是Android 7.0以上对dlopen、dlsym等函数作了限制。所以用这个库。而MSHookFunction,则是大名鼎鼎的cydiasubstrate微信

上面的代码只解决了反射方法的问题。我按照这种思路去解决字段问题的时候发现。架构

GetDeclaredField是inline的,没法切入。而CreateFromArtField又是hidden的,也很差切入。app

所以,放弃了这种方法。

方法二(可用,可是有更好的)

这里对应的方法二,对应的是360文章中的方法二,也就是修改classloader的方式。代码以下。

没错,代码就是这么点。这样,咱们就能够在ReflectionHelper中调用非公开API了。可是这里会依赖Nougat_dlfunctions这个库。

方法三(超级好)

既然是修改classloader,那么咱们为何不在java层修改呢。代码以下。

而这里用的相关反射只是light级别的,没有什么影响。反而代码量超小,也不依赖其余。

方法四(超级好+1)

这个方案来自 @区长 大神

方法四仍是存在一点问题。若是之后把classloader加入到深灰或者黑名单,那就僵硬了。因此,咱们不用反射,直接用unsafe去修改。代码这就不贴了。为了获得classloader的偏移量,咱们写一个和Class结构同样的类,用这个类获得的classLoader的偏移量和Class是同样的。

方法五

田维术 VMRuntime.setHiddenApiExemptions 方法,连接在这里点我查看

以为写的还行的朋友能够关注如下个人微信公众号,这里用于交流一些Android基础架构、疑难杂症、面试等等问题。

相关文章
相关标签/搜索