Android防劫持

在用戶使用app的時候,如果被惡意程序劫持跳轉到別的界面,這個時候我們就要做出預警提示用戶,告訴用戶當前界面已經不是我們的app有潛在的危險.代碼的工作原理很簡單就是在我們所寫的activity對象的Onstop生命週期判斷,將要跳轉的界面是否是安全的

  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.     }  

代碼的 使用方法也很簡單,只需要在你自己寫的Activity的Onstop中調用boolean safe = AntiHijackingUtil.checkActivity(this);即可得到跳轉的界面是否需要提示.


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章