Android Hook技术的简单实现

Android Hook技术的简单实现,第1张

概述一、什么是Hook技术Android程序有一套特有的事件分发机制,都是按既定程序从前往后执行的。Hook技术就是利用反射和代理,在既定程序中插入我们自己写的程序。比如,我们想在某个View的点击事件中添加播放音乐的效果。控件的点击事件,分发流程都是系统已经写好了,这时我们怎么做 一、什么是Hook 技术

AndroID 程序有一套特有的事件分发机制,都是按既定程序从前往后执行的。Hook 技术就是利用反射和代理,在既定程序中插入我们自己写的程序。比如,我们想在某个VIEw的点击事件中添加播放音乐的效果。控件的点击事件,分发流程都是系统已经写好了,这时我们怎么做到在其中插入我们的播放音乐的效果呢?

二、如何寻找Hook点

1.尽量选择静态变量和单例对象,因为一旦创建对象,他们不容易变化,非常容易定位。
2.尽量Hook public的对象和方法

三、Hook过程

选中到了合适的Hook点后,选择合适的代理方式,如果是接口就可以用动态代理,然后偷梁换柱,用代理对象替换原始对象。

四、Hook VIEw的点击事件

先看看VIEw 点击事件的源码

  public voID setonClickListener(@Nullable OnClickListener l) {        if (!isClickable()) {            setClickable(true);        }        getListenerInfo().mOnClickListener = l; }
 @UnsupportedAppUsageListenerInfo getListenerInfo() {        if (mListenerInfo != null) {            return mListenerInfo;        }        mListenerInfo = new ListenerInfo();        return mListenerInfo;}

由代码可以看出,我们正常设置进去的OnClickListener是保存在ListenerInfo里面的。
如果我们可以通过反射将这个ListenerInfo里面的mOnClickListener 替换成我们自定义的OnClickListener是不是就可以实现我们目的了。接下来我们试试!
先看看通过反射修改对象属性的API

fIEld.set(Object obj, Object value) 
fIEld是我们要修改的变量的属性,也就是mOnClickListenerobj就是要修改的对象,就是ListenerInfovalue就是要替换mOnClickListener 的新值

接下来围绕准备这几个变量,我们来写代码

 private voID hookOnClickListener(VIEw vIEw) {        try {            // 得到待hook vIEw 的 ListenerInfo 对象            Method getListenerInfo = VIEw.class.getDeclaredMethod("getListenerInfo");            getListenerInfo.setAccessible(true);            Object ListenerInfo = getListenerInfo.invoke(vIEw);            // 得到 原始的 mOnClickListener 对象            Class<?> ListenerInfoClz = Class.forname("androID.vIEw.VIEw$ListenerInfo");            FIEld mOnClickListener = ListenerInfoClz.getDeclaredFIEld("mOnClickListener");            mOnClickListener.setAccessible(true);            VIEw.OnClickListener originonClickListener = (VIEw.OnClickListener) mOnClickListener.get(ListenerInfo);            // 用自定义的 hookedOnClickListener 替换原始的 mOnClickListener            VIEw.OnClickListener hookedOnClickListener = new HookOnClickListener(originonClickListener);            mOnClickListener.set(ListenerInfo, hookedOnClickListener);        } catch (Exception e) {            Log.d(TAG, "hook clickListener Failed!: ");        }    }

自定义的HookOnClickListener

 class HookOnClickListener implements VIEw.OnClickListener {        private VIEw.OnClickListener origin;        HookOnClickListener(VIEw.OnClickListener origin) {            this.origin = origin;        }        @OverrIDe        public voID onClick(VIEw v) {            Log.d(TAG,"执行点击事件之前");            if (origin != null) {                origin.onClick(v);            }            Log.d(TAG,"执行点击事件之后");        }    }

在MainActivity中的使用

 @OverrIDe    protected voID onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentVIEw(R.layout.activity_main);        tvHook = findVIEwByID(R.ID.tv_hook);        tvHook.setonClickListener(new VIEw.OnClickListener() {            @OverrIDe            public voID onClick(VIEw v) {                Log.d(TAG,"tvHook 的点击事件");            }        });        hookOnClickListener(tvHook);    }

点击tvHook 看看输出结果

/com.example.hook D/MainActivity: 执行点击事件之前/com.example.hook D/MainActivity: tvHook 的点击事件/com.example.hook D/MainActivity: 执行点击事件之后

看到这里我们已经成功Hook到了VIEw的点击事件

五、Hook注意点

AndroID 的API版本比较多,各个厂家也对系统有不同程度的定制,所以类和方法有可能不太一样,这就要求我们做好兼容。

总结

以上是内存溢出为你收集整理的Android Hook技术的简单实现全部内容,希望文章能够帮你解决Android Hook技术的简单实现所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/web/1058142.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-05-25
下一篇2022-05-25

发表评论

登录后才能评论

评论列表(0条)

    保存