赞
踩
一、通过 android/os/Build 类检测虚拟机
-
- UNEXPORT bool AntiEmulator::check_Build(JNIEnv *env) {
- char* sig = "Ljava/lang/String;";
- Field* field = new Field("android/os/Build", env);
- bool ret = false;
-
- // HARDWARE
- jstring HARDWARE = field->get_static_jstring_field("HARDWARE", sig);
- char *cHARDWARE = const_cast<char *>(env->GetStringUTFChars(HARDWARE, NULL));
- if (Str::strstr(cHARDWARE, "vbox86") != nullptr ||
- Str::strstr(cHARDWARE, "nox") != nullptr ||
- Str::strstr(cHARDWARE, "ttVM_x86") != nullptr ) {//是模拟器 不通过
- LOGI("check_Build => check FINGERPRINT find emulator => FINGERPRINT:%s", cHARDWARE);
- ret = true;
- }
- LOGI("HARDWARE:%s", cHARDWARE);
-
- // FINGERPRINT
- jstring FINGERPRINT = field->get_static_jstring_field("FINGERPRINT", sig);
- char *cFINGERPRINT = const_cast<char *>(env->GetStringUTFChars(FINGERPRINT, NULL));
- if (Str::strstr(cFINGERPRINT, "Android") != nullptr || Str::strstr(cFINGERPRINT, "unknown") != nullptr ||
- Str::strstr(cFINGERPRINT, "generic/sdk/generic") != nullptr ||
- Str::strstr(cFINGERPRINT, "generic_x86/sdk_x86/generic_x86") != nullptr ||
- Str::strstr(cFINGERPRINT, "Andy") != nullptr ||
- Str::strstr(cFINGERPRINT, "ttVM_Hdragon") != nullptr ||
- Str::strstr(cFINGERPRINT, "generic/google_sdk/generic") != nullptr ||
- Str::strstr(cFINGERPRINT, "vbox86p") != nullptr ||
- Str::strstr(cFINGERPRINT, "generic/vbox86p/vbox86p") != nullptr) {//是模拟器 不通过
- LOGI("check_Build => check FINGERPRINT find emulator => FINGERPRINT:%s", cFINGERPRINT);
- ret = true;
- }
- LOGI("FINGERPRINT:%s", cFINGERPRINT);
-
- // MODEL
- jstring MODEL = field->get_static_jstring_field("MODEL", sig);
- char *cMODEL = const_cast<char *>(env->GetStringUTFChars(MODEL, NULL));
- if (Str::strstr(cMODEL, "google_sdk") != nullptr || Str::strstr(cMODEL, "Emulator") != nullptr ||
- Str::strstr(cMODEL, "Droid4X") != nullptr ||
- Str::strstr(cMODEL, "TiantianVM") != nullptr ||
- Str::strstr(cMODEL, "Andy") != nullptr ||
- Str::strstr(cMODEL, "Android SDK built for x86_64") != nullptr ||
- Str::strstr(cMODEL, "Android SDK built for x86") != nullptr) {//是模拟器 不通过
- LOGI("check_Build => check MODEL find emulator => MODEL:%s", cMODEL);
- ret = true;
- }
- LOGI("MODEL:%s", cMODEL);
-
- // MANUFACTURER
- jstring MANUFACTURER = field->get_static_jstring_field("MANUFACTURER", sig);
- char *cMANUFACTURER = const_cast<char *>(env->GetStringUTFChars(MANUFACTURER, NULL));
- if (Str::strstr(cMANUFACTURER, "Genymotion") != nullptr ||
- Str::strstr(cMANUFACTURER, "Andy") != nullptr ||
- Str::strstr(cMANUFACTURER, "nox") != nullptr ||
- Str::strstr(cMANUFACTURER, "TiantianVM") != nullptr) {//是模拟器 不通过
- LOGI("check_Build => check MANUFACTURER find emulator => MANUFACTURER:%s", cMANUFACTURER);
- ret = true;
- }
- LOGI("MANUFACTURER:%s", cMANUFACTURER);
-
- // PRODUCT
- jstring PRODUCT = field->get_static_jstring_field("PRODUCT", sig);
- char *cPRODUCT = const_cast<char *>(env->GetStringUTFChars(PRODUCT, NULL));
- if (Str::strstr(cPRODUCT, "sdk") != nullptr ||
- Str::strstr(cPRODUCT, "Andy") != nullptr ||
- Str::strstr(cPRODUCT, "Droid4X") != nullptr ||
- Str::strstr(cPRODUCT, "nox") != nullptr ||
- Str::strstr(cPRODUCT, "vbox86p") != nullptr ) {//是模拟器 不通过
- LOGI("check_Build => check PRODUCT find emulator => PRODUCT:%s", cPRODUCT);
- ret = true;
- }
- LOGI("PRODUCT:%s", cPRODUCT);
-
- // BRAND DEVICE
- jstring BRAND = field->get_static_jstring_field("BRAND", sig);
- char *cBRAND = const_cast<char *>(env->GetStringUTFChars(BRAND, NULL));
- jstring DEVICE = field->get_static_jstring_field("DEVICE", sig);
- char *cDEVICE = const_cast<char *>(env->GetStringUTFChars(DEVICE, NULL));
- if ((Str::strstr(cBRAND, "generic") != nullptr && Str::strstr(cDEVICE, "generic") == cDEVICE) ||
- Str::strstr(cBRAND, "Andy") != nullptr ||
- Str::strstr(cBRAND, "Droid4X") != nullptr ||
- Str::strstr(cBRAND, "nox") != nullptr ||
- Str::strstr(cBRAND, "vbox86p") != nullptr ) {//是模拟器 不通过
- LOGI("check_Build => check BRAND find emulator => BRAND:%s", cBRAND);
- LOGI("check_Build => check DEVICE find emulator => DEVICE:%s", cDEVICE);
- ret = true;
- }
- LOGI("BRAND:%s", cBRAND);
- LOGI("DEVICE:%s", cDEVICE);
- env->ReleaseStringUTFChars(HARDWARE, cHARDWARE);
- env->ReleaseStringUTFChars(FINGERPRINT, cFINGERPRINT);
- env->ReleaseStringUTFChars(MODEL, cMODEL);
- env->ReleaseStringUTFChars(MANUFACTURER, cMANUFACTURER);
- env->ReleaseStringUTFChars(PRODUCT, cPRODUCT);
- env->ReleaseStringUTFChars(BRAND, cBRAND);
- env->ReleaseStringUTFChars(DEVICE, cDEVICE);
- return ret;
- }

