Android笔记:判断是否为模拟器(实测夜神通过)

简介: Android笔记:判断是否为模拟器(实测夜神通过)

因为不确定因素太多,最近公司需要禁止本程序在虚拟机上运行。

我网上找了好多,各种方法什么设备号,拨打电话,蓝牙设备,模拟器的检测往往是防作弊中的重要一关,这里把这两天收集到的代码写在这偏文章里,和大家进行一个简单的分享。


传统方法

传统的检测方法主要是对模拟器的IMSI、IDS、默认文件等几个方面进行检测。


(1)默认号码:

   private static String[] known_numbers = {"15555215554", "15555215556",

               "15555215558", "15555215560", "15555215562", "15555215564",

               "15555215566", "15555215568", "15555215570", "15555215572",

               "15555215574", "15555215576", "15555215578", "15555215580",

               "15555215582", "15555215584"};

1

2

3

4

5

(2)默认ID:

private static String[] known_device_ids = {"000000000000000"};

1

(3)默认IMSI:

private static String[] known_imsi_ids = {"310260000000000"};

1

(4)默认文件路径:

   private static String[] known_files = {

               "/system/lib/libc_malloc_debug_qemu.so",

               "/sys/qemu_trace",

               "/system/bin/qemu-props"};

1

2

3

4

在得知了这些信息后,只需在运行时进行检测,如果检测结果和默认值吻合,那么检测设备便是模拟器。不过随着防反作弊技术的迭代,现在很多模拟器都可以改变这些值来逃避检测,所以上述传统方法在很多时候未曾达到开发者的预期效果。


拨打电话


public boolean isEmulator() {
        String url = "tel:" + "123456";
        Intent intent = new Intent();
        intent.setData(Uri.parse(url));
        intent.setAction(Intent.ACTION_DIAL);
        // 是否可以处理跳转到拨号的 Intent
        boolean canResolveIntent = intent.resolveActivity(mContext.getPackageManager()) != null;
        return Build.FINGERPRINT.startsWith("generic")
            || Build.FINGERPRINT.toLowerCase().contains("vbox")
            || Build.FINGERPRINT.toLowerCase().contains("test-keys")
            || Build.MODEL.contains("google_sdk")
            || Build.MODEL.contains("Emulator")
            || Build.SERIAL.equalsIgnoreCase("unknown")
            || Build.SERIAL.equalsIgnoreCase("android")
            || Build.MODEL.contains("Android SDK built for x86")
            || Build.MANUFACTURER.contains("Genymotion")
            || (Build.BRAND.startsWith("generic") && Build.DEVICE.startsWith("generic"))
            || "google_sdk".equals(Build.PRODUCT)
            || ((TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE))
                .getNetworkOperatorName().toLowerCase().equals("android")
            || !canResolverIntent;

光传感器

/**
 * 判断是否存在光传感器来判断是否为模拟器
 * 部分真机也不存在温度和压力传感器。其余传感器模拟器也存在。
 * @return true 为模拟器
 */
public static Boolean notHasLightSensorManager(Context context) {
    SensorManager sensorManager = (SensorManager) context.getSystemService(SENSOR_SERVICE);
    Sensor sensor8 = sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT); //光
    if (null == sensor8) {
        return true;
    } else {
        return false;
    }
}

蓝牙

    /*
     *判断蓝牙是否有效来判断是否为模拟器
     *返回:true 为模拟器
     */
    public static boolean notHasBlueTooth() {
        BluetoothAdapter ba = BluetoothAdapter.getDefaultAdapter();
        if (ba == null) {
            return true;
        } else {
            // 如果有蓝牙不一定是有效的。获取蓝牙名称,若为null 则默认为模拟器
            String name = ba.getName();
            if (TextUtils.isEmpty(name)) {
                return true;
            } else {
                return false;
            }
        }
    }

设备参数

  /*
    *根据部分特征参数设备信息来判断是否为模拟器
    *返回:true 为模拟器
    */
   public static boolean isFeatures() {
       return Build.FINGERPRINT.startsWith("generic")
               || Build.FINGERPRINT.toLowerCase().contains("vbox")
               || Build.FINGERPRINT.toLowerCase().contains("test-keys")
               || Build.MODEL.contains("google_sdk")
               || Build.MODEL.contains("Emulator")
               || Build.MODEL.contains("Android SDK built for x86")
               || Build.MANUFACTURER.contains("Genymotion")
               || (Build.BRAND.startsWith("generic") && Build.DEVICE.startsWith("generic"))
               || "google_sdk".equals(Build.PRODUCT);
   }

