2018年发布的Android 9中引入了对隐藏API的限制,这对整个Android生态来说当然是一件好事,但也严重限制了以往我们通过反射等手段实现的“黑科技”(如插件化等),所以开发者们纷纷寻找手段绕过这个限制,比如我曾经提出了两个绕过方法,其中一个便是几乎完美的双重反射(即“元反射”,现在来看叫“套娃反射”比较好);而在即将发布的Android R中把这个方法封杀了(谷歌:禁止套娃!),因此我重新研究了Android R中的限制策略。
2021/4/10 更新:
本文存在纰漏,请看一个通用的纯 Java 安卓隐藏 API 限制绕过方案
上有政策
常言道,知己知彼,百战百胜。要想破解这个限制,就必须去搞懂系统是怎么施加的限制;ok,废话不多说,let’s go!
以我们在Java层通过反射获取一个Method为例,Class.getMethod/getDeclaredMethod最终都会进入一个native方法getDeclaredMethodInternal,这个方法的实现如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| static jobject Class_getDeclaredMethodInternal(JNIEnv* env, jobject javaThis, jstring name, jobjectArray args) { Handle<mirror::Method> result = hs.NewHandle( mirror::Class::GetDeclaredMethodInternal<kRuntimePointerSize>( soa.Self(), klass, soa.Decode<mirror::String>(name), soa.Decode<mirror::ObjectArray<mirror::Class>>(args), GetHiddenapiAccessContextFunction(soa.Self()))); if (result == nullptr || ShouldDenyAccessToMember(result->GetArtMethod(), soa.Self())) { return nullptr; } return soa.AddLocalReference<jobject>(result.Get()); }
|
我们可以发现,如果ShouldDenyAccessToMember返回true,那么就会返回null,上层就会抛出方法找不到的异常。这里和Android P没什么不同,只是把ShouldBlockAccessToMember改了个名而已。
ShouldDenyAccessToMember会调用到hiddenapi::ShouldDenyAccessToMember,该函数是这样实现的:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| template<typename T> inline bool ShouldDenyAccessToMember(T* member, const std::function<AccessContext()>& fn_get_access_context, AccessMethod access_method) REQUIRES_SHARED(Locks::mutator_lock_) {
const uint32_t runtime_flags = GetRuntimeFlags(member);
if ((runtime_flags & kAccPublicApi) != 0) { return false; }
const AccessContext caller_context = fn_get_access_context(); const AccessContext callee_context(member->GetDeclaringClass());
if (caller_context.CanAlwaysAccess(callee_context)) { return false; }
switch (caller_context.GetDomain()) { case Domain::kApplication: { DCHECK(!callee_context.IsApplicationDomain());
EnforcementPolicy policy = Runtime::Current()->GetHiddenApiEnforcementPolicy(); if (policy... |