Android Emulator Detection

Ray Chong
2 min readApr 22, 2021
Photo by Daniel Romero on Unsplash

Over the past few years, the Fintech industry is sprouting up all over the world and helping the rise of new markets. Consumers are getting used to experiencing a seamless digital experience when handling their funds. As the mobile application getting mature and providing more functionality to users, they become more attractive to attackers/hackers.

Usually, attackers will start to understand their target application by using an emulator for the operating system where the application will be run and analyzed. Regardless of the type of attacks they wish to execute, the first step is usually to use an emulator. Therefore in this article, I’m going to show some of the methods to identify whether the app is executed and running on an emulator.

First, we need to gather types of the emulator in the market and analyze their properties. This is the list of often used android emulators in the market:

  • Android Studio Emulator
  • Bluestacks
  • Genymotion
  • Nox
  • Droid4x
  • Andy
  • MEmu player

So, to start with the detection, the easiest way is to check on the build values under BuildConfig. All these values can be accessed programmatically and most of the time they contain proof of the presence of an emulator.

  • Build.MANUFACTURER
  • Build.MODEL
  • Build.HARDWARE
  • Build.FINGERPRINT
  • Build.BOARD
  • Build.PRODUCT
private fun checkBuildConfig(): Boolean {
var isEmulator = (Build.MANUFACTURER.contains("Genymotion")
|| Build.MODEL.contains("google_sdk")
|| Build.MODEL.toLowerCase().contains("droid4x")
|| Build.MODEL.contains("Emulator")
|| Build.MODEL.contains("Android SDK built for x86")
|| Build.HARDWARE == "goldfish"
|| Build.HARDWARE == "vbox86"
|| Build.HARDWARE.toLowerCase().contains("nox")
|| Build.FINGERPRINT.startsWith("generic")
|| Build.PRODUCT == "sdk"
|| Build.PRODUCT == "google_sdk"
|| Build.PRODUCT == "sdk_x86"
|| Build.PRODUCT == "vbox86p"
|| Build.PRODUCT.toLowerCase().contains("nox")
|| Build.BOARD.toLowerCase().contains("nox")
|| (Build.BRAND.startsWith("generic") && Build.DEVICE.startsWith("generic")))
return isEmulator
}

Go Advanced:
If all these checkings still not sufficient for you, probably need to go a little bit deeper to check the files/folder usually used by the emulator.

private val GENY_FILES = arrayOf(
"/dev/socket/genyd",
"/dev/socket/baseband_genyd"
)
private val PIPES = arrayOf(
"/dev/socket/qemud",
"/dev/qemu_pipe"
)
private val X86_FILES = arrayOf(
"ueventd.android_x86.rc",
"x86.prop",
"ueventd.ttVM_x86.rc",
"init.ttVM_x86.rc",
"fstab.ttVM_x86",
"fstab.vbox86",
"init.vbox86.rc",
"ueventd.vbox86.rc"
)
private val ANDY_FILES = arrayOf(
"fstab.andy",
"ueventd.andy.rc"
)
private val NOX_FILES = arrayOf(
"fstab.nox",
"init.nox.rc",
"ueventd.nox.rc"
)
fun checkFiles(targets: Array<String>): Boolean {
for (pipe in targets) {
val file = File(pipe)
if (file.exists()) {
return true
}
}
return false
}
fun checkEmulatorFiles():Boolean {
return (checkFiles(GENY_FILES)
|| checkFiles(ANDY_FILES)
|| checkFiles(NOX_FILES)
|| checkFiles(X86_FILES)
|| checkFiles(PIPES))
}

Bottom line:
The usage of fintech mobile applications is growing rapidly over the world. Step into the ground of security is eventually a must for developers to secure their application in order to get rid of fraud cases. There are many more mechanisms to detect emulators available on the internet, do give them a try and figure out the best solution for your use cases.

--

--