一、通过 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;// HARDWAREjstring 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);// FINGERPRINTjstring 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);// MODELjstring 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);// MANUFACTURERjstring 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);// PRODUCTjstring 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   DEVICEjstring 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.qemuFile::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.modelFile::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.abiFile::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");}}
}

安卓逆向环境检测--模拟器相关推荐

  1. 安卓逆向_20 --- 模拟器检测、反调试检测、ELF动态调试、__libc_init 下断

    From( 模拟器检测实战分析 ):https://www.bilibili.com/video/BV1UE411A7rW?p=65 怎样过 app 的模拟器检测:https://bbs.pediy. ...

  2. 安卓逆向——雷电模拟器安卓安装Xposed问题

    环境: 模拟器:雷电 4.0.43版本 安卓版本:7.1.2  x86 Xposed :4.0 以上 直接安装 Xposed 会,提示这类错误(这里测试版本有误,安卓5 重启会卡死)         ...

  3. 安卓逆向之模拟器检测

    很久没更新,给大家来一个过模拟器方面的讲解 有问题可+v:13140310004 最近疫情又严重了,大家注意防范 简单介绍模拟检测的原理 模拟器检测,顾名思义,软件.手游等不能运行在模拟器上面. 灰黑 ...

  4. js逆向、安卓逆向教程

    JS基础 提示信息 - 吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn 安卓逆向 1.模拟器环境搭建 Magisk 是一套用于定制 Android 的开源软件,支 ...

  5. BUUCTF-Reverse:helloword + findit(安卓逆向)

    Helloword+findit Helloword findit 这两道题是安卓逆向的题目~ 第一次接触安卓逆向的题目~ 工具下载: https://down.52pojie.cn/Tools/ H ...

  6. 安卓逆向_24( 一 ) --- Hook 框架 frida( Hook Java层 和 so层) )

    From:Hook 神器家族的 Frida 工具使用详解:https://blog.csdn.net/FlyPigYe/article/details/90258758 详解 Hook 框架 frid ...

  7. 安卓逆向_21 --- Java层和so层的反调试( IDA 动态调试 JNI_OnLoad、init_array下断)

    1. 安卓程序动态调试条件 安卓程序动态调试条件 ( 2个满足1个即可 ): 1. 在 AndroidMainfest.xml ---> application 标签下,设置或者添加属性 and ...

  8. 安卓逆向_10 --- Log 日志的插入和分析、toast方法、栈跟踪

    From:https://blog.csdn.net/weixin_42680210/article/details/90384358 在安卓逆向中,常常用到 栈跟踪.toast方法.Log日志的插入 ...

  9. 安卓逆向_3 --- 篡改apk名称和图标、修改包名实现应用分身、修改资源去广告、去除re管理器广告

    From:https://www.bilibili.com/video/BV1UE411A7rW?p=7 Android 中 adb shell dumpsys 相关命令:https://blog.c ...

最新文章

  1. linux两个文件修改主机名
  2. 使用 Truffle Develop 和 console
  3. 【H2 Database】Server模式启动
  4. STM32串口的使用(原理、结构体、库函数、串口发送字符(串)、重定向printf串口发送、串口中断接收控制灯)
  5. java android 数组_Android开发基础之Java 数组
  6. poj2109 Power of Cryptography
  7. mysql表空间名字查询_数据库表空间信息查询
  8. 分段函数if语句_S0A1 Geogebra新手课:分段函数的绘制,以一次函数方案选择为例...
  9. mac配置php mysql_mac配置Apache+php+mysql
  10. 关于PHP的工作流引擎
  11. Mybatis案例超详解
  12. 提取rosbag中的图像话题存为本地图像
  13. librdkafka问题小记
  14. 阿里云首席安全科学家吴翰清的思考:弹性安全网络,构建下一代安全的互联网
  15. html logo写法,教你用CSS3打造HTML5的Logo
  16. 腾讯扩容 php环境失效,腾讯云硬盘扩容挂载应该怎么办?
  17. 计算机一级评分原理,计算机一级Word和Excel操作自动评分的实现探究
  18. 区块链技术涉及哪些编程语言?
  19. html雾霾蓝色号rgb,新型流行色—雾霾蓝
  20. dr优先级默认_DR和BDR优先级

热门文章

  1. Netty对象池技术Recycler解析
  2. jquery.flot图表插件使用
  3. memblock初始化过程中fdt mem处理
  4. TLS/SSL 协议详解(6) SSL 数字证书的一些细节1
  5. 系统安装完成后盘符不是C盘
  6. c语言课程设计 湖南工程学院 小学生cai 系统 2013,研究报告C语言课程设计小学生心算CAI系统报告书.doc...
  7. java 千分之一的概率,世界上几十亿人,两个人相遇的概率为千分之一
  8. A Handy Guide To Handling Handles
  9. Android Studio 4.0 集成环信sdk EaseUI全纪录
  10. document.body 属性