当前位置: 代码迷 >> Android >> 【Android应用保护技术探索之路系列】之4:对抗动态调试
  详细解决方案

【Android应用保护技术探索之路系列】之4:对抗动态调试

热度:47   发布时间:2016-04-27 23:50:14.0
【Android应用保护技术探索之路系列】之四:对抗动态调试

作者:郭孝星
微博:郭孝星的新浪微博
邮箱:[email protected]
博客:http://blog.csdn.net/allenwells
github:https://github.com/AllenWell

【Android应用保护技术探索之路系列】章节目录

【Android应用保护技术探索之路系列】之一:Android应用保护技术开篇
【Android应用保护技术探索之路系列】之二:对抗反编译
【Android应用保护技术探索之路系列】之三:对抗静态分析
【Android应用保护技术探索之路系列】之四:对抗动态调试
【Android应用保护技术探索之路系列】之五:对抗重编译

对抗动态调试常用的有两种方式:检测调试器和检测模拟器。

一 检测调试器

动态调试器使用调试器来挂钩应用,获取应用运行时的数据。我们可以在应用中加入检测调试器的代码,如果检测到调试器则终止应用的运行。

在AndroidManifest.xml的Application标签中加入:

android:debuggable = "false"

来让应用不可调试。

我们可以在应用运行时检测这个标志是否被修改,如果被修改则终止程序运行,如下所示:

package com.droider.antidebug;import android.os.Bundle;import android.app.Activity;import android.content.pm.ApplicationInfo;import android.util.Log;import android.view.Menu;import android.widget.Toast;public class MainActivity extends Activity {    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        setTitle("反调试演示程序");        if ((getApplicationInfo().flags &=                 ApplicationInfo.FLAG_DEBUGGABLE) != 0){            Log.e("com.droider.antidebug", "程序被修改为可调试状态");            android.os.Process.killProcess(android.os.Process.myPid());        }          if (android.os.Debug.isDebuggerConnected()) {   //检测调试器            Log.e("com.droider.antidebug", "检测到测试器");            android.os.Process.killProcess(android.os.Process.myPid());        }           }       @Override    public boolean onCreateOptionsMenu(Menu menu) {        getMenuInflater().inflate(R.menu.activity_main, menu);        return true;    }}

二 检测模拟器

应用发布后是给用户安装到手机中运行的,如果发现应用运行在模拟器中,这显然不是正常的情况,说明可能有人想分析它,这个时候我们应予以阻止。

模拟器和真实设备有着诸多差异,比如:

  • ro.product.model:该值在模拟器中是sdk,在真实设备中是手机的型号。
  • ro.build.tags:该值在模拟器中是test-keys,在真实设备中是realease-keys。
  • ro.lernel.qemu:该值在模拟器中是1,在真实设备中没有该属性。

下面以ro.lernel.qemu属性为例,检测代码如下:

package com.droider.checkqemu;import java.io.BufferedReader;import java.io.DataOutputStream;import java.io.InputStreamReader;import java.lang.reflect.Method;import android.os.Bundle;import android.app.Activity;import android.content.Context;import android.graphics.Color;import android.util.Log;import android.view.Menu;import android.widget.TextView;public class MainActivity extends Activity {    private TextView text_info;    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        setTitle("模拟器检测演示程序");        text_info = (TextView) findViewById(R.id.textView1);        if (isRunningInEmualtor()) {    //检测模拟器            text_info.setTextColor(Color.RED);            text_info.setText("程序运行在模拟器中!");        } else {            text_info.setTextColor(Color.GREEN);            text_info.setText("程序运行在真实设备中!");        }    }    boolean isRunningInEmualtor() {        boolean qemuKernel = false;        Process process = null;        DataOutputStream os = null;        try{              process = Runtime.getRuntime().exec("getprop ro.kernel.qemu");              os = new DataOutputStream(process.getOutputStream());            BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream(),"GBK"));            os.writeBytes("exit\n");              os.flush();            process.waitFor();            qemuKernel = (Integer.valueOf(in.readLine()) == 1);            Log.d("com.droider.checkqemu", "检测到模拟器:" + qemuKernel);                     } catch (Exception e){              qemuKernel = false;            Log.d("com.droider.checkqemu", "run failed" + e.getMessage());         } finally {            try{                  if (os != null) {                      os.close();                  }                  process.destroy();              } catch (Exception e) {            }              Log.d("com.droider.checkqemu", "run finally");         }        return qemuKernel;    }    public static String getProp(Context context, String property) {        try {            ClassLoader cl = context.getClassLoader();            Class SystemProperties = cl.loadClass("android.os.SystemProperties");            Method method = SystemProperties.getMethod("get", String.class);            Object[] params = new Object[1];            params[0] = new String(property);            return (String)method.invoke(SystemProperties, params);        } catch (Exception e) {            return null;        }    }    @Override    public boolean onCreateOptionsMenu(Menu menu) {        getMenuInflater().inflate(R.menu.activity_main, menu);        return true;    }}

版权声明:本文为博主原创文章,未经博主允许不得转载。

  相关解决方案