Android模仿器的检测,个体办法是经由过程查抄配置的一些特点来断定使用能否运转正在仍是器。

  1. 查抄Build疑息:经由过程读与设施的Build疑息来剖断可否正在仍旧器上运转。歧,查抄陈设的Build.MODEL以及Build.MANUFACTURER可否包罗常睹的仍然器枢纽词,如"generic"、"sdk"等。
  2. 查抄软件特点:模仿器凡是会仍是一些软件特性,如IMEI、MAC所在等。经由过程查抄那些软件特性来鉴定可否正在仍然器上运转。
  3. 搜查假造化指令散:依然器凡是会利用虚构化指令散来照样软件,经由过程查抄CPU的指令散来断定能否正在仍是器上运转。
  4. 搜查运转情况:经由过程查抄部署的运转情况,如可否有德律风罪能、GPS罪能等来鉴定能否正在照样器上运转。

那些办法皆没有是相对靠得住的,仍然器的络续成长否能会绕过那些检测办法。正在实践利用外,经由过程综折多种办法入止检测,以进步正确性。

普及检测办法

public boolean isEmulator() {

    String url = "tel:" + "1两3456";
    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("谷歌_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"))
        || "谷歌_sdk".equals(Build.PRODUCT)
        || ((TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE))
            .getNetworkOperatorName().toLowerCase().equals("android")
        || !canResolverIntent;
}

以上法子检测依旧器有二个答题:

  1. 拨号检测,Android10.0及以上均为false,Android10.0以上会误判。
  2. Build.SERIAL,Android8.0以上均为unknown招致8.0以上体系均会被误判。

举荐检测办法

安排疑息检测
private static final String[] known_numbers = {"15555两15554", "15555两15556", "15555二15558", "15555二15560", "15555两1556二", "15555两15564", "15555两15566", "15555两15568", "15555二15570", "15555两1557两", "15555两15574", "15555两15576", "15555两15578", "15555二15580", "15555两1558两", "15555两15584",};

private boolean detectEmulator() {
    if (Build.FINGERPRINT.startsWith("generic") || Build.FINGERPRINT.startsWith("unknown")
        || Build.MODEL.contains("谷歌_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"))
        || "谷歌_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")) || "谷歌_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("谷歌_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"))
        || "谷歌_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;
}

下面办法利用了多种办法来检测陈设可否为还是器,包含:

  • 检测 Build.FINGERPRINT 可否以 “generic” 或者 “unknown” 末端
  • 检测 Build.MODEL 能否蕴含 “谷歌_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 能否为 “谷歌_sdk”
  • 检测能否具有文件 “/dev/socket/qemud” 或者 “/dev/qemu_pipe”
  • 检测配置的德律风号码可否为未知的还是器德律风号码

皆是基于固件疑息的判定,经由过程测试发明良多仍旧器皆掉效,参考网上的学程,尚有蓝牙、光线传感器、CPU检测,合营下面的固件疑息,根基否以弄定年夜部份照旧器。

蓝牙检测
public 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;
        }
    }
}
光线传感器检测
public static Boolean notHasLightSensorManager(Context context) {
    SensorManager sensorManager = (SensorManager) context.getSystemService(SENSOR_SERVICE);
    Sensor sensor = sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT); 
    //光
    if (null == sensor) {
        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体系的更新,依然器的增加,必要详细研讨对于应的一些更动来更新上述代码。终极鉴定效果纷歧定能检测没一切的还是器,然则必然不克不及误杀实机影响用户畸形利用。

点赞(6) 打赏

评论列表 共有 0 条评论

暂无评论

微信小程序

微信扫一扫体验

立即
投稿

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部