当前位置:网站首页>AMS advanced - how to start an unregistered activity

AMS advanced - how to start an unregistered activity

2022-06-09 08:17:00 Straw hat learning programming

background :

We have combed the past Activity Start the whole process know :Activity The startup of the system mainly goes through the following stages :

  • launch Activity start-up
  • And AMS Establish communication node , Mainly in the Instrumentation Get in class AMS Of Binder agent , Prepare for communication .
  • Switch from application process to system process (system_service) Of AMS service , from AMS Determine whether the application process is created , If not, then AMS And Zegote Process communication creates an application process .
  • After the application process is created , Start the application process , Then the application process switches to AMS service ,AMS Further startup Activity The check ( Such as :Activity Whether to register, etc ).
  • start-up Activity, stay ActivityThread Of Handler In the implementation of Activity Life cycle

  We all know that under normal circumstances, we need to start a Activity Must be in AndroidManifest Register this in the file Activity. So is there any way to start without registering ?

By reading the source code , We know AMS One of our jobs is to serve Activity Start up management of . In this process, the to be started Activity Carry out a series of tests , Like here Activity Whether to register or not is AMS A link of inspection . It is necessary to start without registration Must cheat AMS The test of . So the plan is to pass Hook AMS and ActivityThread Medium Handler To achieve .

  One 、Hook AMS

         If you want to cheat AMS Start up inspection of , That must be in AMS Of StartActivity Intercept and replace before inspection Intent The target pointed to in the object Activity For registered agents Activity. such AMS During the inspection, the agent is the one to be inspected Activity. So as to cheat AMS The purpose of the inspection .

         After the process of the previous section , We can go through Hook obtain AMS Communication nodes to achieve interception AMS Of startActivity Method , Replace before inspection Intent Purpose

 

 

public static void hookAms(){
    try {

        //  obtain Singleton object 
        Class<?> clazz = Class.forName("android.app.ActivityManager");
        Field singletonField = clazz.getDeclaredField("IActivityManagerSingleton");
        singletonField.setAccessible(true);
        Object singleton = singletonField.get(null);

        //  obtain IActivityManager  object 
        Class<?> singletonClass = Class.forName("android.util.Singleton");
        Field mInstanceField = singletonClass.getDeclaredField("mInstance");
        mInstanceField.setAccessible(true);
        final Object mInstance = mInstanceField.get(singleton);


        Class<?> iActivityManagerClass = Class.forName("android.app.IActivityManager");

        Object proxyInstance = Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),
                new Class[]{iActivityManagerClass}, new InvocationHandler() {

                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        // IActivityManager  When the method of , Will run here first 
                        Log.d(TAG,"methodName="+method.getName());
                        if ("startActivity".equals(method.getName())) {
                            //  Replace Intent
                            int index = 0;

                            for (int i = 0; i < args.length; i++) {
                                if (args[i] instanceof Intent) {
                                    index = i;
                                    break;
                                }
                            }
                            //  Start the plug-in intent
                            Intent intent = (Intent) args[index];

                            Intent proxyIntent = new Intent();
                            // there packageName To fill in Activity Package name of the main project , That is, the application package name , instead of Activity Class 
                            proxyIntent.setClassName("com.single.code.app.plugin",
                                    "com.single.code.app.pluginlib.PluginProxyActivity");

                            //  Keep the original 
                            proxyIntent.putExtra(TARGET_INTENT, intent);
                            Log.e(TAG, "startActivity: proxyIntent intent ="+proxyIntent);
                            Log.e(TAG, "startActivity: target intent ="+intent);
                            args[index] = proxyIntent;
                        }
                        return method.invoke(mInstance, args);
                    }

                });

        //  Replace the  IActivityManager object 
        mInstanceField.set(singleton, proxyInstance);

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

  Two 、Hook Handler

         adopt Hook AMS To replace Intent To deceive AMS Of Activity After starting the inspection , We still need to Activity Before it is really started Intent Replace with the real goal Activity, Otherwise, it will be found that our agent is starting Activity 了 . Also by combing Activity Start the process we know ,Activity after AMS After a series of tests, it was finally ActivityThread Of Handler Start and execute the lifecycle in .

