欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Android检测模拟器

程序员文章站 2022-05-16 18:05:27
...

1. 前言

模拟器大家都应该很熟悉的吧!现在市面上的模拟器多的数不清,例如:雷电模拟器、夜神模拟器等等。而因为模拟器所搭载的Android系统是阉割过的,一些安全相关的功能都没有了。这就造成了一个安全问题,在模拟器运行的APP,可被动态调试、抓取数据等,从而增大APP被**、敏感数据遭泄露的风险。所以一些公司就会禁止用户在模拟器中使用他们的APP。

那怎么检测APP当前运行的环境是模拟器呢?接下来我就介绍一个方案给大家吧!

2. 解决方案

网上相关资料其实蛮多的,但是因为模拟器的技术也在逐步增长,所以有些资料其实并没有完全有用,还是会出现无法检测某些模拟器。

我在GitHub上发现了一个开源项目 anti-emulator 。经测试可以检测出市面上较常用的模拟器。我将关键代码提取了出来,封装成一个module,详见 lib_anti_emulator

我封装了两个方法,如下所示:

/**
 * 检测是否是模拟器
 *
 * @param context 上下文
 * @return true:是模拟器;false:不是模拟器
 */
public static boolean check(Context context) {
    try {
        return isTaintTrackingDetected(context) || isMonkeyDetected() || isDebugged()
                || isQEmuEnvDetected(context);
    } catch (Exception e) {
        e.printStackTrace();
        return false;
    }
}

/**
 * 检测是否是模拟器,安全模式<br>
 * 机制较弱,可避免部分真机被识别为模拟器,但是这也造成了有些模拟器无法被识别
 *
 * @param context 上下文
 * @return true:是模拟器;false:不是模拟器
 */
public static boolean checkSafely(Context context) {
    try {
        return isTaintTrackingDetected(context) || isMonkeyDetected() || isDebugged()
                || isQEmuEnvSafeDetected(context);
    } catch (Exception e) {
        e.printStackTrace();
        return false;
    }
}

这两个方法的区分,看注释大家也应该很清楚了。而这也是 anti-emulator 的最大缺点,可以说是检测机制太强,或者说某些真机系统被魔改了,造成真机会被错误识别为模拟器的bug。所以如果使用 check 方法,为了避免用户无法正常使用APP,就需要我们再做一些处理,例如当被检测为模拟器时,可以弹出窗口,引导用户上报相关真机信息,然后后台审核并记录这些信息,将此用户所使用的真机加入白名单,免检测模拟器。

当然如果APP不需要这么强的检测机制的话,那就用 checkSafely 方法就行了。

3. 演示

我在我的 BlogDemo 中已加入演示代码,感兴趣的可以去看看。下面是演示的相关内容,演示环境是雷电模拟器。

3.1 标准模式

能够正确检测模拟器,提示“是模拟器”。

Android检测模拟器

3.2 安全模式

不能够正确检测模拟器,提示“不是模拟器”。PS:雷电模拟器的仿真程度真高,所以平时大家调试APP的时候,如果不想用真机,可以试试雷电模拟器哦!比起 Android Studio 自带的模拟器,不会那么吃 CPU 和内存。

Android检测模拟器


如果想进一步交流和学习的同学,可以加一下QQ群哦!

Android检测模拟器