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;
}
}
return false;
}
继续跟踪传递进来的参数 runtime->GetHiddenApiExemptions()
发现这玩意儿也是 runtime 里面的一个参数,既然如此,我们可以一不做二不休,仿照修改 runtime flag 的方式直接修改 hidden_api_exemptions_
也能绕过去。但如果我们继续跟踪下去,会有个有趣的发现:这个API 竟然是暴露到 Java 层的,有一个对应的 VMRuntime.setHiddenApiExemptions Java方法;也就是说,只要我们通过 VMRuntime.setHiddenApiExemptions
设置下豁免条件,我们就能愉快滴使用反射了。
再结合上面这个方法,我们只需要通过 「元反射」来反射调用 VMRuntime.setHiddenApiExemptions
就能将我们自己要使用的隐藏 API 全部都豁免掉了。更进一步,如果我们再观察下上面的 IsExempted
方法里面调用的 DoesPrefixMatch
,发现这玩意儿在对方法签名进行前缀匹配;童鞋们,我们所有Java方法类的签名都是以 L 开头啊!如果我们把直接传个 L
进去,所有的隐藏API全部被赦免了!
详细代码在这里:
tiann/FreeReflectiongithub.com
理论上讲,这个方案不存在兼容性问题。即使 ROM 删掉了 setHiddenApiExemptions
方法,我们依然可以用「元反射」的方式去反射隐藏API,并且所有的代码加起来不超过30行!当然,如果 Google 继续改进验证隐藏API调用的方法,这个方式可能会失效;但是目前的机制没有问题。
文章的最后,我想说的是,本文的目的不是刻意去绕过限制。不给思维设限,才会有更多可能。
最后
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。
因此我收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点!不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门
如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
7)
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!