写点什么

另一种绕过 -Android-P 以上非公开 API 限制的办法,安卓多线程面试题

用户头像
Android架构
关注
发布于: 15 小时前

以系统类的身份去反射 有两个意思,1. 直接把我们自己变成系统类;2. 借助系统类去调用反射。我们一个个分析。


「直接把我们自己变成系统类」这个方式有童鞋可能觉得天方夜谭,APP 的类怎么可能成为系统类?但是,一切皆有可能!我们知道,对 APP 来说,所谓的系统类就是被 BootstrapClassLoader 加载的类,这个 ClassLoader 并非普通的 DexClassLoader,因此我们无法通过插入 dex path 的方式注入类。但是,Android 的 ART 在 Android O 上引入了 JVMTI,JVMTI 提供了将某一个类转换为 BootstrapClassLoader 中的类的方法!具体来说,我们写一个类暴露反射相关的接口,然后通过 JVMTI 提供的 AddToBootstrapClassLoaderSearch将此类加入 BootstrapClassLoader 就实现目的了。不过,JVMTI 要在 release 版本的 APP 上运行依然需要 Hack,所以这种途径与其他的黑科技无本质区别。关于 JVMTI 可以参考我这个回答:


[Android Studio 3.5 提供的”Apply Changes“是什么原理??www.zhihu.com[图片上传失败...(image-87cb61-1590133002486)]](


)


第二种方法,「借助系统的类去反射」也就是说,如果系统有一个方法systemMethod,这个systemMethod 去调用反射相反的方法,那么systemMethod毋庸置疑会反射成功。但是,我们从哪去找到这么一个方法给我们用?事


《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
浏览器打开:qq.cn.hn/FTe 免费领取
复制代码


实上,我们不仅能找到这样的方法,而且这个方法能帮助我们调用任意的函数,那就是****反射本身!****可能你已经绕晕了,我解释一下:


  1. 首先,我们通过反射 API 拿到 getDeclaredMethod 方法。getDeclaredMethod 是 public 的,不存在问题;这个通过反射拿到的方法我们称之为元反射方法

  2. 然后,我们通过刚刚反射拿到元反射方法去反射调用 getDeclardMethod。这里我们就实现了以系统身份去反射的目的——反射相关的 API 都是系统类,因此我们的元反射方法也是被系统类加载的方法;所以我们的元反射方法调用的 getDeclardMethod 会被认为是系统调用的,可以反射任意的方法。


伪代码如下:


Method metaGetDeclaredMethod =Class.class.getDeclaredMethod("getDeclardMethod"); // 公开 API,无问题 Method hiddenMethod = metaGetDeclaredMethod.invoke(hiddenClass,"hiddenMethod", "hiddenMethod 参数列表"); // 系统类通过反射使用隐藏 API,检查直接通过。hiddenMethod.invoke // 正确找到 Method 直接反射调用


到这里,我们已经能通过「元反射」的方式去任意获取隐藏方法或者隐藏 Field 了。但是,如果我们所有使用的隐藏方法都要这么干,那还有点小麻烦。在?[上文](


)?中,我们后来发现,隐藏 API 调用还有「豁免」条件,具体代码如下:


if (shouldWarn || action == kDeny) {if (member_signature.IsExempted(runtime->GetHiddenApiExemptions())) {action = kAllow;// Avoid re-examining the exemption list next time.// Note this results in no warning for the member, which seems like what one would expect.// Exemptions effectively adds new members to the whitelist.MaybeWhitelistMember(runtime, member);return kAllow;}// 略


}


只要 IsExempted 方法返回 true,就算这个方法在黑名单中,依然会被放行然后允许被调用。我们再观察一下IsExempted方法:


bool MemberSignature::IsExempted(const std::vectorstd::string& exemptions) {for (const std::string& exemption : exemptions) {if (DoesPrefixMatch(exemption)) {return true;

用户头像

Android架构

关注

还未添加个人签名 2021.10.31 加入

还未添加个人简介

评论

发布
暂无评论
另一种绕过-Android-P以上非公开API限制的办法,安卓多线程面试题