启动未在AndroidMainfest中声明的Activity

对于插件化项目, 在插件包中新增一个Activity, 主包不能直接启动这个Activity, 因为这个Activity事先没有Mainfest文件中声明,会直接报Activity Not Found异常。

基本思路是

1)App发送要启动的NextActivity信息给AMS之前,把这个Activity 替换为一个在AndroidMainfest.xml中声明的MainActivity, 这样就可以绕过

AMS的检查了。在替换的过程中将原来的Activity信息放在Bundle中。

2)AMS 通知App 启动MainActivity时,我们不会启动MainActivity,在即将启动的时候,把MainActivity 替换为原来的Activity.

 

在App发送启动的Activity信息给AMS 之前,可以对ActivityManagerNative进行Hook, 将NextActivity 替换为已注册的MainActivity.

public static void hookActivityManagerNative(){
    try{
        Object gDefault = ReflectUtil.getStaticFieldObject("android.app.ActivityManagerNative","gDefault");
        Object  activityManager = ReflectUtil.getFieldObject("android.util.Singleton",gDefault,"mInstance");

        Class activityManagerInterface = Class.forName("android.app.IActivityManager");
        Object proxy = Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),
                new Class[] {activityManagerInterface},
                new DeceptionHookHandler(activityManager));

        ReflectUtil.setFileObject("android.util.Singleton",gDefault,"mInstance",proxy);
    }catch (Exception e){
        e.printStackTrace();
    }
}

 

static class DeceptionHookHandler implements InvocationHandler{
     Object mBase;
     public DeceptionHookHandler(Object object){
         this.mBase = object;
     }

     @Override
     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
         //动态代理
         if("startActivity".equals(method.getName())){
             //替换原始Activity 为别的Activity
             //找到第一个参数Intent
             Intent raw = null;
             int index=0;
             if(args != null && args.length > 0){
                 for (int i=0;i

 

AMS 通知App进程启动MainActivity,对ActivityThread中H 类的mCallback 进行hook, 将 MainActivity 替换为 NextActivity

public static void hookActivityThreadHCallback(){
    try{
        Object currentActivityThread =ReflectUtil.getStaticFieldObject("android.app.ActivityThread","sCurrentActivityThread");
        Handler mHandler = (Handler) ReflectUtil.getFieldObject("android.app.ActivityThread",currentActivityThread,"mH");
        ReflectUtil.setFileObject(Handler.class,mHandler,"mCallback",new DeceptionHandlerCallback(mHandler));
    }catch (Exception e){
         e.printStackTrace();
    }
 }
static class DeceptionHandlerCallback implements Handler.Callback{
    private Handler mH;
    public DeceptionHandlerCallback(Handler mHandler){
        this.mH = mHandler;
    }
    
    /**
     *  启动目标Activity
     */
    public void startTargetActivity(Message msg) {
        try {
            Object obj = msg.obj;
            //获取Intent 变量
            Intent intent = (Intent) ReflectUtil.getFieldObject(obj, "intent");
            Intent targetIntent = intent.getParcelableExtra("extra_intent");
            intent.setComponent(targetIntent.getComponent());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public boolean handleMessage(Message msg) {
        if(msg.what == 100){ //等于LAUNCH_ACTIVITY
             startTargetActivity(msg);
        }
        mH.handleMessage(msg);
        return true;
    }
}

代码地址:https://github.com/xiongliang120/HookProject.git

 

 

 

 

 

 

你可能感兴趣的:(andoid基础)