精华内容
下载资源
问答
  • Android Activity 防劫持,界面防劫持,无视Android系统版本限制,无需操作栈
  • Android 界面防劫持

    2020-07-31 13:50:43
    目录 一 什么是页面劫持 二 页面劫持常用攻击手段 三 如何防范页面劫持 3.1 用户方面 3.2 开发者方面 四 参考 一 什么是页面劫持 界面劫持是指在Android系统中,恶意软件通过监控目标软件的运行,当检测到当前运行...

    一、什么是页面劫持

    界面劫持是指在Android系统中,恶意软件通过监控目标软件的运行,当检测到当前运行界面为某个被监控应用的特定界面时(一般为登录或支付界面),弹出伪造的钓鱼页面,从而诱导用户输入信息,最终窃取用户的隐私(恶意盗取用户账号、卡号、密码等信息),或者利用假冒界面进行钓鱼欺诈。

    二、页面劫持常用攻击手段

    (1)监听系统Logocat日志,一旦监听到发生Activity界面切换行为,即进行攻击,覆盖上假冒Activity界面实施欺骗;

    (2)监听系统API,一旦恶意程序监听到相关界面的API组件调用,即可发起攻击;

    (3)5.0以下机型枚举获取栈顶Activity,监控到目标Activity出现,即可发起攻击;

    (4) 恶意启动Service监听目标应用,在切换到目标Activity时,弹出对话框劫持当前界面迷惑用户。

    (5)通过截屏录制屏幕,分析用户行为,对应弹窗。(自己臆想的)

    ps:目前来看,只有系统app才有权限获取所有log、顶栈信息,普通app只能获取自己的数据,并没有权限。(可能有其他方式,我没找到)

    三、如何防范页面劫持

    3.1 用户方面

    1、在支付等关键使用环境,看到应用切换后台的相关提示,得注意下
    2、在支付等关键使用环境,查看后台,最新记录有不明应用。

    3.2 开发者方面

    针对Activity类型劫持,在登录窗口或者用户隐私输入等关键Activity的onPause方法中检测最前端Activity应用是不是自身,如果不是,则提示。
    针对弹窗对话框类型的劫持。可以对自身弹窗设置标志位,如果acitvity失去焦点,并没有onpause,检查标志位即可判断是否是他人应用覆盖,可以对用户提醒。

    针对弹窗,自行实践即可,针对Activity,下面有个工具类

    package com.demo.ck.listenerdemo;
    
    import android.app.ActivityManager;
    import android.app.KeyguardManager;
    import android.content.Context;
    import android.content.Intent;
    import android.content.pm.ApplicationInfo;
    import android.content.pm.PackageManager;
    import android.content.pm.ResolveInfo;
    import android.os.Looper;
    import android.widget.Toast;
    
    import java.lang.reflect.Field;
    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.List;
    
    /**
     * Description: Activity反劫持检测工具
     */
    public class ViewInterceptUtil {
        public static void check(final Context context) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    // 白名单
                    boolean safe = ViewInterceptUtil.checkActivity(context.getApplicationContext());
                    // 系统桌面
                    boolean isHome = ViewInterceptUtil.isHome(context.getApplicationContext());
                    // 锁屏操作
                    boolean isReflectScreen = ViewInterceptUtil.isReflectScreen(context.getApplicationContext());
                    // 判断程序是否当前显示
                    if (!safe && !isHome && !isReflectScreen) {
                        Looper.prepare();
                        Toast.makeText(context.getApplicationContext(), "注意-------",
                                Toast.LENGTH_LONG).show();
                        Looper.loop();
                    }
                }
            }).start();
        }
    
        /**
         * 检测当前Activity是否安全
         */
        public static boolean checkActivity(Context context) {
            PackageManager pm = context.getPackageManager();
            // 查询所有已经安装的应用程序
            List<ApplicationInfo> listAppcations =
                    pm.getInstalledApplications(PackageManager.GET_UNINSTALLED_PACKAGES);
            Collections.sort(listAppcations, new ApplicationInfo.DisplayNameComparator(pm));// 排序
    
            List<String> safePackages = new ArrayList<>();
            // 得到所有的系统程序包名放进白名单里面.
    //        for (ApplicationInfo app : listAppcations) {// 这个排序必须有.
    //            if ((app.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
    //                safePackages.add(app.packageName);
    //            }
    //        }
    
            String runningActivityPackageName = getCurrentPkgName(context);
            if (runningActivityPackageName != null) {
                // 有些情况下在5x的手机中可能获取不到当前运行的包名,所以要非空判断。
                if (runningActivityPackageName.equals(context.getPackageName())) {
                    return true;
                }
                // 白名单比对
                for (String safePack : safePackages) {
                    if (safePack.equals(runningActivityPackageName)) {
                        return true;
                    }
                }
            }
            return false;
        }
    
        private static String getCurrentPkgName(Context context) {
            // 5x系统以后利用反射获取当前栈顶activity的包名.
            ActivityManager.RunningAppProcessInfo currentInfo = null;
            Field field = null;
            int START_TASK_TO_FRONT = 2;
            String pkgName = null;
            try {
                // 通过反射获取进程状态字段.
                field = ActivityManager.RunningAppProcessInfo.class.getDeclaredField("processState");
            } catch (Exception e) {
                e.printStackTrace();
            }
            ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
            List appList = am != null ? am.getRunningAppProcesses() : null;
            ActivityManager.RunningAppProcessInfo app;
            for (int i = 0; i < (appList != null ? appList.size() : 0); i++) {
                //ActivityManager.RunningAppProcessInfo app : appList
                app = (ActivityManager.RunningAppProcessInfo) appList.get(i);
                //表示前台运行进程.
                if (app.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
                    Integer state = null;
                    try {
                        state = field != null ? field.getInt(app) : 0;// 反射调用字段值的方法,获取该进程的状态.
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    // 根据这个判断条件从前台中获取当前切换的进程对象
                    if (state != null && state == START_TASK_TO_FRONT) {
                        currentInfo = app;
                        break;
                    }
                }
            }
            if (currentInfo != null) {
                pkgName = currentInfo.processName;
            }
            return pkgName;
        }
    
        /**
         * 判断当前是否在桌面
         *
         * @param context 上下文
         */
        public static boolean isHome(Context context) {
            ActivityManager mActivityManager =
                    (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
            List<ActivityManager.RunningTaskInfo> rti = mActivityManager.getRunningTasks(1);
            return getHomes(context).contains(rti.get(0).topActivity.getPackageName());
        }
    
        /**
         * 获得属于桌面的应用的应用包名称
         *
         * @return 返回包含所有包名的字符串列表
         */
        private static List<String> getHomes(Context context) {
            List<String> names = new ArrayList<String>();
            PackageManager packageManager = context.getPackageManager();
            Intent intent = new Intent(Intent.ACTION_MAIN);
            intent.addCategory(Intent.CATEGORY_HOME);
            List<ResolveInfo> resolveInfo = packageManager.queryIntentActivities(intent,
                    PackageManager.MATCH_DEFAULT_ONLY);
            for (ResolveInfo ri : resolveInfo) {
                names.add(ri.activityInfo.packageName);
            }
            return names;
        }
    
        /**
         * 判断当前是否在锁屏再解锁状态
         *
         * @param context 上下文
         */
        public static boolean isReflectScreen(Context context) {
            KeyguardManager mKeyguardManager =
                    (KeyguardManager) context.getSystemService(Context.KEYGUARD_SERVICE);
            if (mKeyguardManager != null) {
                return mKeyguardManager.isKeyguardLocked();
            }
            return false;
        }
    }
    
    
    

    四、参考

    https://dun.163.com/news/p/47d0c43eb1854bae91872edc656dbd9e
    https://www.jianshu.com/p/d4677e837648

    展开全文
  • Android登录界面防止被劫持,目前没有好的反劫持方法,只能提醒用户登陆界面劫持,具体实施如下: 涉及到的工具类: import android.app.ActivityManager; import android.app.KeyguardManager; import ...

    Android登录界面防止被劫持,目前没有好的反劫持方法,只能提醒用户登陆界面被劫持,具体实施如下:

    涉及到的工具类:

     

    
    
    import android.app.ActivityManager;
    import android.app.KeyguardManager;
    import android.content.Context;
    import android.content.Intent;
    import android.content.pm.ApplicationInfo;
    import android.content.pm.PackageManager;
    import android.content.pm.ResolveInfo;
    
    import java.lang.reflect.Field;
    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.List;
    
    /**
     *
     * Activity反劫持检测工具
     *
     * 在用户使用app的时候,如果被恶意程序劫持跳转到别的界面,
     * 这个时候我们就要做出预警提示用户,告诉用户当前界面已经不是我们的app有潜在的危险.
     * 代码的工作原理很简单就是在我们所写的activity对象的Onstop生命周期判断,
     * 将要跳转的界面是否是安全的。具体代码如下:
     *
     * created by ww 2/22/21 11:30 AM
     */
    
    public class AntiHijackingUtil {
        public static final String TAG = "AntiHijackingUtil";
    
    
        /**
         * 检测当前Activity是否安全
         */
        public static boolean checkActivity(Context context) {
            PackageManager pm = context.getPackageManager();
            // 查询所有已经安装的应用程序
            List<ApplicationInfo> listAppcations =
                    pm.getInstalledApplications(PackageManager.GET_UNINSTALLED_PACKAGES);
            Collections.sort(listAppcations, new ApplicationInfo.DisplayNameComparator(pm));// 排序
    
    
            List<String> safePackages = new ArrayList<>();
            for (ApplicationInfo app : listAppcations) {// 这个排序必须有.
                if ((app.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
                    safePackages.add(app.packageName);
                }
            }
            // 得到所有的系统程序包名放进白名单里面.
            ActivityManager activityManager =
                    (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
            String runningActivityPackageName;
            int sdkVersion;
            try {
                sdkVersion = Integer.valueOf(android.os.Build.VERSION.SDK);
            } catch (NumberFormatException e) {
                sdkVersion = 0;
            }
            if (sdkVersion >= 21) {// 获取系统api版本号,如果是5x系统就用这个方法获取当前运行的包名
                runningActivityPackageName = getCurrentPkgName(context);
            } else {
                runningActivityPackageName =
                        activityManager.getRunningTasks(1).get(0).topActivity.getPackageName();
            }
            // 如果是4x及以下,用这个方法.
            if (runningActivityPackageName != null) {
                // 有些情况下在5x的手机中可能获取不到当前运行的包名,所以要非空判断。
                if (runningActivityPackageName.equals(context.getPackageName())) {
                    return true;
                }
                // 白名单比对
                for (String safePack : safePackages) {
                    if (safePack.equals(runningActivityPackageName)) {
                        return true;
                    }
                }
            }
            return false;
        }
    
    
        private static String getCurrentPkgName(Context context) {
            // 5x系统以后利用反射获取当前栈顶activity的包名.
            ActivityManager.RunningAppProcessInfo currentInfo = null;
            Field field = null;
            int START_TASK_TO_FRONT = 2;
            String pkgName = null;
            try {
                // 通过反射获取进程状态字段.
                field = ActivityManager.RunningAppProcessInfo.class.getDeclaredField("processState");
            } catch (Exception e) {
                e.printStackTrace();
            }
            ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
            List appList = am.getRunningAppProcesses();
            ActivityManager.RunningAppProcessInfo app;
            for (int i = 0; i < appList.size(); i++) {
                //ActivityManager.RunningAppProcessInfo app : appList
                app = (ActivityManager.RunningAppProcessInfo) appList.get(i);
                //表示前台运行进程.
                if (app.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
                    Integer state = null;
                    try {
                        state = field.getInt(app);// 反射调用字段值的方法,获取该进程的状态.
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    // 根据这个判断条件从前台中获取当前切换的进程对象
                    if (state != null && state == START_TASK_TO_FRONT) {
                        currentInfo = app;
                        break;
                    }
                }
            }
            if (currentInfo != null) {
                pkgName = currentInfo.processName;
            }
            return pkgName;
        }
    
    
        /**
         * 判断当前是否在桌面
         *
         * @param context 上下文
         */
        public static boolean isHome(Context context) {
            ActivityManager mActivityManager =
                    (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
            List<ActivityManager.RunningTaskInfo> rti = mActivityManager.getRunningTasks(1);
            return getHomes(context).contains(rti.get(0).topActivity.getPackageName());
        }
    
    
        /**
         * 获得属于桌面的应用的应用包名称
         *
         * @return 返回包含所有包名的字符串列表
         */
        private static List<String> getHomes(Context context) {
            List<String> names = new ArrayList<String>();
            PackageManager packageManager = context.getPackageManager();
            Intent intent = new Intent(Intent.ACTION_MAIN);
            intent.addCategory(Intent.CATEGORY_HOME);
            List<ResolveInfo> resolveInfo = packageManager.queryIntentActivities(intent,
                    PackageManager.MATCH_DEFAULT_ONLY);
            for (ResolveInfo ri : resolveInfo) {
                names.add(ri.activityInfo.packageName);
            }
            return names;
        }
    
    
        /**
         * 判断当前是否在锁屏再解锁状态
         *
         * @param context 上下文
         */
        public static boolean isReflectScreen(Context context) {
            KeyguardManager mKeyguardManager =
                    (KeyguardManager) context.getSystemService(Context.KEYGUARD_SERVICE);
            return mKeyguardManager.inKeyguardRestrictedInputMode();
        }
    }

    使用方法:

         在onPause()方法中调用,提醒用户

     @Override
        protected void onPause() {
            //若程序进入后台不是用户自身造成的,则需要弹出警示
    //        if(needAlarm) {
                //弹出警示信息
    //            Toast.makeText(getApplicationContext(), "您的登陆界面被覆盖,请确认登陆环境是否安全", Toast.LENGTH_SHORT).show();
    //            //启动我们的AlarmService,用于给出覆盖了正常Activity的类名
    //            Intent intent = new Intent(this, AlarmService.class);
    //            startService(intent);
    //        }
            new Thread(new Runnable() {
                @Override
                public void run() {
                    // 白名单
                    boolean safe = AntiHijackingUtil.checkActivity(getApplicationContext());
                    // 系统桌面
                    boolean isHome = AntiHijackingUtil.isHome(getApplicationContext());
                    // 锁屏操作
                    boolean isReflectScreen = AntiHijackingUtil.isReflectScreen(getApplicationContext());
                    // 判断程序是否当前显示
                    if (!safe && !isHome && !isReflectScreen) {
                        Looper.prepare();
                        Toast.makeText(getApplicationContext(), "您的登陆界面被覆盖,请确认登陆环境是否安全",
                                Toast.LENGTH_LONG).show();
                        Looper.loop();
                    }
                }
            }).start();
            super.onPause();
    
        }
    
    展开全文
  • 在用户使用app的时候,如果被恶意程序劫持跳转到别的界面,这个时候我们就要做出预警提示用户,告诉用户当前界面已经不是我们的app有潜在的危险.代码的工作原理很简单就是在我们所写的activity对象的Onstop生命周期判断...

     在用户使用app的时候,如果被恶意程序劫持跳转到别的界面,这个时候我们就要做出预警提示用户,告诉用户当前界面已经不是我们的app有潜在的危险.代码的工作原理很简单就是在我们所写的activity对象的Onstop生命周期判断,将要跳转的界面是否是安全的。

           具体代码如下

    [java] view plain copy
     
    1. public class AntiHijackingUtil {  
    2.       
    3.     public static final String TAG = "AntiHijackingUtil";  
    4.       
    5.     // 白名单列表  
    6.     private static List<String> safePackages;  
    7.       
    8.     static {  
    9.         safePackages = new ArrayList<String>();  
    10.     }  
    11.       
    12.     public static void configSafePackages(List<String> packages) {  
    13.         return;  
    14.     }  
    15.     private static PackageManager pm;  
    16.     private List<ApplicationInfo> mlistAppInfo;    
    17.     /** 
    18.      * 检测当前Activity是否安全 
    19.      */  
    20.     public static boolean checkActivity(Context context) {  
    21.          boolean safe = false;  
    22.          pm = context.getPackageManager();    
    23.             // 查询所有已经安装的应用程序    
    24.             List<ApplicationInfo> listAppcations = pm.getInstalledApplications(PackageManager.GET_UNINSTALLED_PACKAGES);    
    25.             Collections.sort(listAppcations,new ApplicationInfo.DisplayNameComparator(pm));// 排序    
    26.             List<ApplicationInfo> appInfos = new ArrayList<ApplicationInfo>(); // 保存过滤查到的AppInfo    
    27.             //appInfos.clear();    
    28.          for (ApplicationInfo app : listAppcations) {//这个排序必须有.    
    29.              if ((app.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {    
    30.                  //appInfos.add(getAppInfo(app));    
    31.                 safePackages.add(app.packageName);  
    32.              }    
    33.          }   
    34.          //得到所有的系统程序包名放进白名单里面.  
    35.           
    36.         ActivityManager activityManager =(ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);  
    37.         String runningActivityPackageName;  
    38.         int sdkVersion;   
    39.           
    40.         try {    
    41.             sdkVersion = Integer.valueOf(android.os.Build.VERSION.SDK);    
    42.         } catch (NumberFormatException e) {    
    43.             sdkVersion = 0;    
    44.         }   
    45.           
    46.         if(sdkVersion>=21){//获取系统api版本号,如果是5x系统就用这个方法获取当前运行的包名  
    47.             runningActivityPackageName= getCurrentPkgName(context);  
    48.         }  
    49.         else runningActivityPackageName=activityManager.getRunningTasks(1).get(0).topActivity.getPackageName();  
    50.         //如果是4x及以下,用这个方法.  
    51.                
    52.            
    53.         if(runningActivityPackageName!=null){//有些情况下在5x的手机中可能获取不到当前运行的包名,所以要非空判断。  
    54.            if (runningActivityPackageName.equals(context.getPackageName())) {     
    55.               safe = true;  
    56.            }  
    57.           
    58.             // 白名单比对  
    59.            for (String safePack : safePackages) {  
    60.                if (safePack.equals(runningActivityPackageName)) {  
    61.                    safe = true;  
    62.                }  
    63.            }  
    64.         }  
    65.           
    66.         return safe;          
    67.     }  
    68.       
    69.       
    70.       
    71.     public static String getCurrentPkgName(Context context) {//5x系统以后利用反射获取当前栈顶activity的包名.  
    72.         ActivityManager.RunningAppProcessInfo currentInfo = null;  
    73.         Field field = null;  
    74.         int START_TASK_TO_FRONT = 2;  
    75.         String pkgName = null;  
    76.           
    77.         try {  
    78.             field = ActivityManager.RunningAppProcessInfo.class.getDeclaredField("processState");//通过反射获取进程状态字段.  
    79.         } catch (Exception e) {  
    80.             e.printStackTrace();  
    81.         }  
    82.         ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);  
    83.         List appList = am.getRunningAppProcesses();  
    84.         ActivityManager.RunningAppProcessInfo app;  
    85.           
    86.         for (int i=0;i<appList.size();i++){  
    87.             //ActivityManager.RunningAppProcessInfo app : appList  
    88.             app=(RunningAppProcessInfo) appList.get(i);  
    89.             if (app.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {//表示前台运行进程.  
    90.                 Integer state = null;  
    91.                 try {  
    92.                     state = field.getInt(app);//反射调用字段值的方法,获取该进程的状态.  
    93.                 } catch (Exception e) {  
    94.                     e.printStackTrace();  
    95.                 }  
    96.                 if (state != null && state == START_TASK_TO_FRONT) {//根据这个判断条件从前台中获取当前切换的进程对象.  
    97.                     currentInfo = app;  
    98.                     break;  
    99.                 }  
    100.             }  
    101.         }  
    102.           
    103.         if (currentInfo != null) {  
    104.             pkgName = currentInfo.processName;  
    105.         }  
    106.         return pkgName;  
    107.     }  
    108. }  

              代码的 使用方法也很简单,只需要在你自己写的Activity的Onstop中调用boolean safe = AntiHijackingUtil.checkActivity(this);即可得到跳转的界面是否需要提示.

     

              这里要说明一下 getCurrentPkgName()在有些5x手机也无法获取当前跳入的界面的包名,有了解的还请提示一下,谢谢。

     

    展开全文
  • 当程序处于后台时弹窗提醒,防止其他APP界面劫持 1. 实现对APP所有Activity生命周期的监控 顶层activity中onStope方法被执行,则认为程序处于后台。由于Activity被销毁或者activity不再处于栈顶时也会调用onStop方法...

    当程序处于后台时弹窗提醒,防止其他APP界面劫持

    1. 实现对APP所有Activity生命周期的监控

    顶层activity中onStope方法被执行,则认为程序处于后台。由于Activity被销毁或者activity不再处于栈顶时也会调用onStop方法所以要加判断排除这两种情况。

      private static int started;
      private static int stopped;
       @Override
        public void onActivityStarted(Activity activity) {
            ++started;
        }
          @Override
        public void onActivityStopped(final Activity activity) {
            ++stopped;
             if (isApplicationInBackground()) {
            //..........弹窗前要做些判断排除activity被销毁时执行这种情况.....
            }
        }
       public static boolean isApplicationInBackground() {
            return started == stopped;
        }
    
    2. 使用防界面劫持工具类

    在Application中注册ActivityLifecycleCallbacks

    public class MyApplication extends Application {
    
     @Override
        public void onCreate() {
            super.onCreate();
            registerActivityLifecycleCallbacks(
                    new NewsLifecycleHandler("安监应用切换至后台")//被劫持时的提示语
                            .setUnnoticeActivity("StartActivity")// 该activity处于栈顶 时程序处于后台,但是不提示
                            .setDestroyedActivity("LoginActivity", "MainActivity")//栈内唯一activity被销毁,时不提示。例如在登录界面退出程序此时栈内只有LoginActivity退出会执行onStop方法触发弹出框所以要加判断防止误报
            );
        }
    }
    
    3. 防劫持工具类源码
    import android.app.Activity;
    import android.app.Application;
    import android.os.Bundle;
    import android.util.Log;
    import android.widget.Toast;
    
    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.List;
    import java.util.Timer;
    
    /**
     * 程序中任何一个activity处于后台时(onStope)都将触发提醒
     */
    public class NewsLifecycleHandler implements Application.ActivityLifecycleCallbacks {
        // I use four separate variables here. You can, of course, just use two and
        // increment/decrement them instead of using four and incrementing them all.
        private static int resumed;
        private static int paused;
        private static int started;
        private static int stopped;
        private static int destroyed;
        private String msg;
        private List<String> destroyActivities = new ArrayList<>();
        private List<String> unnoticeActivities = new ArrayList<>();
        private boolean flag = true;
    
    
        /**
         * 用于执行定时任务
         */
        private Timer timer = null;
    
        /**
         * @param msg 程序进入后台提示用于
         */
        public NewsLifecycleHandler(String msg) {
            resetVariables();
            this.msg = msg;
        }
    
        /**
         * 由于销毁activity时会触发onStop方法,所以在这里设置,避免误报
         *
         * @return
         */
        public NewsLifecycleHandler setDestroyedActivity(String... activityName) {
            Collections.addAll(this.destroyActivities, activityName);
            return this;
        }
    
        /**
         * 该Activities处于后台时不提示
         *
         * @param activityName
         * @return
         */
        public NewsLifecycleHandler setUnnoticeActivity(String... activityName) {
            Collections.addAll(this.unnoticeActivities, activityName);
            return this;
        }
    
        public void resetVariables() {
            resumed = 0;
            paused = 0;
            started = 0;
            stopped = 0;
            flag = true;
        }
    
    
        @Override
        public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
            Log.i("test", "onActivityCreated-----" + activity.getClass().getSimpleName());
        }
    
        @Override
        public void onActivityDestroyed(Activity activity) {
            destroyed++;
            if (destroyActivities.contains(activity.getClass().getSimpleName())) {
                Log.i("test", "进入标志位判定" + activity.getClass().getSimpleName());
                flag = false;
            }
            Log.i("test", "onActivityDestroyed-----" + activity.getClass().getSimpleName());
        }
    
        @Override
        public void onActivityResumed(Activity activity) {
            ++resumed;
        }
    
        @Override
        public void onActivityPaused(Activity activity) {
            ++paused;
        }
    
        @Override
        public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
        }
    
        @Override
        public void onActivityStarted(Activity activity) {
            ++started;
        }
    
    
        @Override
        public void onActivityStopped(final Activity activity) {
            ++stopped;
            if (isApplicationInBackground()) {
                flag = true;
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        try {
                            Thread.sleep(500);//暂停500毫秒 让以下代码后于onDestroy方法执行,用来判断是否是栈内唯一Activity被销毁才触发onStop方法。
                            Log.i("test", "stopped-----" + activity.getClass().getSimpleName());
                            activity.runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    Log.i("test", "执行前flag " + flag + " " + activity.getClass().getSimpleName());
                                    if (flag && !unnoticeActivities.contains(activity.getClass().getSimpleName())) {
                                        Toast.makeText(activity, msg, Toast.LENGTH_SHORT).show();
                                    }
                                }
                            });
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }).start();
            }
        }
    
        // If you want a static function you can use to check if your application is
        // foreground/background, you can use the following:
    
    
        public static boolean isApplicationVisible() {
            return started > stopped;
        }
    
        public static boolean isApplicationInForeground() {
            return resumed > paused;
        }
    
        public static boolean isApplicationInBackground() {
            return started == stopped;
        }
    
    }
    
    
    展开全文
  • 其原理是利用透明层+iframe,使用了css中的opacity和z-index等属性,来到达透明和位于其它界面的上方,然后使用iframe来嵌入劫持页面。到达了用户操作的不是它看到的,不是他以为的那个界面,而是那个透明的位于上层...
  • 1,首先要对自己应用的activity建立一个白名单 2,权限  android:name="android.permission.GET_TASKS" /> 3, import android.app.Activity; import android.app.ActivityManager;...import android.app.Applicatio
  • 梆梆SDKs详细分析(1) – 防界面劫持SDK梆梆SDKs详细分析(2) – 安全键盘SDK揭秘DroidSec.cnANDROID安全中文站 Activity劫持实例与防护手段
  • Android 防界面劫持方案 无视Android系统版本限制,无需操作栈 Demo下载地址:http://download.csdn.net/detail/prince_wenzheng/9742068
  • Android防劫持

    2017-03-19 14:14:38
    在用户使用app的时候,如果被恶意程序劫持跳转到别的界面,这个时候我们就要做出预警提示用户,告诉用户当前界面已经不是我们的app有潜在的危险.代码的工作原理很简单就是在我们所写的activity对象的Onstop生命周期判断...
  • 梆梆的防界面劫持SDK里面提供了两个APK,一个是防界面劫持demo,我们可以称它为demo1,界面如图1。从图中可以看出,梆梆的SDK提供了基类和接口两种方式来防御界面劫持。 图1 另一个就是界面劫持demo,我们可以称它...
  • 梆梆SDKs详细分析-防界面劫持SDK

    千次阅读 2016-02-16 10:29:27
     梆梆的防界面劫持SDK里面提供了两个APK,一个是防界面劫持demo,我们可以称它为demo1,界面如图1。从图中可以看出,梆梆的SDK提供了基类和接口两种方式来防御界面劫持。 图1    另一个就是...
  •  梆梆的防界面劫持SDK里面提供了两个APK,一个是防界面劫持demo,我们可以称它为demo1,界面如图1。从图中可以看出,梆梆的SDK提供了基类和接口两种方式来防御界面劫持。 图1  另一个就是界面劫持demo,我们...
  • Android之Activity劫持实例与防护手段

    千次阅读 2019-12-02 17:15:41
    一、什么叫Activity劫持 这里举一个例子。用户打开安卓手机上的某一应用,进入到登陆页面,这时,恶意软件侦测到用户的这一动作,立即弹出一个与该应用 界面相同的Activity,覆盖掉了合法的Activity,用户几乎无法...
  • App客户端劫持及简单防护

    千次阅读 2018-07-02 12:33:34
    转自:http://blog.nsfocus.net/app-client-hijacking-simple-protection/Android APP客户端安全评估中,有一项叫做activity界面劫持。该bug的攻击场景是,当手机中的恶意APP检测到当前运行的为目标APP时,就启动...
  • 什么叫Activity劫持 这里举一个例子。用户打开安卓手机上的某一应用,进入到登陆页面,这时,恶意软件侦测到用户的这一动作,立即弹出一个与该应用 界面相同的Activity,覆盖掉了合法的Activity,用户几乎无法察觉...
  • Android APP客户端安全评估中,有一项叫做activity界面劫持。该bug的攻击场景是,当手机中的恶意APP检测到当前运行的为目标APP时,就启动自身的钓鱼界面覆盖到目标APP之上,以欺骗用户输入账号密码等。本文将要归纳...
  • 举一个例子,用户打开安卓手机上的某一应用例如支付宝,进入到登陆页面,这时恶意软件检测到用户的这一动作,立即弹出一个与支付宝界面相同的 Activity,覆盖掉了合法的 Activity,用户几乎无法察觉,该用户接下来...
  • Android APP客户端安全评估中,有一项叫做activity界面劫持。 该bug的攻击场景是,当手机中的恶意APP检测到当前运行的为目标APP时,就启动自身的钓鱼界面覆盖到目标APP之上,以欺骗用户输入账号密码等。   本文...
  • cookie劫持

    2020-08-02 19:03:28
    XSS是什么?它的全名是:Cross-sitescripting,为了和CSS层叠样式表区分所以取名XSS。是一种网站应用程序的安全漏洞攻击,是代码注入的一种。它允许恶意用户将代码注入到网页上,...预防措施,防止下发界面显示html标签

空空如也

空空如也

1 2 3 4
收藏数 62
精华内容 24
关键字:

界面防劫持