Android Emulator Detection

Android Emulator Detection

Overview

I wanted to explore all the ways that an Android application or malware could go about detecting whether or not it was being run in an emulator. After some researching (Google), I found that there were two common ways that one could go about accomplishing Android emulator detection programmatically. The post will explore each of these techniques implemented in a Proof-of-Concept application, and detection through reverse engineering. My setup for this experiment was running the application on top of Genymotion, which leverages VirtualBox to create Android virtual machines.

Detection Techniques

The two techniques we will leverage in Android emulator detection are the use of runtime execution, and Java reflection. The first option requires us to create a new runtime instance and execute commands. We are interested in the “getprop” command, which will return information that directly correlates with the android.os.SystemProperties class. I specifically care about the return value from the getprop ro.build.host command. If the application is being emulated on Genymotion, this will return buildbot.soft.genymobile.com, which indicates that we are running in that emulator. You can can also check the return value from getprop ro.product.name, which in the case of my environment will be vbox86p.

for(String prop : props) {

try {

Process p = Runtime.getRuntime().exec("getprop " + prop);

BufferedReader b = new BufferedReader(new InputStreamReader(p.getInputStream()));

String l = b.readLine();

if (l.equals("buildbot.soft.genymobile.com")) {

Toast.makeText(getApplicationContext(), "Emulator Detected", Toast.LENGTH_LONG).show();

}

Log.d("Exec Detect", l);

p.destroy();

} catch (IOException e) {

e.printStackTrace();

}

}

We can also use Java reflection in order to use the accessor methods within the android.os.SystemProperties class to return the same values that indicate that we are running in an emulated environment.

for(String prop : props) {

try {

@SuppressWarnings("rawtype")

Class sp = Class.forName("android.os.SystemProperties");

@SuppressWarnings("rawtypes")

Class[] paramTypes = new Class[1];

paramTypes[0] = String.class;

Method get = sp.getMethod("get", paramTypes);

Object[] params = new Object[1];

params[0] = prop;

String ret = (String) get.invoke(sp, prop);

if (ret.equals("buildbot.soft.genymobile.com")) {

Toast.makeText(getApplicationContext(), "Emulator Detected", Toast.LENGTH_LONG).show();

}

Log.d("Reflect Detect", ret);

So at a high level, our code will go through a list of system properties, and detect through both runtime execution and reflection whether or not a specific property exists. For the Proof-of-Concept I am logging the results, which can simply be accessed via Logcat:

D/Exec Detect( 6954): 0

D/Exec Detect( 6954): vbox86p

D/dalvikvm( 6954): GC_CONCURRENT freed 195K, 2% free 16701K/16964K, paused 0ms+1ms, total 13ms

D/Exec Detect( 6954): buildbot.soft.genymobile.com

D/Exec Detect( 6954): test-keys

D/Reflect Detect( 6954): 0

D/Reflect Detect( 6954): vbox86p

D/Reflect Detect( 6954): buildbot.soft.genymobile.com

D/Reflect Detect( 6954): test-keys

This is what are emulator displays back to us as the application executes:

Detection

So if we are reversing and analyzing an application such as this, how do we figure out if the application is attempting to detect whether or not it is being emulated. I personally love leveraging Androguard for this type of task. We can use Androguard’s python library in order to write a quick wrapper script that will search the packages of our application for methods that correspond to both classes which allow for runtime execution and reflection within Java.

def detect(a, apks,  uv):

# Methods to check for

methods = ['getRuntime', 'exec', 'forName', 'getMethod']

print(t.cyan("[*] {0} Target Package: {1}".format(datetime.datetime.now(), a.get_package())))

print(t.cyan("[*] {0} Checking Reflection".format(datetime.datetime.now())))

for method in methods:

analysis.show_Paths(apks, uv.get_tainted_packages().search_methods("Ljava/lang/Class", method, "."))

print(t.cyan("[*] {0} Checking Runtime".format(datetime.datetime.now())))

for method in methods:

analysis.show_Paths(apks

Now we can zero in on the package and Class of interest to perform further reversing and understanding of the target functionality.