Android安全-代码安全5-调试器和模拟器的检测
Android安全-代码安全5-模拟器和调试器的检测
1.模拟器的检测
一般在分析 APK 的过程中会借助于 Android 模拟器,比如分析网络行为,动态调试等。
因此从 APK 自我保护的角度出发,可以增加对 APK 当前运行环境的检测,判断是否运行在
模拟器中,如果运行在模拟器中可以选择退出整个应用程序的执行或者跳到其他分支。模拟
器检测的手段有很多,下面逐一分析。
(1)判断一些唯一属性
//判断当前设备是否是模拟器。如果返回TRUE,则当前是模拟器,不是返回FALSE
public static boolean isEmulator(Context context){
try{
TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
String imei = tm.getDeviceId();
if (imei != null && imei.equals("000000000000000")){
return true;
}
return (Build.MODEL.equals("sdk")) || (Build.MODEL.equals("google_sdk"));
}catch (Exception ioe) {
}
return false;
}
当然还可以检查一些其他的值,如电池的电池状态、电池电量,Secure.ANDROID_ID,
DeviceId,手机号码等。
(2)虚拟机文件检测
相 对 于 真 实 设 备 , Android 模 拟 器 中 存 在 一 些 特 殊 的 文 件 或 者 目 录 , 如
/system/bin/qemu-props,该可执行文件可以用来在模拟器中设置系统属性。另外还有
/system/lib/libc_malloc_debug_qemu.so 文件以及/sys/qemu_trace 目录。我们可以通过检测这些
特殊文件或者目录是否存在来判断 Android 应用程序是否运行在模拟器中,关键代码如下:
1. private static String[] known_files = { 2. "/system/lib/libc_malloc_debug_qemu.so", 3. "/sys/qemu_trace", 4. "/system/bin/qemu-props" 5. }; 6. 7. public static boolean hasQEmuFiles() { 8. for(String pipe : known_files) { 9. File qemu_file = new File(pipe); 10. if (qemu_file.exists()) 11. return true; 12. } 13. return false; 14. }
更完整的代码可以参考 Tim Strazzere 的 Github 中 anti-emulator,该项目中还列举了其他一些
模拟器检测的方法,如检测 socket 文件/dec/socket/qemud。
2.调试器的检测
在对 APK 逆向分析时,往往会采取动态调试技术,可以使用 netbeans+apktool 对反汇编
生成的 smali 代码进行动态调试。为了防止 APK 被动态调试,可以检测是否有调试器连接。
Android 系统在 android.os.Debug 类中提供了 isDebuggerConnected()方法,用于检测是否有调
试器连接。可以在 Application 类中调用 isDebuggerConnected()方法,判断是否有调试器连接,
如果有,直接退出程序。
除了 isDebuggerConnected 方法,还可以通过在 AndroidManifest 文件的 application 节点中
加入 android:debuggable=”false”使得程序不可被调试,这样如果希望调试代码,则需要修改
该值为 true,因此可以在代码中检查这个属性的值,判断程序是否被修改过,代码如下:
1. if(getApplicationInfo().flags &= ApplicationInfo.FLAG_DEBUGGABLE != 0){ 2. System.out.println("Debug"); 3. android.os.Process.killProcess(android.os.Process.myPid()); 4. }
转自:http://bbs.pediy.com/showthread.php?t=183116