Hook详解

2018-03-28  本文已影响0人  至上小王子

写在前面

hook(钩子),通常是指对一些方法进行拦截。这样当这些方法被调用时,也能够执行我们自己的代码,从而达到监控或更改代码逻辑的目的。

实现方式

方式一、Java 反射实现Hook:

这种方式是最常见的,也是各种框架常采用的一种方式,直接上例子:

   /**
     * 利用Hook的方式修复Toast在7.1系统上BadTokenException
     * Created by conghongjie on 2018/3/28.
     */
   public class ToastCompat extends Toast{

        private static final String TAG = "ToastCompat";

        public ToastCompat(Context context) {
            super(context);
        }

        @Override
        public void show() {
            if(Build.VERSION.SDK_INT==Build.VERSION_CODES.N_MR1){
                tryToHack();
            }
            super.show();
        }

        private void tryToHack(){
            try {
                Object mTN=getFieldValue(this,"mTN");
                if(mTN!=null){
                    Object rawHandler=getFieldValue(mTN,"mHandler");
                    if(rawHandler!=null){
                        //替换为封装后的mHandler
                        setFieldValue(rawHandler,"mCallback",new InternalHandlerCallback((Handler)rawHandler));
                    }
                }
            }catch (Throwable e){
                e.printStackTrace();
            }
        }

        private class InternalHandlerCallback implements Handler.Callback{
            private final Handler mHandler;
            public InternalHandlerCallback(Handler mHandler) {
                this.mHandler = mHandler;
            }
            @Override
            public boolean handleMessage(Message msg) {
                try {
                    // 捕获BadTokenException
                    mHandler.handleMessage(msg);
                }catch (BadTokenException e) {
                   e.printStackTrace();
                }
                return true;
            }
        }
    }

总结一下,此方法的实现思路:

方式二、更改方法体的内存指向:

上一篇 下一篇

猜你喜欢

热点阅读