hook Activity的mInstrumentation变量

在《Android插件化原理解析——Hook机制之动态代理》一文中,hook了ContextImpl的mInstrumentation变量,我实现了下hook activity的mInstrumentation变量,原理见 http://weishu.me/2016/01/28/understand-plugin-framework-proxy-hook/

直接上代码:在Activity的onCreate()中

private void testHook() {
    Field instrumentationField = null;
    try {
        // 此处使用Activity,不能使用this
        // this指向继承于BaseActivity的类,如NewsDetailActivity,getDeclaredField获取到的是声明的域
        instrumentationField = Activity.class.getDeclaredField("mInstrumentation");
    } catch (NoSuchFieldException e) {
        e.printStackTrace();
    }
    AppLogUtils.e("mInstrumentationField:" + instrumentationField);
    if (instrumentationField != null) {
        // 设置为可访问,否则IllegalAccessException
        instrumentationField.setAccessible(true);
        Instrumentation originInstrumentation = null;
        try {
            // 获取Activity对象的Instrumentation对象
            originInstrumentation = (Instrumentation) instrumentationField.get(this);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }

        if (BuildConfig.DEBUG) {
            // 通过打印发现每个Activity的Instrumentation对象都是一个,所以应该是可以用Activity中的mainThread的Instrumentation来获取即可
            AppLogUtils.e("originInstrumentation:" + originInstrumentation);
        }

        // 通过查找想要“包装”的方法是否存在,判断能否可以被hook
        Method execStartActivityMethod = null;
        try {
            execStartActivityMethod = Instrumentation.class.getDeclaredMethod("execStartActivity", Context.class, IBinder.class, IBinder.class, Activity.class, Intent.class, int.class, Bundle.class);
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }

        // hook
        if (originInstrumentation != null && execStartActivityMethod != null) {
            try {
                instrumentationField.set(this, new TestInstrumentation(originInstrumentation));
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
    }
}

class TestInstrumentation extends Instrumentation {
    private Instrumentation mOriginInstrumentation;

    public TestInstrumentation(Instrumentation instrumentation) {
        mOriginInstrumentation = instrumentation;
    }

    public ActivityResult execStartActivity(
            Context who, IBinder contextThread, IBinder token, Activity target,
            Intent intent, int requestCode, Bundle options) {
        try {
            AppLogUtils.e("my instrumentation start activity");
            // 查找当前方法
            Method execStartActivityMethod = null;
            try {
                execStartActivityMethod = Instrumentation.class.getDeclaredMethod("execStartActivity", Context.class, IBinder.class, IBinder.class, Activity.class, Intent.class, int.class, Bundle.class);
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            }
            ActivityResult result = null;
            if (execStartActivityMethod != null) {
                execStartActivityMethod.setAccessible(true);
                try {
                    // 执行activity启动
                    result = (ActivityResult) execStartActivityMethod.invoke(mOriginInstrumentation, who, contextThread, token, target, intent, requestCode, options);
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                }
            }
            return result;
        } catch (Throwable t) {
            t.printStackTrace();
        }
        return null;
    }
}
通过测试发现,进入不同activity,activity的mInstrumentation变量都是一样的,应该是使用mainThread的mInstrumentation的变量,因此可以改进成在Application的onCreate()中进行hook。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值