package com.weishu.upf.hook_classloader;

import java.io.File;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;

import com.weishu.upf.hook_classloader.ams_hook.AMSHookHelper;
import com.weishu.upf.hook_classloader.classloder_hook.BaseDexClassLoaderHookHelper;
import com.weishu.upf.hook_classloader.classloder_hook.LoadedApkClassLoaderHookHelper;

/**
 * @author weishu
 * @date 16/3/28
 */
public class MainActivity extends Activity {

    private static final String TAG = "MainActivity";

    // patch宿主ClassLoader的方式
    private static final int PATCH_BASE_CLASS_LOADER = 1;

    // 自定义ClassLoader的方式
    private static final int CUSTOM_CLASS_LOADER = 2;

    private static final int HOOK_METHOD = CUSTOM_CLASS_LOADER;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Button t = new Button(this);
        t.setText("test button");

        setContentView(t);

        Log.d(TAG, "context classloader: " + getApplicationContext().getClassLoader());
        t.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                try {
                    Intent t = new Intent();
                    if (HOOK_METHOD == PATCH_BASE_CLASS_LOADER) {
                        t.setComponent(new ComponentName("com.weishu.upf.dynamic_proxy_hook.app2",
                                "com.weishu.upf.dynamic_proxy_hook.app2.MainActivity"));
                    } else {
                        t.setComponent(new ComponentName("com.weishu.upf.ams_pms_hook.app",
                                "com.weishu.upf.ams_pms_hook.app.MainActivity"));
                    }
                    startActivity(t);
                } catch (Throwable e) {
                    e.printStackTrace();
                }
            }
        });
    }

    @Override
    protected void attachBaseContext(Context newBase) {
        super.attachBaseContext(newBase);
        try {
            Utils.extractAssets(newBase, "dynamic-proxy-hook.apk");
            Utils.extractAssets(newBase, "ams-pms-hook.apk");
            Utils.extractAssets(newBase, "test.apk");

            if (HOOK_METHOD == PATCH_BASE_CLASS_LOADER) {
                File dexFile = getFileStreamPath("test.apk");
                File optDexFile = getFileStreamPath("test.dex");
                BaseDexClassLoaderHookHelper.patchClassLoader(getClassLoader(), dexFile, optDexFile);
            } else {
                LoadedApkClassLoaderHookHelper.hookLoadedApkInActivityThread(getFileStreamPath("ams-pms-hook.apk"));
            }

            AMSHookHelper.hookActivityManagerNative();
            AMSHookHelper.hookActivityThreadHandler();

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

}

@@ -60,74 +60,121 @@
 le;%0A
-%0A
 import 
-android.app.Activity;%0Aimport android.content.ComponentName
+java.lang.reflect.InvocationTargetException;%0Aimport java.lang.reflect.Method;%0A%0Aimport android.app.Activity
 ;%0Aim
@@ -222,22 +222,15 @@
 oid.
-content.Intent
+net.Uri
 ;%0Aim
@@ -1387,32 +1387,54 @@
           try %7B%0A
+                    //
                 
@@ -1458,24 +1458,46 @@
 w Intent();%0A
+                    //
             
@@ -1542,32 +1542,54 @@
 CLASS_LOADER) %7B%0A
+                    //
                 
@@ -1671,16 +1671,38 @@
 .app2%22,%0A
+                    //
         
@@ -1798,33 +1798,77 @@
             
-%7D else %7B%0A
+//                    %7D else %7B%0A                    //
             
@@ -1949,32 +1949,44 @@
 app%22,%0A          
+          //
                 
@@ -1983,32 +1983,42 @@
                 
+          
 %22com.weishu.upf.
@@ -2075,171 +2075,1547 @@
     
-%7D%0A                    startActivity(t);%0A                %7D catch (Throwable e) %7B%0A                    e.printStackTrace();%0A                %7D%0A            %7D%0A        %7D)
+//                    %7D%0A                    //                    startActivity(t);%0A%0A                    Uri uri = Uri.fromFile(getFileStreamPath(%22test.apk%22));%0A                    boolean ret = (Boolean) invokeMethod(Class.forName(%22android.provider.DocumentsContract%22).newInstance(), %22isDocumentUri%22, new Class%5B%5D %7B Context.class, Uri.class %7D,%0A                            new Object%5B%5D %7B getApplicationContext(), uri %7D);%0A                    Log.d(TAG, %22ret%22 + ret);%0A                %7D catch (Throwable e) %7B%0A                    e.printStackTrace();%0A                %7D%0A            %7D%0A        %7D);%0A    %7D%0A%0A    private static Method getDeclaredMethod(Object object, String name, Class%3C?%3E%5B%5D types) %7B%0A        for (Class%3C?%3E superClass = object.getClass(); superClass != Object.class; superClass.getSuperclass()) %7B%0A            try %7B%0A                return superClass.getDeclaredMethod(name, types);%0A            %7D catch (NoSuchMethodException e) %7B%0A%0A            %7D%0A        %7D%0A        return null;%0A    %7D%0A%0A    private static Object invokeMethod(Object obj, String methodName, Class%3C?%3E%5B%5D argTypes, Object%5B%5D args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException %7B%0A        Method method = getDeclaredMethod(obj, methodName, argTypes);%0A        if (method == null) %7B%0A            throw new IllegalAccessException(%22could not found method:%22 + methodName);%0A        %7D%0A        method.setAccessible(true);%0A        try %7B%0A            return method.invoke(obj, args);%0A        %7D catch (IllegalAccessException e) %7B%0A%0A        %7D%0A        return null
 ;%0A  

修复动态代理里面的作业说明.