Android模拟器识别检测技术

Android模拟器识别检测技术

Android模拟器常常被用来刷单,如何准确的识别模拟器成为App开发中的一个重要模块,目前也有专门的公司提供相应的SDK供开发者识别模拟器。 目前流行的Android模拟器大概分为两种,一种是基于Qemu,另一类是基于Genymotion(VirtualBox类),网上现在流行用一些模拟器特征进行鉴别,比如:

  • 通过判断IMEI是否全部为0000000000格式(>=6.0的国产ROM可能直接返回00000000000000,也要区分)
  • 判断Build中的一些模拟器特征值
  • 匹配Qemu的一些特征文件以及属性
  • 通过获取cpu信息,将x86的给过滤掉(真机一般都是基于ARM)

不过里面的很多手段都能通过改写ROM或者Xposed作假,让判断的性能打折扣。其实,现在绝大部分手机都是基于ARM架构,其他CPU架构给忽略不计,模拟器全部运行在PC上,因此,只需要判断是运行的设备否是ARM架构即可。

ARM与Simpled X86在架构上有很大区别,ARM采用的哈弗架构将指令存储跟数据存储分开,与之对应的,ARM的一级缓存分为I-Cache(指令缓存)与D-Cahce(数据缓存),而Simpled X86只有一块缓存,而模拟器采用的可以看做是Simpled-x86架构,如果我们将一段代码可执行代码动态映射到内存,在执行的时候,Simpled-X86架构上动态修改这部分代码后,指令缓存会被同步修改,而ARM修改的却是D-Cahce中的内容,此时I-Cache中的指令并不一定被更新,这样,程序就会在ARM与Simpled-x86上有不同的表现,根据计算结果便可以知道究竟是还在ARM平台上运行,为什么说模拟器采用的是Simpled-x86架构,拿QEMU来说,它采用了一些手段,主动保证了Self-Modifying Code的同步性,看QEMU对于Self-Modifying Code的处理:

On RISC targets, correctly written software uses memory barriers and cache flushes, so some of the protection above would not be necessary. However, QEMU still requires that the generated code always matches the target instructions in memory in order to handleexceptions correctly.

无论是x86还是ARM,只要是静态编译的程序,都没有修改代码段的权限,所以,首先需要将上面的汇编代码翻译成可执行文件,再需要申请一块内存,将可执行代码段映射过去,执行。
以下实现代码是测试代码的核心,主要就是将地址e2844001的指令add r4, r4, #1,在运行中动态替换为e2877001的指令add r7, r7, #1,这里目标是ARM-V7架构的,要注意它采用的是三级流水,PC值=当前程序执行位置+8。通过arm交叉编译链编译出的可执行代码如下:

8410:       e92d41f0        push    {r4, r5, r6, r7, r8, lr}
8414:       e3a07000        mov     r7, #0
8418:       e1a0800f        mov     r8, pc      // 本平台针对ARM7,三级流水  PC值=当前程序执行位置+8
841c:       e3a04000        mov     r4, #0
8420:       e2877001        add     r7, r7, #1
    ....
842c:       e1a0800f        mov     r8, pc
8430:       e248800c        sub     r8, r8, #12   // PC值=当前程序执行位置+8
8434:       e5885000        str     r5, [r8]
8438:       e354000a        cmp     r4, #10
843c:       aa000002        bge     844c <out>
.....

如果是在ARM上运行,e2844001处指令无法被覆盖,最终执行的是add r4,#1 ,而在x86平台上,执行的是add r7,#1 ,代码执行完毕, r0的值在模拟器上是1,而在真机上是10。之后,将上述可执行代码通过mmap,映射到内存并执行即可,具体做法如下,将可执行的二进制代码直接拷贝可执行代码区,去执行

void (*asmcheck)(void);
int detect() {
        //可执行二进制代码
    char code[] =
        "\xF0\x41\x2D\xE9"
        "\x00\x70\xA0\xE3"
        "\x0F\x80\xA0\xE1"
        "\x00\x40\xA0\xE3"
        "\x01\x70\x87\xE2"
        "\x00\x50\x98\xE5"
        "\x01\x40\x84\xE2"
        ....
    // 映射一块可执行内存 PROT_EXEC
    void *exec = mmap(NULL, (size_t) getpagesize(), PROT_EXEC|PROT_WRITE|PROT_READ, MAP_ANONYMOUS | MAP_SHARED, -1, (off_t) 0);
    memcpy(exec, code, sizeof(code) + 1);
       //强制赋值到函数
    asmcheck = (void *) exec;
      //执行函数
    asmcheck();
    __asm __volatile (
    "mov %0,r0 \n"
    :"=r"(a)
    );
    munmap(exec, getpagesize());
    return a;
}

经验证, 无论是Android自带的模拟器,还是夜神模拟器,或者Genymotion造假的模拟器,都能准确识别。在32位真机上完美运行,但是在64位的真机上可能会存在兼容性问题,可能跟arm64-v8a的指令集不同有关系,也希望人能指点。为了防止在真机上出现崩溃,最好还是单独开一个进程服务,利用Binder实现模拟器鉴别的查询。

另外,对于Qemu的模拟器还有一种任务调度的检测方法,但是实验过程中发现不太稳定,并且仅限Qemu,不做参考,不过这里给出原文链接:
DEXLabs

仅供参考,欢迎指正

作者:看书的小蜗牛
原文链接 Android模拟器识别技术

Github链接 AntiFakerAndroidChecker

参考文档

QEMU emulation detection
DEXLabs

https://github.com/HackBraid/CacheEmulatorChecker

这个文章是可以使用的,在这里 有一个大问题,就是他没有arm64-v8a的so文件。所以不支持arm64-v8a指令集,但是目前大部分的机器都使用的是arm64-v8a,所以,它会死亡,找个折中的方法就是,使用低版本指令集的so文件。

//设置使用的so文件库

ndk { abiFilters 'armeabi' }

希望有一个好的方案,

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值