二、通过检查prop.build文件中的字段来判断是否为模拟器
-
- UNEXPORT bool AntiEmulator::check_prop() {
- char tmp[1024] = {0};
-
- // ro.kernel.qemu
- File::read_property("ro.kernel.qemu", reinterpret_cast<char *>(&tmp));
- if (Str::strcmp(tmp, "1") == 0){
- return true;
- }
- LOGI("check_prop ro.kernel.qemu -> %s", tmp);
-
- // ro.product.model
- File::read_property("ro.product.model", reinterpret_cast<char *>(&tmp));
- if (Str::strstr(tmp, "sdk") != nullptr || Str::strstr(tmp, "Android SDK") != nullptr){
- return true;
- }
- LOGI("check_prop ro.product.model -> %s", tmp);
-
- // ro.product.cpu.abi
- File::read_property("ro.product.cpu.abi", reinterpret_cast<char *>(&tmp));
- if (Str::strcmp(tmp, "x86") == 0){
- return true;
- }
- LOGI("check_prop ro.product.cpu.abi -> %s", tmp);
- return false;
- }

三、检查是否存在一些模拟器框架文件
-
- UNEXPORT void AntiEmulator::check_file() {
- char *(path[]) = {
- "/system/bin/androVM-prop", //检测androidVM
- "/system/bin/microvirt-prop", //检测逍遥模拟器--新版本找不到特征
- "/system/lib/libdroid4x.so", //检测海马模拟器
- "/system/bin/windroyed", //检测文卓爷模拟器
- "/system/bin/nox-prop", //检测夜神模拟器--某些版本找不到特征
- "/system/lib/libnoxspeedup.so",//检测夜神模拟器
- "/system/bin/ttVM-prop", //检测天天模拟器
- "/data/.bluestacks.prop", //检测bluestacks模拟器 51模拟器
- "/system/bin/duosconfig", //检测AMIDuOS模拟器
- "/system/etc/xxzs_prop.sh", //检测星星模拟器
- "/system/etc/mumu-configs/device-prop-configs/mumu.config", //网易MuMu模拟器
- "/system/priv-app/ldAppStore", //雷电模拟器
- "/system/bin/ldinit", //雷电模拟器
- "/system/bin/ldmountsf", //雷电模拟器
- "/system/app/AntStore", //小蚁模拟器
- "/system/app/AntLauncher", //小蚁模拟器
- "vmos.prop", //vmos虚拟机
- "fstab.titan", //光速虚拟机
- "init.titan.rc", //光速虚拟机
- "x8.prop", //x8沙箱和51虚拟机
- "/system/lib/libc_malloc_debug_qemu.so", //AVD QEMU
- "/system/bin/microvirtd",
- "/dev/socket/qemud",
- "/dev/qemu_pipe"};
- for (int i = 0; i < sizeof(path) / sizeof(char*); i++){
- if (Syscall::check_file_or_dir_exists(path[i])){
- LOGI("check_file %s file existing", path[i]);
- // TODO 风险
-
- }
- }
- }

