安卓安全对抗之Unidbg检测(入门)

Unidbg简介

Unidbg是一个基于unicorn的模拟android-arm环境的一个小模拟器,通过这个东西,用户可以实现黑盒调试断电,跟踪逆向等操作...

检测手段

Unidbg这个东西,几乎全身上下都是特征,模拟CPU指令没有完整的权限控制,还有不符合安卓源代码一些定义,这些都导致了他被检测。

PS: 那堆烂大街的检测我懒得写。

libc堆检测

    const char *c_str = NULL;
    char buff[128] = {0};
    jboolean isCopy;	// 返回JNI_TRUE表示原字符串的拷贝,返回JNI_FALSE表示返回原字符串的指针
    c_str = (*env)->GetStringUTFChars(env, j_str, &isCopy);

上面这串代码是JNI从Java层获取字符串的一个例子,看起来平平无奇对吧?实际上你翻看unidbg源代码,你会发现,他对这个东西实现是通过mmap创建了一块内存区域,而谷歌官方的源代码里面写的是通过new来创建的(libc),通过特征识别就可以判断出这块区域是否在libc堆区,进而完成检测。

cpu features检测

CPU会有features,这些东西通常没人注意,他会出现在/proc/cpuinfo之中,读取出来对比一下其它方式获取的结果,完成检测。

程序中读取features有3种方法:

  • 通过辅助向量获取(getauxval)
unsigned long hwcaps = getauxval(AT_HWCAP);
  • 通过mrs寄存器(从状态寄存器读取到通用寄存器)
uint64_t value;
asm volatile("mrs %[result], ID_AA64PFR0_EL1 "
    : [result] "=r"(value));
  • 通过文件cpu_info

这个检测不具备很容易修复的特性,因为mrs读取系统状态寄存器ID_AA64PFR0_EL1,在unidbg/unicorn环境中,你可以使用msr修改大部分系统寄存器(正常环境会panic),但是ID_AA64PFR0_EL1是你无法修改的,要是想改变ID_AA64PFR0_EL1,必须重新编译unicorn。