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链接 CacheEmulatorChecker

参考文档

QEMU emulation detection DEXLabs

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

编辑于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏皮振伟的专栏

[linux][memory]balloon技术分析

前言: 我大天朝人觉得什么东西含量不够,叫做有“水份”。内存的含量不足,叫“balloon”。作者是外语专业毕业的,感觉不同国度的人虽然语言不同,但是表达出来的...

4818
来自专栏JackeyGao的博客

Django小技巧03: 优化数据库查询

本文介绍一个非常简单的技巧, 能够帮助你在使用 Django ORM 时优化数据库查询.

1102
来自专栏NetCore

Catalog Service - 解析微软微服务架构eShopOnContainers(三)

上一篇我们说了Identity Service,因为其基于IdentityServer4开发的,所以知识点不是很多,今天我们来看下Catalog Service...

2788
来自专栏晨星先生的自留地

实战系列之你真的会mysql注入么?

1895
来自专栏FreeBuf

无文件Powershell恶意程序使用DNS作为隐蔽信道

思科Talos安全团队最近发现一款Powershell恶意程序,用DNS进行双向通信。 前言 DNS是企业网络中最常用的Internet应用层协议。DNS提供域...

2529
来自专栏大学生计算机视觉学习DeepLearning

2018最新win10 安装tensorflow1.4(GPU/CPU)+cuda8.0+cudnn8.0-v6 + keras 安装CUDA莫名失败 导入tensorflow失败报错问题解决

原文链接:https://www.cnblogs.com/DOMLX/p/9747019.html

4052
来自专栏拂晓风起

Loader拉取图片,由于redirect重定向,导致策略文件无效 设置checkPolicyFile后还是无效:需要一个策略文件,但在加载此媒体时未设置 checkPolicyFile 标志

1036
来自专栏魏琼东

应用SAAS结构技术的开源药店管理系统-如何自己部署这种SOA/SAAS结构的应用

一、药店系统内容说明 在前些时间,我们发布了一个基于AgileEAS.NET平台的SAAS结构的案例-AgileEAS.NET平台开发实例-药店系统-快速的SA...

36310
来自专栏逸鹏说道

NET跨平台:在Ubuntu下搭建ASP.NET 5开发环境

0x00 写在前面的废话 年底这段时间实在太忙了,各种事情都凑在这个时候,没时间去学习自己感兴趣的东西,所以博客也好就没写了。最近工作上有个小功能要做成Web应...

2803
来自专栏Janti

记一次线程池调优经历

背景: 最近的一个项目需要用到招标,临时加了给我们的系统增加了一个性能需求,多少呢? 一秒钟300次NTP(不知道ntp的同学可以百度一下),平均3ms一次啊,...

4956

扫码关注云+社区