AndroidHook相关基础例子

前言

Hook是什么?举个例子,有一个人写了一封情书给你喜欢的女孩,在送信的路上你偷偷的把那封情书拿了换成你自己写的情书,再放了回去,那个人拿着你写的情书给了你喜欢的女孩。

不要问为什么会有Hook。反正Hook是有广大的应用场景。

Hook可以做很多常规开发中由于限制而认为不可能实现的事情。

备注说明:前面写的《组件化》框架gradle部分源码已经被我改得面目全非,有空再写一篇文章说明一下。

Hook的流程

Hook 有3步
1.找到替换点
2.构建动态代理对象
3.替换

往往第一步会比较麻烦耗时,因为首先你得把你要Hook的整个流程,关键点都弄清楚,然后再分析出是否有可以Hook的点。

Android Hook简单例子

我们这个简单的例子是这样。
描述如下 (如何实现省略):
新建一个项目,里面很简单,添加一个按钮,点击按钮弹出 :我爱你


        Button button = findViewById(R.id.btn_test);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(DebugActivity.this,  "我爱你", Toast.LENGTH_SHORT).show();
            }
        });

我们通过Hook不修改上面的代码让点击按钮弹出:你是SB

如何分析代码部分省略找到Hook点部分省略。


    private void hookClick(View button) throws Exception {
        //获取到ListenerInfo
        Class mViewClass = Class.forName("android.view.View");
        Method mGetListenerInfoMethod = mViewClass.getDeclaredMethod("getListenerInfo");
        mGetListenerInfoMethod.setAccessible(true);
        Object mListenerInfo = mGetListenerInfoMethod.invoke(button);  
        //设置新OnClickListener的动态代理 
        Object mProxyOnClickListener = Proxy.newProxyInstance(getClassLoader(), new Class[]{View.OnClickListener.class}, new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                Toast.makeText(DebugActivity.this, "你是SB", Toast.LENGTH_SHORT).show();
                return null;
            }
        }); 
        //替换
        mOnClickListenerField.set(mListenerInfo, mProxyOnClickListener);
    }

调用

调用上面这个方法把这个按钮传进去点击就弹出就变成了:你是SB

Hook后继续执行

如果你希望Hook后还能继续执行我爱你,


    private void hookClick(View button) throws Exception {
        //获取到ListenerInfo
        Class mViewClass = Class.forName("android.view.View");
        Method mGetListenerInfoMethod = mViewClass.getDeclaredMethod("getListenerInfo");
        mGetListenerInfoMethod.setAccessible(true);
        Object mListenerInfo = mGetListenerInfoMethod.invoke(button);  
        
        //获取原来已经设置好的mOnClickListener
        Class mListenerInfoViewClass = Class.forName("android.view.View$ListenerInfo");
        Field mOnClickListenerField = mListenerInfoViewClass.getDeclaredField("mOnClickListener");
        mOnClickListenerField.setAccessible(true);
        final Object mOnClickListener = mOnClickListenerField.get(mListenerInfo);
        //设置新OnClickListener的动态代理 
        Object mProxyOnClickListener = Proxy.newProxyInstance(getClassLoader(), new Class[]{View.OnClickListener.class}, new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                Toast.makeText(DebugActivity.this, "我是XXX", Toast.LENGTH_SHORT).show();
                //继续调用这个是核心
                method.invoke(mOnClickListener, args);
                return null;//如果原来的调用是有返回值请  return method.invoke(mOnClickListener, args);
            }
        }); 
        //替换
        mOnClickListenerField.set(mListenerInfo, mProxyOnClickListener);
    }

核心思想

核心思想就是构建一个View.OnClickListener 的动态代理
然后把之前设置好的替换掉

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值