近期需要鉴定设备是否是模拟器,从网上看了下大部分的方法是不准确的,也可能是测试环境的原因, 这些包括
1.检测模拟器的特有文件
2.检测设备的驱动
3.检测手机的一些硬件
4.检测手机的运营商家
5.检测模拟器的默认号码
6.检测设备的imsi ID
代码如下
public class MainActivity extends Activity {
private TextView tv;
private static String[] known_files = {
"/system/lib/libc_malloc_debug_qemu.so", "/sys/qemu_trace",
"/system/bin/qemu-props"};
private static String[] known_pipes = {
"/dev/socket/qemud",
"/dev/qemu_pipe"
};
private static String[] known_numbers = {"15555215554", "15555215556",
"15555215558", "15555215560", "15555215562", "15555215564",
"15555215566", "15555215568", "15555215570", "15555215572",
"15555215574", "15555215576", "15555215578", "15555215580",
"15555215582", "15555215584",};
private static String[] known_imsi_ids = {"310260000000000", // 默认的 imsi id
"460076067205994",// 夜神模拟器
"460001067113753"// 雷电模拟器
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_PHONE_STATE}, 10002121);
}
tv = findViewById(R.id.main_text);
tv.setText("检测模拟器上特有的几个文件\n");
CheckEmulatorFiles();
tv.append("\n检测驱动文件内容\n");
checkQEmuDriverFile();
tv.append("\n检测手机上的一些硬件信息\n");
CheckEmulatorBuild();
tv.append("\n检测手机运营商家\n");
CheckOperatorNameAndroid(this);
tv.append("\n检测模拟器默认的电话号码\n");
CheckPhoneNumber();
tv.append("\n检测imsi id\n");
CheckImsiIDS();
}
// 检测模拟器上特有的几个文件
public Boolean CheckEmulatorFiles() {
for (int i = 0; i < known_files.length; i++) {
String file_name = known_files[i];
File qemu_file = new File(file_name);
if (qemu_file.exists()) {
tv.append("Emulator\n");
return true;
}
}
tv.append("Not Find Emulator Files\n");
return false;
}
//检测手机上的一些硬件信息
public Boolean CheckEmulatorBuild() {
String BOARD = android.os.Build.BOARD;
String BOOTLOADER = android.os.Build.BOOTLOADER;
String BRAND = android.os.Build.BRAND;
String DEVICE = android.os.Build.DEVICE;
String HARDWARE = android.os.Build.HARDWARE;
String MODEL = android.os.Build.MODEL;
String PRODUCT = android.os.Build.PRODUCT;
if (BOARD == "unknown" || BOOTLOADER == "unknown"
|| BRAND == "generic" || DEVICE == "generic"
|| MODEL == "sdk" || PRODUCT == "sdk"
|| HARDWARE == "goldfish") {
tv.append("Emulator\n");
return true;
}
tv.append("Not Find Emulator by EmulatorBuild\n");
return false;
}
//检测手机运营商家
@SuppressLint("WrongConstant")
public boolean CheckOperatorNameAndroid(Context context) {
String szOperatorName = ((TelephonyManager) context.getSystemService("phone")).getNetworkOperatorName();
if (szOperatorName.toLowerCase().equals("android") == true) {
tv.append("Emulator\n");
return true;
}
tv.append("Not Find Emulator by OperatorName\n");
return false;
}
// 检测驱动文件内容
// 读取文件内容,然后检查已知QEmu的驱动程序的列表
public Boolean checkQEmuDriverFile() {
File driver_file = new File("/proc/tty/drivers");
if (driver_file.exists() && driver_file.canRead()) {
byte[] data = new byte[1024]; //(int)driver_file.length()
try {
InputStream inStream = new FileInputStream(driver_file);
inStream.read(data);
inStream.close();
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
String driver_data = new String(data);
for (String known_qemu_driver : known_pipes) {
if (driver_data.indexOf(known_qemu_driver) != -1) {
tv.append("Emulator\n");
return true;
}
}
}
tv.append("Not Find known_qemu_drivers\n");
return false;
}
// 检测模拟器默认的电话号码
@SuppressLint("MissingPermission")
public Boolean CheckPhoneNumber() {
TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
String phonenumber = telephonyManager.getLine1Number();
for (String number : known_numbers) {
if (number.equalsIgnoreCase(phonenumber)) {
tv.append("Emulator\n");
return true;
}
}
tv.append("Not Find PhoneNumber\n");
return false;
}
// 检测imsi id是不是“310260000000000”
public Boolean CheckImsiIDS() {
TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
@SuppressLint("MissingPermission") String imsi_ids = telephonyManager.getSubscriberId();
for (String know_imsi : known_imsi_ids) {
if (know_imsi.equalsIgnoreCase(imsi_ids)) {
tv.append("Emulator\n");
return true;
}
}
tv.append("Not Find imsi ids\n");
return false;
}
}
其中方法1在部分模拟器上生效,2.3.4.5全部失效,6只有在知道模拟器的imsi ID时,将其放入比对的数组中才会生效
雷电模拟器的运行结果如下
夜神模拟器的如下
联想A8手机如下
VIVO_X21如下