美文网首页
Hook技术

Hook技术

作者: couriravant | 来源:发表于2019-10-13 22:11 被阅读0次

    一、什么是 Hook 技术

    Hook 技术又叫做钩子函数,在系统没有调用该函数之前,钩子程序就先捕获该消息,钩子函数先得到控制权,这时钩子函数既可以加工处理,也可以强制结束消息的传递。可以理解位劫持。
    被劫持的对象称为hook点,为了保证hook的稳定性,hook点一般选择容易找到并且不易变化的对象,静态变量、单例。

    二、hook技术分类

    根据语言 :

    1)hook java 主要通过反射和代理实现,应用于在skd开发环境修改java代码
    2)hook native 在ndk开发环境和系统开发环境修改native代码

    根据进程划分:应用程序进程hook、全局hook

    根据实现方式

    1)通过反射和代理,只能hook当前进程
    2)通过hook框架,如xposed,需要 root

    这里主要实践Java hook,以hook startActivity为例:

    //hook点
     Instrumentation mInstrumentation;
    
    @Override
        public void startActivity(Intent intent, Bundle options) {
            warnIfCallingFromSystemProcess();
            if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) == 0
                    && options != null && ActivityOptions.fromBundle(options).getLaunchTaskId() == -1) {
                throw new AndroidRuntimeException(
                        "Calling startActivity() from outside of an Activity "
                        + " context requires the FLAG_ACTIVITY_NEW_TASK flag."
                        + " Is this really what you want?");
            }
            mMainThread.getInstrumentation().execStartActivity(
                    getOuterContext(), mMainThread.getApplicationThread(), null,
                    (Activity) null, intent, -1, options);
        }
    

    选择ActivityThread类的mInstrumentation作为hook点, 用我们那自己的代理mInstrumentation对象来替换hook点。
    那就分为两步,1. 实现代理的mInstrumentation 2.替换hook点

    1、实现代理的mInstrumentation

    由于mInstrumentation的类型Instrumentation是一个类,不是接口,因此这里采用静态代理

    public class ProxyInstrumentation extends Instrumentation {
        private static final String TAG = "ProxyInstrumentation";
    
        Instrumentation mBase;
    
        public ProxyInstrumentation(Instrumentation mBase) {
            this.mBase = mBase;
        }
        public ActivityResult execStartActivity(
                Context who, IBinder contextThread, IBinder token, Activity target,
                Intent intent, int requestCode, Bundle options) {
    
            Log.d(TAG, " Hook before");
            try {
                Method execStartActivity = Instrumentation.class.getDeclaredMethod(
                        "execStartActivity",
                        Context.class, IBinder.class, IBinder.class, Activity.class,
                        Intent.class, int.class, Bundle.class);
                execStartActivity.setAccessible(true);
                return (ActivityResult) execStartActivity.invoke(mBase, who,
                        contextThread, token, target, intent, requestCode, options);
            } catch (Exception e) {
                throw new RuntimeException("do not support!");
            }
        }
    }
    

    2、替换hook点

        public void replaceInstrumentation() throws Exception {
            //先获取到当前的ActivityThread对象
            Class<?> activityThreadClass = Class.forName("android.app.ActivityThread");
            Method currentActivityThreadMethod = activityThreadClass.getDeclaredMethod("currentActivityThread");
            currentActivityThreadMethod.setAccessible(true);
            Object currentActivityThread = currentActivityThreadMethod.invoke(null);
            // 拿到原始的 mInstrumentation字段
            Field mInstrumentationField = activityThreadClass.getDeclaredField("mInstrumentation");
            mInstrumentationField.setAccessible(true);
            Instrumentation mInstrumentation = (Instrumentation) mInstrumentationField.get(currentActivityThread);
            // 创建代理对象
            Instrumentation evilInstrumentation = new ProxyInstrumentation(mInstrumentation);
            //赋值,替换为代理类
            mInstrumentationField.set(currentActivityThread, evilInstrumentation);
        }
    

    实现时在Activity的onCreate方法中使用replaceInstrumentation来替换即可。

    相关文章

      网友评论

          本文标题:Hook技术

          本文链接:https://www.haomeiwen.com/subject/zxukmctx.html