Android 绕过反射黑名单的方法

 更新时间:2021年02月08日 09:24:13   作者:苍耳  
这篇文章主要介绍了Android 绕过反射黑名单的方法,帮助大家更好的理解和使用Android,感兴趣的朋友可以了解下

限制原理

Google 从 Android P 开始引入了针对非公开 API 的限制,这一点可以从 Native 相关的源码中找到限制的原理,从而从中找到解决办法,不过非必要原因不太建议去挑战这种限制,毕竟不清楚在后续的版本中会不会做限制,维护起来挺麻烦的。

在 Native 层有几个访问级别:

class HiddenApiAccessFlags {
  public:
  enum ApiList {
    kWhitelist = 0,
    kLightGreylist,
    kDarkGreylist,
    kBlacklist,
  };
}

另外还有几个对应的响应级别:

enum Action {
  kAllow,     //通过
  kAllowButWarn, //通过,但日志警告
  kAllowButWarnAndToast, //通过,且日志警告和弹窗
  kDeny  //拒绝访问
};

这里介绍一下网上的一些解决方式,此外,还可以把我们调用了反射方法的类的类加载器设置为系统类加载器,这样就可以绕过 Native 层的限制了。

系统类伪装

黑名单在系统中有一个 fn_caller_is_trusted 的条件:如果调用者是系统类,那么就允许被调用。即如果我们能以系统类的身份去反射,那么就能畅通无阻:

  1. 首先通过反射 API 拿到 getDeclaredMethod 方法。getDeclaredMethod 是 public 的,不存在问题;这个通过反射拿到的方法网上称之为元反射方法。
  2. 然后通过刚刚的元反射方法去反射调用 getDeclardMethod。这里我们就实现了以系统身份去反射的目的——反射相关的 API 都是系统类,因此我们的元反射方法也是被系统类加载的方法;所以我们的元反射方法调用的 getDeclardMethod 会被认为是系统调用的,可以反射任意的方法。

伪代码如下:

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

豁免条件

隐藏 API 的调用有「豁免」条件,即只要它是豁免的,则即使它在黑名单中,也会被放行。这种方式暴露给了 Java 层,因此可以通过 VMRuntime.setHiddenApiExemptions 方法来实现。再结合上面这个方法,我们只需要通过 「元反射」 来反射调用 VMRuntime.setHiddenApiExemptions 就能将我们自己要使用的隐藏 API 全部都豁免掉了。另外系统在检查豁免时是通过方法签名进行前缀匹配的,而 Java 方法签名都是 L 开头的,因此我们可以把直接传个 L 进去,那么所有的隐藏API全部被赦免了!

源码直接参考网上大佬的开源项目: FreeReflection

public final class BootstrapClass {

  private static final String TAG = "BootstrapClass";

  private static Object sVmRuntime;
  private static Method setHiddenApiExemptions;

  static {
    if (SDK_INT >= Build.VERSION_CODES.P) {
      try {
        Method forName = Class.class.getDeclaredMethod("forName", String.class);
        Method getDeclaredMethod = Class.class.getDeclaredMethod("getDeclaredMethod", String.class, Class[].class);

        Class<?> vmRuntimeClass = (Class<?>) forName.invoke(null, "dalvik.system.VMRuntime");
        Method getRuntime = (Method) getDeclaredMethod.invoke(vmRuntimeClass, "getRuntime", null);
        setHiddenApiExemptions = (Method) getDeclaredMethod.invoke(vmRuntimeClass, "setHiddenApiExemptions", new Class[]{String[].class});
        sVmRuntime = getRuntime.invoke(null);
      } catch (Throwable e) {
        Log.w(TAG, "reflect bootstrap failed:", e);
      }
    }
  }

  /**
   * make the method exempted from hidden API check.
   *
   * @param method the method signature prefix.
   * @return true if success.
   */
  public static boolean exempt(String method) {
    return exempt(new String[]{method});
  }

  /**
   * make specific methods exempted from hidden API check.
   *
   * @param methods the method signature prefix, such as "Ldalvik/system", "Landroid" or even "L"
   * @return true if success
   */
  public static boolean exempt(String... methods) {
    if (sVmRuntime == null || setHiddenApiExemptions == null) {
      return false;
    }

    try {
      setHiddenApiExemptions.invoke(sVmRuntime, new Object[]{methods});
      return true;
    } catch (Throwable e) {
      return false;
    }
  }

  /**
   * Make all hidden API exempted.
   *
   * @return true if success.
   */
  public static boolean exemptAll() {
    return exempt(new String[]{"L"});
  }
}

以上就是Android 绕过反射黑名单的方法的详细内容,更多关于Android 绕过反射黑名单的资料请关注脚本之家其它相关文章!

相关文章

  • Kotlin Service服务组件开发详解

    Kotlin Service服务组件开发详解

    这几天分析了一下的启动过程,于是乎,今天写一下Service使用; 给我的感觉是它并不复杂,千万不要被一坨一坨的代码吓住了,虽然弯弯绕绕不少,重载函数一个接着一个,就向走迷宫一样,但只要抓住主线阅读,很快就能找到出口
    2022-12-12
  • android使用多线程更新ui示例分享

    android使用多线程更新ui示例分享

    在Android平台中多线程应用很广泛,在UI更新、游戏开发和耗时处理(网络通信等)等方面都需要多线程,下面是一个在线程中更新UI的代码
    2014-01-01
  • Android自定义控件实现带文本与数字的圆形进度条

    Android自定义控件实现带文本与数字的圆形进度条

    这篇文章主要为大家详细介绍了Android自定义控件实现带文本与数字的圆形进度条,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-12-12
  • Android BadgeView红点更新信息提示示例代码

    Android BadgeView红点更新信息提示示例代码

    本篇文章主要介绍了Android BadgeView红点更新信息提示示例代码,具有一定的参考价值,有兴趣的可以了解一下。
    2017-01-01
  • 深入Android SQLite 事务处理详解

    深入Android SQLite 事务处理详解

    本篇文章是对Android中SQLite 事务处理进行了详细的分析介绍。需要的朋友参考下
    2013-05-05
  • 浅谈Android RecyclerView 间距全适配

    浅谈Android RecyclerView 间距全适配

    本篇文章主要介绍了浅谈Android RecyclerView 间距全适配,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-12-12
  • Android 自动完成文本框的实例

    Android 自动完成文本框的实例

    下面小编就为大家分享一篇Android 自动完成文本框的实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-01-01
  • Kotlin实现半圆形进度条的方法示例

    Kotlin实现半圆形进度条的方法示例

    这篇文章主要给大家介绍了关于Kotlin实现半圆形进度条的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧。
    2018-03-03
  • android获取附近蓝牙设备并计算距离的实例代码

    android获取附近蓝牙设备并计算距离的实例代码

    下面小编就为大家分享一篇android获取附近蓝牙设备并计算距离的实例代码,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-01-01
  • Android利用绘制缓冲实现代码雨效果

    Android利用绘制缓冲实现代码雨效果

    看过很多代码雨的前端实现,却很少看到过Android代码雨效果的实现,当然 open gl es的实现是有的,一个主要的原因是,在Android Canvas绘制时,很少有人考虑使用绘制缓冲,所以本文将给大家介绍Android如何利用绘制缓冲实现代码雨效果,需要的朋友可以参考下
    2024-03-03

最新评论