β

一种绕过Android P对非SDK接口限制的简单方法

Harries Blog™ 80 阅读

众所周知, Android P 引入了 针对非 SDK 接口(俗称为隐藏 API )的使用限制
。这是继 Andro id N上 针对 NDK 中私有库的链接限制
之后的又一次重大调整。从今以后,不论是native层的NDK还是 Java层的SDK,我们只能使用 Google 提供的、公开的标准接口。这对 开发者 以及用户乃至整个Android生态,当然是一件好事。但这也同时意味着Android上的各种黑 科技 有可能会逐渐走向消亡。

作为一个有追求的 开发 者,我们既要尊重并遵守规则,也要有能力在必要的时候 突破 规则的束缚,带着镣铐跳舞。恰好最近有人反馈 VirtualXposed 在 Android P上无法运行
,那么今天就来探讨一下,如何突破Android P上针对非SDK接口调用的限制。

系统是如何实现这个限制的?

知己知彼,百战不殆。既然我们想要突破这个限制,自然先得弄清楚,系统是如何给我们施加这个限制的。

文档
中说,通过反射或者JNI访问非公开接口时会触发警告/异常等,那么不妨跟踪一下反射的流程,看看系统到底在哪一步做的限制(以下的 源码 分析大可以走马观花的看一下,需要的时候自己再仔细看)。我们从 java .lang.Class.getDeclaredMethod(String)
看起,这个方法在Java层 最终调用到
getDeclaredMethodInternal
这个native方法,看一下这个方法的源码:

static jobject Class_getDeclaredMethodInternal(JNIEnv* env, jobject javaThis,
                                               jstring name, jobjectArray args) {
  ScopedFastNativeObjectAccess soa(env);
  StackHandleScope<1> hs(soa.Self());
  DCHECK_EQ(Runtime::Current()->GetClassLinker()->GetImagePointerSize(), kRuntimePointerSize);
  DCHECK(!Runtime::Current()->IsActiveTransaction());
  Handle<mirror::Method> result = hs.NewHandle(
      mirror::Class::GetDeclaredMethodInternal<kRuntimePointerSize, false>(
          soa.Self(),
          DecodeClass(soa, javaThis),
          soa.Decode<mirror::String>(name),
          soa.Decode<mirror::ObjectArray<mirror::Class>>(args)));
  if (result == nullptr || ShouldBlockAccessToMember(result->GetArtMethod(), soa.Self())) {
    return nullptr;
  }
  return soa.AddLocalReference<jobject>(result.Get());
}
作者:Harries Blog™
追心中的海,逐世界的梦
原文地址:一种绕过Android P对非SDK接口限制的简单方法, 感谢原作者分享。

发表评论