【Android应用保护技术探索之路系列】之四:对抗动态调试
2015-07-23 11:31
676 查看
作者:郭孝星
微博:郭孝星的新浪微博
邮箱:allenwells@163.com
博客:http://blog.csdn.net/allenwells
Github:https://github.com/AllenWells
【Android应用保护技术探索之路系列】之二:对抗反编译
【Android应用保护技术探索之路系列】之三:对抗静态分析
【Android应用保护技术探索之路系列】之四:对抗动态调试
【Android应用保护技术探索之路系列】之五:对抗重编译
对抗动态调试常用的有两种方式:检测调试器和检测模拟器。
在AndroidManifest.xml的Application标签中加入:
来让应用不可调试。
我们可以在应用运行时检测这个标志是否被修改,如果被修改则终止程序运行,如下所示:
模拟器和真实设备有着诸多差异,比如:
ro.product.model:该值在模拟器中是sdk,在真实设备中是手机的型号。
ro.build.tags:该值在模拟器中是test-keys,在真实设备中是realease-keys。
ro.lernel.qemu:该值在模拟器中是1,在真实设备中没有该属性。
下面以ro.lernel.qemu属性为例,检测代码如下:
微博:郭孝星的新浪微博
邮箱: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; } }
相关文章推荐
- 【Android应用保护技术探索之路系列】之三:对抗静态分析
- 【Android应用保护技术探索之路系列】之二:对抗反编译
- 【Android应用保护技术探索之路系列】之一:Android应用保护技术开篇
- android实现点击按钮实现home键的功能
- Android应用开发相关下载资源(2015/05/06更新)
- Android 让他们自己控制开发的定义(一个)
- 8 个最优秀的 Android Studio 插件
- android viewpager tab indicator炫酷的Tab动画效果
- Android log日志
- 安卓源码----安卓系统启动过程(初次研究源码,表述不当还请见谅)
- min3d引擎使用指南(Android)<三>
- Android Sqlite 批量 insert/update 提高效率
- android中Toast的用法
- android 在布局中合理的使用tag标签的好处
- Android Button控件与CountDownTimer的结合使用
- 【Android】Android聊天机器人实现
- Android中的Interpolator
- Smalidea无源码调试 android 应用
- Android中常用到的各种框架
- android知识图谱