So all we have to do is Activity Start the execution lifecycle again before Intent Just replace it . and ActivityThread Of mH Attribute is a perfect Hook spot .

public static void hookHandler(){
    try {
        Class<?> clazz = Class.forName("android.app.ActivityThread");
        Field sCurrentActivityThreadField = clazz.getDeclaredField("sCurrentActivityThread");
        sCurrentActivityThreadField.setAccessible(true);
        Object activityThread = sCurrentActivityThreadField.get(null);

        Field mHField = clazz.getDeclaredField("mH");
        mHField.setAccessible(true);
        Object mH = mHField.get(activityThread);

        // new  One  Callback  Replace the  mCallback object 
        Class<?> handlerClass = Class.forName("android.os.Handler");
        Field mCallbackField = handlerClass.getDeclaredField("mCallback");
        mCallbackField.setAccessible(true);
        mCallbackField.set(mH, new Handler.Callback() {
            @Override
            public boolean handleMessage(@NonNull Message msg) {
                //  take Intent Change back 
                Log.e(TAG, "handleMessage:"+msg);
                switch (msg.what) {
                    case 100:
                        try {
                            //  obtain ActivityClientRecord Medium intent object 
                            Field intentField = msg.obj.getClass().getDeclaredField("intent");
                          
                            intentField.setAccessible(true);
                            Intent proxyIntent = (Intent) intentField.get(msg.obj);

                            //  Get the plug-in Intent
                            Intent intent = proxyIntent.getParcelableExtra(TARGET_INTENT);
                           if(intent != null){
                               Log.e(TAG, "handleMessage: " + intent);
                               //  Replace it with 
                               proxyIntent.setComponent(intent.getComponent());
                           }
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        break;
                    case 159:
                        try {
                            Class<?> clazz = Class.forName("android.app.servertransaction.ClientTransaction");
                            Field mActivityCallbacksField = clazz.getDeclaredField("mActivityCallbacks");
                            mActivityCallbacksField.setAccessible(true);

                            List activityCallbacks = (List) mActivityCallbacksField.get(msg.obj);
                            for (int i = 0; i < activityCallbacks.size(); i++) {
                                if (activityCallbacks.get(i).getClass().getName()
                                        .equals("android.app.servertransaction.LaunchActivityItem")) {
                                    Object launchActivityItem = activityCallbacks.get(i);
                                    Field mIntentField = launchActivityItem.getClass().getDeclaredField("mIntent");
                                    mIntentField.setAccessible(true);
                                    Intent proxyIntent = (Intent) mIntentField.get(launchActivityItem);
                                    Log.e(TAG, "handleMessage: proxyIntent intent ="+proxyIntent);
                                    // The plug-in intent
                                    Intent intent = proxyIntent.getParcelableExtra(TARGET_INTENT);
                                    Log.e(TAG, "handleMessage: target intent ="+intent);
                                    if (intent != null) {
                                        mIntentField.set(launchActivityItem, intent);
                                    }
                                    break;
                                }
                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        break;
                }
                return false;
            }
        });
    } catch (Exception e) {
        e.printStackTrace();
    }
}

  there Hook Only aim at Android10 Let's look at the source code . therefore Android10 And above need to be adapted by themselves . Some people may wonder if this is not taking off their pants and farting ? You can go to register directly , Why do you do this . To do such a thing is to pretend 13 outside , Or is it because learning plug-in is one of the necessary knowledge of plug-in .

Here's a post GitHub Of Demo:https://github.com/279154451/SAppPlugin

Interested students can clone Come down and have a look

原网站

版权声明
本文为[Straw hat learning programming]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/03/202203021348159935.html