Group of Software Security In Progress

GoSSIP @ LoCCS.Shanghai Jiao Tong University

Rage Against the Virtual Machine: Hindering Dynamic Analysis of Android Malware

Do not go gentle into that good night.

Rage, rage against the dying of the light.

—– From The Poems of Dylan Thomas (1914 – 1953)

论文 Rage Against the Virtual Machine: Hindering Dynamic Analysis of Android Malware 是一篇发表在European Workshop on System Security会议上的很有趣的论文。它提出了两种(一种?)app检测自己是否处于模拟环境的通用方法。

论文下载

文章前半部分都在介绍背景,现状,指出现有的Android Malware 使用一些“启发式的模拟环境检测”来对抗一些自动化的动态分析引擎,采用的启发式特征包括设备序号:

  • IMEI
  • 网络参数:MAC,所处网段
  • 各种传感器:加速度计,陀螺仪,GPS。。
  • 能被检测出来,都是因为模拟环境不够真实。。
  • 这些问题很容易修正,导致方法很快失效

作者的方法1:

  • 首先看作者对模拟环境一系列假设(全系统模拟):
  • 在真实的物理CPU中,PC在每条指令执行之后都会增长
  • 模拟器为了效率引入JIT,VPC只在基本块结束才会更新
  • 多线程会相互打断,上下文的切换则是由操作系统完成的
  • 如果在JIT的基本块被中断,上下文的PC可能是没办法正常存储的
  • 模拟器为此才去的策略让中断只发生在基本块之间的branch语句上
  • 接下来其实我们只需要观测到这种现象就可以说明自己处在模拟环境下

作者的例子:

Thread 1:

1
2
3
4
5
6
while (ture) {
  global = 1
  global += 1
  global += 1
  global += 1
}

Thread 2:

1
2
3
while (true) {
  print(global)
}

Thread2 看到的global的值如果绝大多数都是4的话,就说明自己在模拟器中

作者的方法2:

  • 哈佛结构的ARM(?)并不保证ICache 和 DCache 的一致性
  • 也就是自修改代码再修改完代码段之后,还需要调用cacheflush函数清空ICache并把DCache写回,才能保证CPU读到指令的是修改过的。。。
  • 然而。。。模拟器并不太可能去再实现一个虚拟缓存。。。效率太低了。。。

所以总结来说,作者给出了一个很难被解决的检测模拟环境的方法,针对跨架构的动态分析应该是比较有效。进一步,作者也给出了一些应对的措施,解决方法主要两点:更加精确地二进制翻译(慢),或者使用物理设备辅助模拟执行(比如说Avatar)。。