欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android模擬器最新檢測方法詳解

 更新時間:2024年02月11日 11:46:09   作者:移動安全星球  
這篇文章主要介紹了Android模擬器的檢測方法,在Android開發(fā)過程中,防作弊一直是老生常談的問題,而模擬器的檢測往往是防作弊中的重要一環(huán),接下來我們來講解有關(guān)于模擬器的檢測方法,需要的朋友可以參考下

最近看到某客戶端有一個檢測模擬器的方法,我正常手機(jī)結(jié)果被判斷是模擬器了,很好奇,于是找了一下原因。

普遍檢測方法

public boolean isEmulator() {
    String url = "tel:" + "123456";
    Intent intent = new Intent();
    intent.setData(Uri.parse(url));
    intent.setAction(Intent.ACTION_DIAL);
    // 是否可以處理跳轉(zhuǎn)到撥號的 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;
}

這個代碼檢測模擬器有兩個問題:

1、撥號檢測,Android10.0及以上均為false

2、Build.SERIAL,Android8.0以上均為unknown

這導(dǎo)致8.0以上系統(tǒng)均會被誤判

推薦模擬器檢測方法

設(shè)備信息檢測

private static final String[] known_numbers = {"15555215554", "15555215556", "15555215558", "15555215560", "15555215562", "15555215564", "15555215566", "15555215568", "15555215570", "15555215572", "15555215574", "15555215576", "15555215578", "15555215580", "15555215582", "15555215584",};
private boolean detectEmulator() {
        if (Build.FINGERPRINT.startsWith("generic") || Build.FINGERPRINT.startsWith("unknown")
                || 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)) {
            return true;
        }
        if (Build.PRODUCT.equals("sdk") || Build.PRODUCT.equals("sdk_x86")
                || Build.PRODUCT.equals("vbox86p") || Build.PRODUCT.equals("emulator")) {
            return true;
        }
        if (Build.BOARD == null) {
            return true;
        }
        if (Build.BOARD.equals("unknown")
                || Build.BOARD.contains("android")
                || Build.BOARD.contains("droid")) {
            return true;
        }
        if (Build.DEVICE == null) {
            return true;
        }
        if (Build.DEVICE.equals("unknown")
                || Build.DEVICE.contains("android")
                || Build.DEVICE.contains("droid")) {
            return true;
        }
        if (Build.HARDWARE == null) {
            return true;
        }
        if (Build.HARDWARE.equals("goldfish")
                || Build.HARDWARE.equals("ranchu")
                || Build.HARDWARE.contains("ranchu")) {
            return true;
        }
        if (Build.BRAND == null) {
            return true;
        }
        if (Build.BRAND.startsWith("generic") && Build.DEVICE.startsWith("generic")) {
            return true;
        }
        if (Build.MANUFACTURER.equals("unknown")) {
            return true;
        }
        if (Build.MANUFACTURER.equals("Genymotion")) {
            return true;
        }
        if ((Build.BRAND.startsWith("generic") && Build.DEVICE.startsWith("generic"))
                || "google_sdk".equals(Build.PRODUCT)) {
            return true;
        }
        if (Build.PRODUCT == null) {
            return true;
        }
        if (Build.PRODUCT.equals("sdk")
                || Build.PRODUCT.equals("sdk_x86")
                || Build.PRODUCT.equals("vbox86p")
                || Build.PRODUCT.equals("emulator")) {
            return true;
        }
        if (Build.HARDWARE.equals("goldfish")
                || Build.HARDWARE.equals("ranchu")) {
            return true;
        }
        if (Build.FINGERPRINT.startsWith("generic")
                || Build.FINGERPRINT.startsWith("unknown")
                || 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)) {
            return true;
        }
        if (Build.PRODUCT == null) {
            return true;
        }
        if (Build.PRODUCT.equals("sdk")
                || Build.PRODUCT.equals("sdk_x86")
                || Build.PRODUCT.equals("vbox86p")
                || Build.PRODUCT.equals("emulator")) {
            return true;
        }
        if (Build.HARDWARE.equals("goldfish")
                || Build.HARDWARE.equals("ranchu")) {
            return true;
        }
        if (new File("/dev/socket/qemud").exists()
                || new File("/dev/qemu_pipe").exists()) {
            return true;
        }
        try {
            TelephonyManager telephonyManager = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
            if (telephonyManager != null) {
                String deviceId = telephonyManager.getDeviceId();
                List<String> knownNumbers = Arrays.asList(known_numbers);
                if (knownNumbers.contains(deviceId)) {
                    return true;
                }
            }
        } catch (Exception e) {
        }
        return false;
    }

