The text explains the specific method of Activity hijacking protection in Android. The project developed by the company has the problem of Activity hijacking in the security check. On the Internet there are a lot of Activity hijacking protection practices have problems, I improve some methods hope to share with you.

What is Activity hijacking

In order to improve the user experience of Android, switching between different applications is basically seamless. For example, when a user opens an application such as Alipay on an Android phone and enters the landing page, the malware detects the user’s action and immediately pops up an Activity with the same interface as Alipay. The legitimate Activity is overwritten, and the user can hardly detect it. The user then enters the username and password on the malware Activity, so you can imagine what happens next. Specific Activity hijack principles can refer to this article as follows: blog.csdn.net/nailsoul/ar…

Aliju Security The security component SDK of Aliju security has the functions of secure signature, secure encryption, secure storage, simulator detection, anti-debugging, anti-injection, anti-activity hijacking and so on. Developers only need to integrate the SECURITY component SDK to effectively solve the problem of login Windows being hijacked by Trojan viruses, thus helping users and enterprises reduce losses.

Protective measures

Currently, there is no specific protection against Activity hijacking, because such attacks are user-level and cannot be eradicated at the code level. However, we can appropriately give users some warning messages in the APP to remind them that their login screen is overwritten. I checked many solutions on the Internet as follows:

  • The encapsulated AntiHijackingUtil class (check system program whitelist) is called in Acitivity’s onStop method to check whether the program is overwritten by system programs.
  • Override the onKeyDown and onPause methods in the normal Activity login screen created earlier to determine whether the application entered the background by the user (by touching the back button or the HOME button) so that when it is overwritten, You can pop up an alert.

The AntiHijackingUtil class code looks like this:

/** * Description: Activity * author: zs * Date: 2018/7/8 16:31 */ public class AntiHijackingUtil { public static final String TAG ="AntiHijackingUtil"; 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)); // Sort List<String> safePackages = new ArrayList<>();for(ApplicationInfo app: listAppcations) {// This sort must have.if((app.flags & ApplicationInfo.FLAG_SYSTEM) ! = 0) { safePackages.add(app.packageName); }} // Whitelist all system package names. 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) {/ / acquisition system API version number, if it is 5 x system will use this method to get the currently running package name runningActivityPackageName = getCurrentPkgName (context); }else{ runningActivityPackageName = activityManager.getRunningTasks(1).get(0).topActivity.getPackageName(); } // If 4x or less, use this method.if(runningActivityPackageName ! = null) {// In some cases, the current package name can not be obtained on the 5x phone, so it is not null.if (runningActivityPackageName.equals(context.getPackageName())) {
                return true; } // Whitelist alignmentfor (String safePack : safePackages) {
                if (safePack.equals(runningActivityPackageName)) {
                    return true; }}}return false; } private static String getCurrentPkgName(Context Context) {private static String getCurrentPkgName(Context Context) { ActivityManager.RunningAppProcessInfo currentInfo = null; Field field = null; int START_TASK_TO_FRONT = 2; String pkgName = null; Try {/ / by reflection for process status field. The 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); // Indicates the foreground running process.if(app.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) { Integer state = null; try { state = field.getInt(app); } catch (Exception e) {e.printStackTrace();} catch (Exception e) {e.printStackTrace(); } // Get the currently switched process object from the foreground according to this judgment conditionif(state ! = null && state == START_TASK_TO_FRONT) { currentInfo = app;break; }}}if(currentInfo ! = null) { pkgName = currentInfo.processName; }returnpkgName; } public static Boolean isHome(Context context) {ActivityManager mActivityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); List<ActivityManager.RunningTaskInfo> rti = mActivityManager.getRunningTasks(1);returngetHomes(context).contains(rti.get(0).topActivity.getPackageName()); } /** * get the package name ** @ of the application that belongs to the desktopreturn*/ 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);
        }
        returnnames; } public static Boolean isReflectScreen(context context) { KeyguardManager mKeyguardManager = (KeyguardManager) context.getSystemService(Context.KEYGUARD_SERVICE);returnmKeyguardManager.inKeyguardRestrictedInputMode(); }}Copy the code

However, there are problems with both methods. The Android onKeyDown method currently does not listen to the HOME button at all. You can try it in code. The AntiHijackingUtil class only detects system programs and warns that code cannot be checked while the screen is locked. Click the HOME button and lock the screen while unlocking the app.

Improvement of protection method

The expected goals we want to achieve are as follows:

  • Users voluntarily quit the APP (back button, HOME button) in this case, we do not need to give users a pop-up warning
  • When the APP locks the screen and then unlocks it, we do not need to give users a pop-up warning
  • Give a reasonable warning when other apps suddenly overwrite our APP

APP returns the detection code for desktop, screen lock and unlock

Public static Boolean isHome(Context Context) {ActivityManager mActivityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); List<ActivityManager.RunningTaskInfo> rti = mActivityManager.getRunningTasks(1);returngetHomes(context).contains(rti.get(0).topActivity.getPackageName()); } /** * get the package name ** @ of the application that belongs to the desktopreturn*/ 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);
        }
        returnnames; } public static Boolean isReflectScreen(context context) { KeyguardManager mKeyguardManager = (KeyguardManager) context.getSystemService(Context.KEYGUARD_SERVICE);return mKeyguardManager.inKeyguardRestrictedInputMode();
    }
Copy the code

And checks in the onStop method to see if a warning alert needs to pop up

   @Override
    protected void onStop() {
        super.onStop();
        new Thread(new Runnable() {
            @Override
            public void run() {/ / white list Boolean safe = AntiHijackingUtil. CheckActivity (getApplicationContext ()); Boolean isHome = Antihijackingutil.ishome (getApplicationContext()); / / lock screen Boolean operation isReflectScreen = AntiHijackingUtil. IsReflectScreen (getApplicationContext ()); // Check whether the program is currently displayedif(! safe && ! isHome && ! isReflectScreen) { Looper.prepare(); Toast.makeText(getApplicationContext(), R.string.activity_safe_warning, Toast.LENGTH_LONG).show(); Looper.loop(); } } }).start(); }Copy the code

Feeling the problem solved, let’s click on the notification bar to open other applications to simulate malware overwriting our APP and see how it works

All code synchronized to GitHub: github.com/christian-z…