您的位置:首页 > 移动开发 > Android开发

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

2015-07-23 11:31 676 查看
作者:郭孝星

微博:郭孝星的新浪微博

邮箱:allenwells@163.com

博客:http://blog.csdn.net/allenwells

Github:https://github.com/AllenWells

【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;
    }
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: