Android虚拟机、模拟器识别

源码地址:https://github.com/ysrc/Anti-Emulator (如果你也和我当初一样在so文件调用和生成的相关问题上出现了问题,欢迎留言交流)

在我们开发的App中,我们可能不希望它被运行在模拟器上,所以我们需要一种手段去检测模拟器,当当前设备被检测为模拟器时,我们就直接结束掉App进程。目前常见的检测模拟器手段主要被应用在游戏领域和加固领域。

通常我们去检测模拟器时会利用一些Android系统的运行特征,但这些方式比较复杂也比较难以理解,需要对Android系统有比较深入的了解,如何有一种办法比较高容错率并且检测效果还不错呢,之前,一般的检测模拟器的手段都是通过检测一些系统特定属性,如检测当前设备手机号,设备DeviceId,dev下是否存在socket/qemud和qemu_pipe两个文件,以及build.prop下的一些属性,在分析某赚软件时,它正是使用的这种检测方式,但是当当前设备被root后,就可以通过安装一些修改设备信息的软件来躲避这种检测方式,最近在看到某款游戏的检测手段时,看到了基于文件特征的检测方式,在这个基础上我又加了一些检测方式用来判断模拟器。

目前市面上流行的Android模拟器主要有Genymotion,天天模拟器,夜神模拟器,海马玩模拟器,畅玩模拟器,itools模拟器,逍遥模拟器,文卓爷模拟器,原生Android模拟器,BlueStacks,我们都知道除了原生模拟器之外,大部分Android模拟器都是基于VirtualBox的,这是重要的检测点之一,其次相比于手机,模拟器上少了一些重要特征,如蓝牙功能,温度传感器等等,这些都是可以用来检测模拟器的依据,同时,每种定制版本的模拟器上,都会有一些它特有的可执行文件,如下是我在测试多种模拟器时收集的特征文件:

if (anti("/system/lib/libdroid4x.so")) {   //文卓爷
}
if (anti("/system/bin/windroyed")) {   //文卓爷
}
if (anti("/system/bin/microvirtd")) {  //逍遥
}
if (anti("/system/bin/nox-prop")) {  //夜神
}
if (anti("/system/bin/ttVM-prop")) { //天天模拟器
}

如上图,每个模拟器都编译了自己的动态库或是可执行文件,这些文件在手机上是不存在的,那么我们就可以以此来判断当前设备是否是模拟器,如何去检测该模拟器是否存在也很简单,anti函数如下:

int anti(char *res) {
   struct stat buf;
   
int result = stat(res, &buf) == 0 ? 1 : 0;
   
if (result) {
       LOGE("the %s is exist", res);
       
//    LOGE("this is a Emulator!!!");
   
}
   return result;
}

C提供了一个stat函数用来判断当前文件是否存在,如果执行成功则会返回0,使用这种检测手段就需要去收集大量的模拟器特征,在测试时,本人也碰到了一些问题,如检测这个文件时:

anti("/system/lib/libc_malloc_debug_qemu.so");
//cm,魔趣等基于aosp改版的系统上会存在libc_malloc_debug_qemu.so这个文件

我发现在一些debug版本的定制版系统上都存在这个文件,但测试了大量官方rom时都是没有问题的,所以这种方式的可靠度是不够高的,本人在这个判断的基础上再去判断了一次,如下:

if (anti("/system/lib/libc_malloc_debug_qemu.so")) {
   //cm,魔趣等基于aosp改版的系统上会存在libc_malloc_debug_qemu.so这个文件
   
if (access("/system/lib/libbluetooth_jni.so", F_OK) != 0) {
       LOGE("the bluetooth is not exist");
       
i++;//在误报情况下,再去检测当前设备是否存在蓝牙,不存在则判断为模拟器
   
}
}

目前市面上手机都是拥有蓝牙功能的,设备用于蓝牙功能时,我们发现系统的system/lib下有一个libbluetooth_jni.so文件,而这个文件在模拟器上是不存在的。

此类类似的特征文件还有一些,这里就不一个个列举了,除了检测这些固定文件外,我们还可以去检测一些模拟器特定的系统属性,在adb shell下输入getprop即可看到大量系统属性,所以这里就是通过一定系统属性去检测当前设备,如init.svc.vbox86-setup(基于VirtualBox的模拟器都会存在该属性):


通过一些测试我们可以过滤出一些比较敏感的信息,这些属性我们都可以用作检测模拟器的手段,在so里去获取这些属性也很简单,系统为我们提供了现成的api函数:

int anti2(char *res) {
   char buff[PROP_VALUE_MAX];
   
memset(buff, 0, PROP_VALUE_MAX);
   
int result =
           __system_property_get(res, (char *) &buff) > 0 ? 1 : 0; //返回命令行内容的长度
   
if (result != 0) {
       LOGE("the %s result is %s", res, buff);
       
//  LOGE("this is a Emulator!!!");
   
}
   return result;
}

