android安全校验方案总结和参考

动态调试攻击风险解决

application 设置debugable=“false”

Android防止被动态调试的解决方法

另参考:
安卓应用加固之反动态调试技术总结
Android 动态加载(防止逆向编译)技术
App动态调试

代码未混淆风险

Android Studio 代码混淆(包教包会)
Android Studio 代码混淆(你真的会混淆吗)
Android studio开启代码混淆,让你的代码更安全
android studio 代码混淆如何忽略第三方jar包

界面劫持风险

Android 防界面劫持方案

Broadcast Receiver组件导出风险

AndroidManifest.xml中的
export=“true->false”
参考:移动APP安全测试

拒绝服务攻击漏洞

7.8 应用本地拒绝服务漏洞检测

其他参考

移动APP安全测试
深入浅出 App 端安全漏洞之任意调试漏洞、中间人劫持漏洞及加密算法漏洞

我使用的代码

在Application中调用 securityCheck() ,注册ActivityLifecycleCallbacks,在onAcitivityResumed() 和 onActivityPause() 中做反劫持,就不用在BaseActivity中使用了。

    private void securityCheck() {
        // 防止动态调试攻击风险
        DebuggerUtils.checkDebuggableInNotDebugModel(this);
        // 反劫持
        registerActivityLifecycleCallbacks(mSecurityLifecycleCallbacks);


    }

    ActivityLifecycleCallbacks mSecurityLifecycleCallbacks = new ActivityLifecycleCallbacks() {
        @Override
        public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
        }

        @Override
        public void onActivityStarted(Activity activity) {
        }

        @Override
        public void onActivityResumed(Activity activity) {
            AntiHijackingUtils.getInstance().onResume();
        }

        @Override
        public void onActivityPaused(Activity activity) {
            AntiHijackingUtils.getInstance().onPause(activity);
        }

        @Override
        public void onActivityStopped(Activity activity) {

        }

        @Override
        public void onActivitySaveInstanceState(Activity activity, Bundle outState) {

        }

        @Override
        public void onActivityDestroyed(Activity activity) {

        }
    };

AntiHijackingUtils 反劫持工具类


import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
 
/**
 * Title: AntiHijackingUtils<br/>
 * Description: 反界面劫持工具类<br/>
 * refer: [Android 防界面劫持方案,无视Android系统版本限制,无需操作栈] (https://blog.csdn.net/Prince_WenZheng/article/details/54630259?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.compare&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.compare)
 */
 
public class AntiHijackingUtils {
    /**
     * 用于执行定时任务
     */
    private Timer timer = null;
 
    /**
     * 用于保存当前任务
     */
    private List<MyTimerTask> tasks = null;
 
    /**
     * 唯一实例
     */
    private static AntiHijackingUtils antiHijackingUtils;
 
    private AntiHijackingUtils() {
        // 初始化
        tasks = new ArrayList<MyTimerTask>();
        timer = new Timer();
    }
 
    /**
     * 获取唯一实例
     *
     * @return 唯一实例
     */
    public static AntiHijackingUtils getInstance() {
        if (antiHijackingUtils == null) {
            antiHijackingUtils = new AntiHijackingUtils();
        }
        return antiHijackingUtils;
    }
 
    /**
     * 在activity的onPause()方法中调用
     *
     * @param activity
     */
    public void onPause(final Activity activity) {
        MyTimerTask task = new MyTimerTask(activity);
        tasks.add(task);
        timer.schedule(task, 1000);
    }
 
    /**
     * 在activity的onResume()方法中调用
     */
    public void onResume() {
        if (tasks.size() > 0) {
            tasks.get(tasks.size() - 1).setCanRun(false);
            tasks.remove(tasks.size() - 1);
        }
    }
 
    /**
     * 自定义TimerTask类
     */
    class MyTimerTask extends TimerTask {
        /**
         * 任务是否有效
         */
        private boolean canRun = true;
        private Activity activity;
 
        public void setCanRun(boolean canRun) {
            this.canRun = canRun;
        }
 
        public MyTimerTask(Activity activity) {
            this.activity = activity;
        }
 
        @Override
        public void run() {
            activity.runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    if (canRun) {
                        // 程序退到后台,进行风险警告
                        ToastUtil.popupMessage(activity, "程序切换至后台运行,请注意观察运行环境是否安全!");
                        tasks.remove(MyTimerTask.this);
                    }
                }
            });
        }
    }
}

防止动态调试工具类 DebuggerUtils

import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.os.Debug;
import android.support.v4.BuildConfig;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.Locale;

/**
 * 动态调试工具类
 * · 检查是否被动态调试,如果是,则强制退出应用。
 *
 * refer: [Android防止被动态调试的解决方法] (https://blog.csdn.net/qq_43278826/article/details/106055838?utm_medium=distribute.pc_aggpage_search_result.none-task-blog-2~all~first_rank_v2~rank_v25-2-106055838.nonecase)
 */
public class DebuggerUtils {
    /**
     * 判断当前应用是否是debug状态
     */
    public static boolean isDebuggable(Context context) {
        try {
            ApplicationInfo info = context.getApplicationInfo();
            return (info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 检测是否在非Debug编译模式下,进行了调试操作,以防动态调试
     *
     * @param context
     * @return
     */
    public static void checkDebuggableInNotDebugModel(Context context) {
        //非Debug 编译,反调试检测
        if (!BuildConfig.DEBUG) {
            if (isDebuggable(context)) {
                System.exit(0);
            }

            Thread t = new Thread(new Runnable() {
                @Override
                public void run() {
                    while (true) {
                        try {
                            //每隔300ms检测一次
                            Thread.sleep(300);
                            //判断是否有调试器连接,是就退出
                            if (Debug.isDebuggerConnected()) {
                                System.exit(0);
                            }

                            //判断是否被其他进程跟踪,是就退出
                            if (isUnderTraced()) {
                                System.exit(0);
                            }
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }, "SafeGuardThread");
            t.start();
        }
        if (isUnderTraced()) {
            System.exit(0);
        }

    }

    /**
     * 当我们使用Ptrace方式跟踪一个进程时,目标进程会记录自己被谁跟踪,可以查看/proc/pid/status看到这个信息,而没有被调试的时候TracerPid为0
     *
     * @return
     */
    private static boolean isUnderTraced() {
        String processStatusFilePath = String.format(Locale.US, "/proc/%d/status", android.os.Process.myPid());
        File procInfoFile = new File(processStatusFilePath);
        try {
            BufferedReader b = new BufferedReader(new FileReader(procInfoFile));
            String readLine;
            while ((readLine = b.readLine()) != null) {
                if (readLine.contains("TracerPid")) {
                    String[] arrays = readLine.split(":");
                    if (arrays.length == 2) {
                        int tracerPid = Integer.parseInt(arrays[1].trim());
                        if (tracerPid != 0) {
                            return true;
                        }
                    }
                }
            }

            b.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

        return false;
    }

}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值