上述代碼使用了多種方法來檢測設(shè)備是否為模擬器,這些方法包括:

  • 檢測 Build.FINGERPRINT 是否以 “generic” 或 “unknown” 開頭
  • 檢測 Build.MODEL 是否包含 “google_sdk”、“Emulator” 或 “Android SDK built for x86”
  • 檢測 Build.MANUFACTURER 是否為 “Genymotion”
  • 檢測 Build.PRODUCT 是否為 “sdk”、“sdk_x86”、“vbox86p” 或 “emulator”
  • 檢測 Build.BOARD 是否為 “unknown” 或包含 “android” 或 “droid”
  • 檢測 Build.DEVICE 是否為 “unknown” 或包含 “android” 或 “droid”
  • 檢測 Build.HARDWARE 是否為 “goldfish”、“ranchu” 或包含 “ranchu”
  • 檢測 Build.BRAND 是否以 “generic” 開頭,且 Build.DEVICE 以 “generic” 開頭
  • 檢測 Build.PRODUCT 是否為 “google_sdk”
  • 檢測是否存在文件 “/dev/socket/qemud” 或 “/dev/qemu_pipe”
  • 檢測設(shè)備的電話號碼是否為已知的模擬器電話號碼

上述方法都是基于固件信息的判斷,通過測試發(fā)現(xiàn)很多模擬器都失效,參考網(wǎng)上的教程,還有藍(lán)牙、光線傳感器、cpu檢測,配合上面的固件信息,基本可以搞定大部分模擬器。

藍(lán)牙檢測方法

public boolean notHasBlueTooth() {
    BluetoothAdapter ba = BluetoothAdapter.getDefaultAdapter();
    if (ba == null) {
        return true;
    } else {
        // 如果有藍(lán)牙不一定是有效的。獲取藍(lán)牙名稱,若為null 則默認(rèn)為模擬器
        String name = ba.getName();
        if (TextUtils.isEmpty(name)) {
            return true;
        } else {
            return false;
        }
    }
}

光傳感器檢測方法

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;
    }
}

CPU檢測方法

public static boolean checkIsNotRealPhone() {
    String cpuInfo = readCpuInfo();
    if ((cpuInfo.contains("intel") || cpuInfo.contains("amd"))) {
        return true;
    }
    return false;
}
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系統(tǒng)的更新,模擬器的增多,我們需要具體研究對應(yīng)的一些變動來更新上述代碼。

我們檢測要注意一個問題,不一定能檢測出所有的模擬器,但是一定不能誤殺真機(jī)。

總結(jié)

建議 首先使用傳感器進(jìn)行可疑性判斷

藍(lán)牙, wifi, 電池 可以作為 輔助數(shù)據(jù)進(jìn)行監(jiān)聽。

附加傳感器類型代碼

public String getSensorTypeName(int type) {
        switch (type) {
            case Sensor.TYPE_ACCELEROMETER:
                return "加速度傳感器";
            case Sensor.TYPE_GYROSCOPE:
                return "陀螺儀傳感器";
            case Sensor.TYPE_LIGHT:
                return "環(huán)境光線傳感器";
            case Sensor.TYPE_MAGNETIC_FIELD:
                return "電磁場傳感器";
            case Sensor.TYPE_ORIENTATION:
                return "方向傳感器";
            case Sensor.TYPE_PRESSURE:
                return "壓力傳感器";
            case Sensor.TYPE_PROXIMITY:
                return "距離傳感器";
            case Sensor.TYPE_TEMPERATURE:
                return "溫度傳感器";
            case Sensor.TYPE_GRAVITY:
                return "重場傳感器";
            case Sensor.TYPE_LINEAR_ACCELERATION:
                return "線性加速度傳感器";
            case Sensor.TYPE_ROTATION_VECTOR:
                return "旋轉(zhuǎn)矢量傳感器";
            case Sensor.TYPE_RELATIVE_HUMIDITY:
                return "濕度傳感器";
            case Sensor.TYPE_AMBIENT_TEMPERATURE:
                return "溫度傳感器";
            case Sensor.TYPE_GAME_ROTATION_VECTOR:
                return "游戲旋轉(zhuǎn)矢量傳感器";
            case Sensor.TYPE_STEP_COUNTER:
                return "計步器";
            case Sensor.TYPE_GEOMAGNETIC_ROTATION_VECTOR:
                return "地磁旋轉(zhuǎn)矢量傳感器";
            case Sensor.TYPE_SIGNIFICANT_MOTION:
                return "特殊動作觸發(fā)傳感器";
            default:
                return "未知傳感器";
        }
    }

到此這篇關(guān)于Android模擬器最新檢測方法詳解的文章就介紹到這了,更多相關(guān)Android模擬器檢測內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論