Skip to content

Commit

Permalink
Add detecting the tracer pid.
Browse files Browse the repository at this point in the history
Added method for detecting an application attaching via ptrace,
used ITW by Alibaba's packer.
  • Loading branch information
strazzere committed Jan 30, 2015
1 parent 7d863c4 commit 59e2e35
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 50 deletions.
10 changes: 9 additions & 1 deletion AntiEmulator/src/diff/strazzere/anti/MainActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,15 @@ public boolean isMonkeyDetected() {

public boolean isDebugged() {
log("Checking for debuggers...");
if (FindDebugger.isBeingDebugged()) {

boolean tracer = false;
try {
tracer = FindDebugger.hasTracerPid();
} catch (Exception exception) {
exception.printStackTrace();
}

if (FindDebugger.isBeingDebugged() || tracer) {
log("Debugger was detected");
return true;
} else {
Expand Down
84 changes: 41 additions & 43 deletions AntiEmulator/src/diff/strazzere/anti/common/Utilities.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,52 +6,50 @@
import android.content.pm.PackageManager;

/**
* Common functions used for detection of
* system fingerprints.
* Common functions used for detection of system fingerprints.
*
* @author tstrazzere
*/
public class Utilities {

/**
* Method to reflectively invoke the SystemProperties.get
* command - which is the equivalent to the adb shell getProp
* command.
*
* @param context A {@link Context} object used to get the proper
* ClassLoader (just needs to be Application Context object)
* @param property A {@code String} object for the property to
* retrieve.
* @return {@code String} value of the property requested.
*/
public static String getProp(Context context, String property) {
try {
ClassLoader classLoader = context.getClassLoader();
Class<?> systemProperties = classLoader.loadClass("android.os.SystemProperties");

Method get = systemProperties.getMethod("get", String.class);

Object[] params = new Object[1];
params[0] = new String(property);

return (String) get.invoke(systemProperties, params);
} catch (IllegalArgumentException iAE) {
throw iAE;
} catch (Exception exception) {
throw null;
}
}

public static boolean hasPackageNameInstalled(Context context, String packageName) {
PackageManager packageManager = context.getPackageManager();

// In theory, if the package installer does not throw an exception, package exists
try {
packageManager.getInstallerPackageName(packageName);
return true;
}
catch(IllegalArgumentException exception) {
return false;
}
}
/**
* Method to reflectively invoke the SystemProperties.get command - which is the equivalent to the adb shell getProp
* command.
*
* @param context
* A {@link Context} object used to get the proper ClassLoader (just needs to be Application Context
* object)
* @param property
* A {@code String} object for the property to retrieve.
* @return {@code String} value of the property requested.
*/
public static String getProp(Context context, String property) {
try {
ClassLoader classLoader = context.getClassLoader();
Class<?> systemProperties = classLoader.loadClass("android.os.SystemProperties");

Method get = systemProperties.getMethod("get", String.class);

Object[] params = new Object[1];
params[0] = new String(property);

return (String) get.invoke(systemProperties, params);
} catch (IllegalArgumentException iAE) {
throw iAE;
} catch (Exception exception) {
throw null;
}
}

public static boolean hasPackageNameInstalled(Context context, String packageName) {
PackageManager packageManager = context.getPackageManager();

// In theory, if the package installer does not throw an exception, package exists
try {
packageManager.getInstallerPackageName(packageName);
return true;
} catch (IllegalArgumentException exception) {
return false;
}
}
}
47 changes: 44 additions & 3 deletions AntiEmulator/src/diff/strazzere/anti/debugger/FindDebugger.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;

Expand All @@ -14,21 +15,59 @@
*/
public class FindDebugger {

private static String tracerpid = "TracerPid";

/**
* Believe it or not, there are packers that use this...
*/
public static boolean isBeingDebugged() {
return Debug.isDebuggerConnected();
}

/**
* This is used by Alibaba to detect someone ptracing the application.
*
* Easy to circumvent, the usage ITW was a native thread constantly doing this every three seconds - and would cause
* the application to crash if it was detected.
*
* @return
* @throws IOException
*/
public static boolean hasTracerPid() throws IOException {
BufferedReader reader = null;
try {
reader = new BufferedReader(new InputStreamReader(new FileInputStream("/proc/self/status")), 1000);
String line;

while ((line = reader.readLine()) != null) {
if (line.length() > tracerpid.length()) {
if (line.substring(0, tracerpid.length()).equalsIgnoreCase(tracerpid)) {
if (Integer.decode(line.substring(tracerpid.length() + 1).trim()) > 0) {
return true;
}
break;
}
}
}

} catch (Exception exception) {
exception.printStackTrace();
} finally {
reader.close();
}
return false;
}

/**
* This was reversed from a sample someone was submitting to sandboxes for a thesis, can't find paper anymore
*
* @throws IOException
*/
public static boolean hasAdbInEmulator() {
public static boolean hasAdbInEmulator() throws IOException {
boolean adbInEmulator = false;
BufferedReader reader = null;
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream("/proc/net/tcp")),
1000);
reader = new BufferedReader(new InputStreamReader(new FileInputStream("/proc/net/tcp")), 1000);
String line;
// Skip column names
reader.readLine();
Expand Down Expand Up @@ -60,6 +99,8 @@ public static boolean hasAdbInEmulator() {
}
} catch (Exception exception) {
exception.printStackTrace();
} finally {
reader.close();
}

return adbInEmulator;
Expand Down
12 changes: 9 additions & 3 deletions AntiEmulator/src/diff/strazzere/anti/emulator/FindEmulator.java
Original file line number Diff line number Diff line change
Expand Up @@ -202,15 +202,16 @@ public static boolean hasKnownImsi(Context context) {

public static boolean hasEmulatorBuild(Context context) {
String BOARD = android.os.Build.BOARD; // The name of the underlying board, like "unknown".
String BOOTLOADER = android.os.Build.BOOTLOADER; // The system bootloader version number.
// This appears to occur often on real hardware... that's sad
// String BOOTLOADER = android.os.Build.BOOTLOADER; // The system bootloader version number.
String BRAND = android.os.Build.BRAND; // The brand (e.g., carrier) the software is customized for, if any.
// "generic"
String DEVICE = android.os.Build.DEVICE; // The name of the industrial design. "generic"
String HARDWARE = android.os.Build.HARDWARE; // The name of the hardware (from the kernel command line or
// /proc). "goldfish"
String MODEL = android.os.Build.MODEL; // The end-user-visible name for the end product. "sdk"
String PRODUCT = android.os.Build.PRODUCT; // The name of the overall product.
if ((BOARD.compareTo("unknown") == 0) || (BOOTLOADER.compareTo("unknown") == 0)
if ((BOARD.compareTo("unknown") == 0) /* || (BOOTLOADER.compareTo("unknown") == 0) */
|| (BRAND.compareTo("generic") == 0) || (DEVICE.compareTo("generic") == 0)
|| (MODEL.compareTo("sdk") == 0) || (PRODUCT.compareTo("sdk") == 0)
|| (HARDWARE.compareTo("goldfish") == 0)) {
Expand Down Expand Up @@ -241,6 +242,11 @@ public static boolean checkQemuBreakpoint() {
}

public static boolean hasEmulatorAdb() {
return FindDebugger.hasAdbInEmulator();
try {
return FindDebugger.hasAdbInEmulator();
} catch (Exception exception) {
exception.printStackTrace();
return false;
}
}
}

0 comments on commit 59e2e35

Please sign in to comment.