This is an apk for detecting virtual machine. Most of these techniques can be bypassed by changing the android framework and kernel.
Key points for testing this apk: use an arm based image emulator otherwise you can't compile those jni code with arm assembly int it.
Simply checking those properties in qemu.
Some emulators have default device id.
Check whether there exists qemu pipes. /dev/socket/qemud /dev/qemu_pipe
Some emulators have default numbers.
Some emulators have default IMSI numbers.
There is a Build.java file and it has some public variables. We can check those strings.
Some emulators have "android" as operators.
There is goldfish under "/proc/tty/drivers" and "/proc/cpuinfo".
There is "/system/lib/libc_malloc_debug_qemu.so", "/sys/qemu_trace", "/system/bin/qemu-props" in an emulator.
There is "/dev/socket/genyd", "/dev/socket/baseband_genyd" in genymotion emulators. For those who is not using genymotion, you can probably ignore this.
Funny one. Some people may use Monkey for testing. It's not a real monkey just some kind of testing skills.
Bypass this one by changing the goldfish kernel source code.
Some emulators has eth0 network interface.
Simply detect taintdroid.
Emulators may can't register sensors or its sensors have constant values.
In qemu, the processor has to finish the current task before start the other one. So here the thread two can't get the globale variable when it querys. It has to wait for the thread one to finish that arm assembly block code.
For my apk, if it prints 5000 in the string, it means the global variable is a constant and it is in the emulator. Otherwise, it is in the real device.
Arm is actually based on harvard architecture. Whihc means, if we get a function address and put function 1 and function 2 on that address rotationally we may execute function 1 and function 2 randomly. While in emulators, it just execute what function we put there right before we call it.
For my apk, if it prints out "#SMC1#" and "#SMC2#" one by one, it should be in emulator. If this two strings are random, it's in the real device.
For qemu, it actually gets locked or quit abnormally when we call "bkpt".