CPU

   /*
    *根据CPU是否为电脑来判断是否为模拟器
    *返回:true 为模拟器
    */
   public static boolean checkIsNotRealPhone() {
       String cpuInfo = readCpuInfo();
       if ((cpuInfo.contains("intel") || cpuInfo.contains("amd"))) {
           return true;
       }
       return false;
   }
   /*
    *根据CPU是否为电脑来判断是否为模拟器(子方法)
    *返回:String
    */
   public static String readCpuInfo() {
       String result = "";
       try {
           String[] args = {"/system/bin/cat", "/proc/cpuinfo"};
           ProcessBuilder cmd = new ProcessBuilder(args);
           Process process = cmd.start();
           StringBuffer sb = new StringBuffer();
           String readLine = "";
           BufferedReader responseReader = new BufferedReader(new InputStreamReader(process.getInputStream(), "utf-8"));
           while ((readLine = responseReader.readLine()) != null) {
               sb.append(readLine);
           }
           responseReader.close();
           result = sb.toString().toLowerCase();
       } catch (IOException ex) {
       }
       return result;
   }

大家有什么问题或者新的方法可以留言评论。


Android笔记:多开/分身检测



目录
相关文章
|
2月前
|
Linux 编译器 Android开发
FFmpeg开发笔记(九)Linux交叉编译Android的x265库
在Linux环境下,本文指导如何交叉编译x265的so库以适应Android。首先,需安装cmake和下载android-ndk-r21e。接着,下载x265源码,修改crosscompile.cmake的编译器设置。配置x265源码,使用指定的NDK路径,并在配置界面修改相关选项。随后,修改编译规则,编译并安装x265,调整pc描述文件并更新PKG_CONFIG_PATH。最后,修改FFmpeg配置脚本启用x265支持,编译安装FFmpeg,将生成的so文件导入Android工程,调整gradle配置以确保顺利运行。
125 1
FFmpeg开发笔记(九)Linux交叉编译Android的x265库
|
2月前
|
Unix Linux Shell
FFmpeg开发笔记(八)Linux交叉编译Android的FFmpeg库
在Linux环境下交叉编译Android所需的FFmpeg so库,首先下载`android-ndk-r21e`,然后解压。接着,上传FFmpeg及相关库(如x264、freetype、lame)源码,修改相关sh文件,将`SYSTEM=windows-x86_64`改为`SYSTEM=linux-x86_64`并删除回车符。对x264的configure文件进行修改,然后编译x264。同样编译其他第三方库。设置环境变量`PKG_CONFIG_PATH`,最后在FFmpeg源码目录执行配置、编译和安装命令,生成的so文件复制到App工程指定目录。
78 9
FFmpeg开发笔记(八)Linux交叉编译Android的FFmpeg库
|
8月前
|
安全 Android开发
夜神模拟器 安卓7.0 burp抓包 https流量
夜神模拟器 安卓7.0 burp抓包 https流量
258 0
|
9月前
|
存储 传感器 定位技术
《移动互联网技术》 第四章 移动应用开发: Android Studio开发环境的使用方法:建立工程,编写源程序,编译链接,安装模拟器,通过模拟器运行和调试程序
《移动互联网技术》 第四章 移动应用开发: Android Studio开发环境的使用方法:建立工程,编写源程序,编译链接,安装模拟器,通过模拟器运行和调试程序
124 0
|
18天前
|
Java API Android开发
技术经验分享:Android源码笔记——Camera系统架构
技术经验分享:Android源码笔记——Camera系统架构
21 0
|
2月前
|
安全 Linux Android开发
FFmpeg开发笔记(十六)Linux交叉编译Android的OpenSSL库
该文介绍了如何在Linux服务器上交叉编译Android的FFmpeg库以支持HTTPS视频播放。首先,从GitHub下载openssl源码,解压后通过编译脚本`build_openssl.sh`生成64位静态库。接着,更新环境变量加载openssl,并编辑FFmpeg配置脚本`config_ffmpeg_openssl.sh`启用openssl支持。然后,编译安装FFmpeg。最后,将编译好的库文件导入App工程的相应目录,修改视频链接为HTTPS,App即可播放HTTPS在线视频。
59 3
FFmpeg开发笔记(十六)Linux交叉编译Android的OpenSSL库
|
2月前
|
Java 测试技术 开发工具
Android 笔记:AndroidTrain , Lint , build(1),只需一篇文章吃透Android多线程技术
Android 笔记:AndroidTrain , Lint , build(1),只需一篇文章吃透Android多线程技术
|
2月前
|
设计模式 缓存 前端开发
真的强!借助阿里技术博主分享的Android面试笔记,我拿到了字节跳动的offer
真的强!借助阿里技术博主分享的Android面试笔记,我拿到了字节跳动的offer
|
2月前
|
开发工具 Android开发
解决夜神模拟器与Android studio自动断开的问题
解决夜神模拟器与Android studio自动断开的问题
48 1
|
2月前
|
编解码 Android开发
android 创建平板电脑模拟器(转)
android 创建平板电脑模拟器(转)
46 2