四、检测cpu温度,一般模拟器没有此文件:/sys/class/thermal/thermal_zone...
-
- UNEXPORT void AntiEmulator::check_cpu_temp() {
- DIR *dirptr = NULL; //当前手机的温度检测,手机下均有thermal_zone文件
- int count = 0;
- struct dirent *entry;
- if ((dirptr = opendir("/sys/class/thermal/")) != NULL) {
- while (entry = readdir(dirptr)) {
- if (!strcmp(entry->d_name, ".") || !strcmp(entry->d_name, "..")) {
- continue;
- }
- char *tmp = entry->d_name;
- if (Str::strstr(tmp, "thermal_zone") != NULL) {
- count++;
- }
- }
- closedir(dirptr);
- } else {
- LOGE("AntiEmulator::check_cpu_temp open thermal fail");
- }
- if (count == 0){
- // TODO 此时为模拟器
- }
- LOGI("AntiEmulator::check_cpu_temp count=%d", count);
- }

五、读取 /proc/cpuinfo,真机一般会获取到hardware
- UNEXPORT void AntiEmulator::check_cpu() {
- string str = Syscall::readFile((char*)"/proc/cpuinfo");
- char* split = (char*)"\n";
- string strs = str + split; // 在字符串末尾也加入分隔符,方便截取最后一段
- size_t pos = strs.find(split);
- while (pos != strs.npos)
- {
- string temp = strs.substr(0, pos);
- if (Str::strstr(const_cast<char *>(temp.c_str()), "Hardware") != NULL){
- LOGI("AntiEmulator::check_cpu find %s", temp.c_str());
- return;
- }
- //去掉已分割的字符串,在剩下的字符串中进行分割
- strs = strs.substr(pos + 1, strs.size());
- pos = strs.find(split);
- }
- // TODO 没找到 Hardware,说明为模拟器
-
- }

