欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Android Hook简介

程序员文章站 2022-07-13 16:18:03
...

Hook:Hook翻译过来是钩子的意思,无论是手机还是电脑运行的时候都依赖系统各种各样的api,当某些api不能满足我们的要求时,我们就得去需改某些api,使之满足我们的要求。这样api hook就自然而然的出现了。我们可以通过api hook,改变一个系统api的原有功能。基本的方法就是通过hook“接触”到需要修改的api函数入口点,改变它的地址指向新的自定义的函数。当然这种技术同样适用于android系统,在android开发中,我们同样能利用hook的原理让系统某些方法运行时调用的是我们定义的方法,从而满足我们的要求。

下面用java反射实现简单的hook:新建一个android项目时有有一个MainActivity,我们在创建一个TestActivity,不再清单文件中注册,利用hook技术,显示的我们写的TestActivity

流程:Activity启动时候一般都是通过startActivity方式启动的,并没有看到调用new Activity(),其实这都是在系统里完成的,在Instrumentation.java中两个重载的方法来创建Activity实例的

//frameworks/base/core/java/android/app/Instrumentation.java
    public Activity newActivity(Class<?> clazz, Context context,
            IBinder token, Application application, Intent intent, ActivityInfo info,
            CharSequence title, Activity parent, String id,
            Object lastNonConfigurationInstance) throws InstantiationException,
            IllegalAccessException {
        Activity activity = (Activity)clazz.newInstance();
        ActivityThread aThread = null;
        activity.attach(context, aThread, this, token, 0, application, intent,
                info, title, parent, id,
                (Activity.NonConfigurationInstances)lastNonConfigurationInstance,
                new Configuration(), null, null, null);
        return activity;
    }
//frameworks/base/core/java/android/app/Instrumentation.java
    public Activity newActivity(ClassLoader cl, String className,
            Intent intent)
            throws InstantiationException, IllegalAccessException,
            ClassNotFoundException {
        return (Activity)cl.loadClass(className).newInstance();
    }

当MainActivity在创建实力时,我们用TestActivity来替换掉,这样应用启动的就是我们用的TestActivity

1,写一个IntrumentationHook继承系统的Intrumentation,并重写父类的new Activity()

//重新Instrumentation的newActivity方法
public class InstrumentationHook extends Instrumentation {
    @Override
    public Activity newActivity(Class<?> clazz, Context context, IBinder token, Application application, Intent intent, ActivityInfo info, CharSequence title, Activity parent, String id, Object lastNonConfigurationInstance) throws InstantiationException, IllegalAccessException {
        return super.newActivity(clazz, context, token, application, intent, info, title, parent, id, lastNonConfigurationInstance);
    }

    @Override
    public Activity newActivity(ClassLoader cl, String className, Intent intent) throws InstantiationException, IllegalAccessException, ClassNotFoundException {
        Activity activity = createActivity(intent);
        if (activity != null) {
            return activity;
        }
        return super.newActivity(cl, className, intent);
    }

    private Activity createActivity(Intent intent) {
        //获取组件得类型,当组件类名是MainActivity时返回TestActivity
        String component = intent.getComponent().getClassName();
        if ("com.example.hooktest.MainActivity".equals(component)) {
            try {
                Class<? extends Activity> testActivity = (Class<? extends Activity>) Class.forName("com.example.hooktest.TestActivity");
                return testActivity.newInstance();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return null;
    }
}

2,获取当前应用的ActivityThread,并替换系统默认的mIntrumentation实例

public class HookManager {
    private static Object activityThreadInstance;

    public static void init() throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        Class<?> thread = Class.forName("android.app.ActivityThread");//获取ActivityThread.class对象
        Method currentActivityThread = thread.getDeclaredMethod("currentActivityThread");//获取ActivityThread类中方法名为currentActivityThread的方法对象
        activityThreadInstance = currentActivityThread.invoke(null);//调用方法对象的方法,获取当前应用的ActivityThread实例
    }

    public static void initmInstrumentation() throws NoSuchFieldException, IllegalAccessException {
        Field mInstrumentation = activityThreadInstance.getClass().getDeclaredField("mInstrumentation");//获取ActivityThread实例中mIntrumentation属性对象
        mInstrumentation.setAccessible(true);
        InstrumentationHook instrumentationHook = new InstrumentationHook();
        mInstrumentation.set(activityThreadInstance,instrumentationHook);//用自定义的instrumentionHook替换掉系统的instrumention对象
    }
}

3,在MyApplication的onCreate里替换ActivityThread里的mIntrumentation

public class MyApplication extends Application {
    @Override
    public void onCreate() {
        try {
            HookManager.init();
            HookManager.initmInstrumentation();
        } catch (Exception e) {
            e.printStackTrace();
        }
        super.onCreate();
    }
}
Android Hook简介

相关标签: hook 反射