通过__system_property_get我们就可以拿到该属性对应的值,值会保存在buff中。

当然了常规通过build.prop的检测方式也未尝一无是处,在检测模拟器时可以多维度去检测,在build.prop中一些字段也是比较重要的,如ro.product.name获取当前设备名称:

char *model = getDeviceInfo("ro.product.name");
if (!strcmp(model, "ChangWan")) {
} else if (!strcmp(model, "Droid4X")) {                     //0均为模拟器
} else if (!strcmp(model, "lgshouyou")) {
} else if (!strcmp(model, "nox")) {
} else if (!strcmp(model, "ttVM_Hdragon")) {
}

通过和一些常见模拟器设备名称进行对比,但是目前模拟器都可以手动去修改imei,deviceID,以及设备信息,这种检测方式效果不大。

本人测试时还发现,当试图去检测一些特殊信息,如当前设备cpu温度时,搜集了一些资料,提供了一个adb方式去获取,/sys/class/thermal/thermal_zoneX/temp(其中X是核心数量),但发现模拟器上没有thermal_zoneX目录,只有两个cooling_deviceX目录,因而有了一个新的判断依据,如下:

int checkTemp() {
   DIR *dirptr = NULL; //当前手机的温度检测,手机下均有thermal_zone文件
   
int i = 0;
   
struct dirent *entry;
   
if ((dirptr = opendir("/sys/class/thermal/")) != NULL) {
       while (entry = readdir(dirptr)) {
           // LOGE("%s  \n", entry->d_name);
           
if (!strcmp(entry->d_name, ".") || !strcmp(entry->d_name, "..")) {
               continue;
           
}
           char *tmp = entry->d_name;
           
if (strstr(tmp, "thermal_zone") != NULL) {
               i++;
           
}
       }
       closedir(dirptr);
   
} else {
       LOGE("open thermal fail");
   
}
   return i;
}

使用opendir函数去访问thermal目录,遍历该目录下所有目录,当不存在thermal_zone目录时,则判断当前设备为模拟器,最后放上几张模拟器测试图。

海马玩:

逍遥模拟器:

真机Nexus 5:

真机乐视2:

以上只是提供了一些检测模拟器的思路,真正的使用还需要大量的进行测试,提高检测的准确性和稳定性。

### 回答1: Android模拟器检测及对抗方法主要针对一些恶意软件或者安全测试工具会利用Android模拟器进行仿真攻击或者测试的现象进行针对性的处理。 在进行Android模拟器检测时,主要需要关注一些与真实Android设备不同的特征,例如与硬件相关的参数、系统属性或者程序运行环境等等。 对于仿真攻击的防范,可以采取识别或者拦截多次尝试注入攻击代码的恶意软件,限制模拟器的资源使用或者对模拟器的输入输出等进行限制。 同时,还可以针对模拟器本身的漏洞或者安全问题进行加强和升级,例如提高模拟器的执行效率、加强其隔离能力和安全控制等等,以提高其整体的安全性和稳定性。 总之,针对Android模拟器检测与对抗是一个不断发展的过程,需要综合运用安全技术和策略手段来保障Android系统的安全和稳定性。 ### 回答2: 随着Android开发工具的不断完善,现今已经出现了许多神经网络和机器学习模型,这些都是建立在手机设备的真实运行平台上的。因此,检测和对抗模拟器成为保护应用软件安全和用户隐私的重要一步。在下面的内容中,将就Android模拟器检测及对抗方法进行简要说明。 检测方法 如何检测模拟器就可以通过检测特定的硬件规范的方式来进行。通过检测设备的Sim卡号、IMEI、MAC地址等硬件定义能力,以此来进行模拟器检测。此外,还有一些开源的用于检测模拟器的工具,例如Anti-Emulator、J2Android等。 对抗方法 对于安卓模拟器检测的对抗方法,主要可以从以下几个方面来进行: (1)虚拟机检测绕过 在模拟器中检查与真实设备硬件参数相同的数据,以绕过检测,提高识别难度。此外还可以使用XPOSED框架,来使硬件参数信息看上去更加真实。 (2)操作系统绕过 使用修改后的ROM来绕过对模拟器检测。例如,Genymotion和AndroVM权限更高的虚拟化环境,同时支持模拟不同版本的Android。 (3)应用层绕过 可以通过模拟器操作系统中不可见的或者不常用的系统调用来绕过检测。此外,还可以通过代理或反向代理技术来绕过复杂的脚本或网络检测。 总之,基于某种检测方式设计的对抗方法是不固定的;因此,开发人员要考虑多种检测模拟器的方法,进行合理的应对。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值