六、读取 /proc/version,模拟器一般有qemu,tencent
- UNEXPORT void AntiEmulator::check_version() {
- string str = Syscall::readFile((char*)"/proc/version");
- char* split = (char*)"\n";
- string strs = str + split; // 在字符串末尾也加入分隔符,方便截取最后一段
- size_t pos = strs.find(split);
- while (pos != strs.npos)
- {
- string temp = strs.substr(0, pos);
- if (Str::strstr(const_cast<char *>(temp.c_str()), "qemu") != NULL ||
- Str::strstr(const_cast<char *>(temp.c_str()), "qemu") != NULL){
- // TODO 发现模拟器
- LOGI("AntiEmulator::check_version find %s", temp.c_str());
- return;
- }
- //去掉已分割的字符串,在剩下的字符串中进行分割
- strs = strs.substr(pos + 1, strs.size());
- pos = strs.find(split);
- }
- }

七、检查传感器个数,少于20个认为是模拟器
- UNEXPORT void AntiEmulator::check_sensor(JNIEnv *env) {
- jobject context = AntiEmulator::getApplicationContext(env);
- LOGI("check_sensor context %p", context);
- jstring sensor = env->NewStringUTF("sensor");
- jobject objService = Method::callMethodObject(env, context,
- "android/content/Context",
- "getSystemService",
- "(Ljava/lang/String;)Ljava/lang/Object;",
- sensor);
- env->DeleteLocalRef(sensor);
- LOGI("check_sensor objService %p", objService);
- jobject sensorlist = Method::callMethodObject(env, objService,
- "android/hardware/SensorManager",
- "getSensorList",
- "(I)Ljava/util/List;",
- -1);
- LOGI("check_sensor sensorlist %p", sensorlist);
- jint len = Method::callMethodInt(env, sensorlist, "java/util/List", "size", "()I");
- LOGI("check_sensor sensorlist len=%d", len);
- if (len < 20){
- // todo 传感器少于20 认为当前环境为非真机环境
- }
-
- }

八、检查摄像头个数
- UNEXPORT void AntiEmulator::check_camera(JNIEnv *env) {
- jobject context = AntiEmulator::getApplicationContext(env);
- LOGI("check_camera context %p", context);
- jstring camera = env->NewStringUTF("camera");
- jobject objService = Method::callMethodObject(env, context,
- "android/content/Context",
- "getSystemService",
- "(Ljava/lang/String;)Ljava/lang/Object;",
- camera);
- env->DeleteLocalRef(camera);
- LOGI("check_camera objService %p", objService);
- jobjectArray cameralist = static_cast<jobjectArray>(Method::callMethodObject(env, objService,
- "android/hardware/camera2/CameraManager",
- "getCameraIdList",
- "()[Ljava/lang/String;"));
- LOGI("check_camera cameralist %p", cameralist);
- int len = env->GetArrayLength(cameralist);
- LOGI("check_camera cameralist len %d", len);
- if (len < 2){
- // todo 摄像头少于2 认为当前环境为非真机环境
-
- }
- // for (int i = 0; i < len + 1; i++){
- // jobject ca = env->GetObjectArrayElement(cameralist, i);
- // LOGI("check_camera camera -> %d : %p", i, ca);
- // }
-
- }

九、检查mounts文件,检测里面是否包含docker关键字 ,防止一些云手机搞虚拟化,通过使用docker进行挂载
- UNEXPORT void AntiEmulator::check_mounts() {
- char *(path[]) = {"/proc/mounts", "/proc/self/mountstats", "/proc/self/mountinfo"};
- for (int i = 0; i < sizeof(path) / sizeof(char*); i++){
- string status = Syscall::readFile(path[i]);
- if (status == "null"){
- break;
- }
- size_t pos = status.find("\n");
- while (pos != status.npos)
- {
- string temp = status.substr(0, pos);
- if (Str::strstr(const_cast<char *>(temp.c_str()), (char*)"docker") != nullptr){
- //TODO 发现docker, 可能存在云手机挂载docker
-
- }
- //去掉已分割的字符串,在剩下的字符串中进行分割
- status = status.substr(pos + 1, status.size());
- pos = status.find("\n");
- }
- }
- }

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。