Hook技术看这篇就够了[通俗易懂]

Hook技术看这篇就够了[通俗易懂]   相信很多搞机的朋友都玩过Xposed,它实现了很多不可思议的功能。它是怎么实现的呢?这里就得提到我们的Hook技术了。    关于Android中的Hook机制,大致有两个方式: 要root权限,直接Hook系统,可以干掉所有的App。 免root权限,但是只能Hook自身,对系统其它App无能为力。   时间所限,这里不展开了。   知识点: …

大家好,又见面了,我是你们的朋友全栈君。

    相信很多搞机的朋友都玩过Xposed, 它实现了很多不可思议的功能。它是怎么实现的呢?这里就得提到我们的Hook技术了。

    关于 Android 中的 Hook 机制,大致有两个方式:

  •   要 root 权限,直接 Hook 系统,可以干掉所有的 App。
  •   免 root 权限,但是只能 Hook 自身,对系统其它 App 无能为力。

    时间所限,这里不展开了。

    知识点:

    今天主要讲的是利用hook技术,将点击事件劫持,做点啥呢?你可以随意,我这里是将双击给屏蔽了。免得点击过快打开多个界面。

1、寻找Hook点

    这一步比较关键,也是个难点。Android中主要是依靠分析系统源码类来做到的,首先我们得找到被Hook的对象,我称之为Hook点;什么样的对象比较好Hook呢?自然是容易找到的对象。什么样的对象容易找到?静态变量和单例;在一个进程之内,静态变量和单例变量是相对不容易发生变化的,因此非常容易定位,而普通的对象则要么无法标志,要么容易改变。我们根据这个原则找到所谓的Hook。

去看setOnClickListener里面做了什么?

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

看完了上面,就能猜到我们设置的Listener最终是被赋值给ListenerInfo的mOnClickListener成员了,ListenerInfo的实例可以说是信息的载体,那么很简单,只要把mOnClickListener,在ListenerInfo中还有mOnLongClickListener,mOnFocusChangeListener两个成员,分别对应了长按事件与焦点变化事件,所以处理长按事件与焦点变化事件与此类似。

public class HookViewClickUtil { 
   

    public static HookViewClickUtil getInstance() {
        return UtilHolder.mHookViewClickUtil;
    }

    private static class UtilHolder { 
   
        private static HookViewClickUtil mHookViewClickUtil = new HookViewClickUtil();
    }

    public static void hookView(View view) {
        try {
            Class viewClazz = Class.forName("android.view.View");
            //事件监听器都是这个实例保存的
            Method listenerInfoMethod = viewClazz.getDeclaredMethod("getListenerInfo");
            if (!listenerInfoMethod.isAccessible()) {
                listenerInfoMethod.setAccessible(true);
            }
            Object listenerInfoObj = listenerInfoMethod.invoke(view);

            Class listenerInfoClazz = Class.forName("android.view.View$ListenerInfo");

            Field onClickListenerField = listenerInfoClazz.getDeclaredField("mOnClickListener");

            if (!onClickListenerField.isAccessible()) {
                onClickListenerField.setAccessible(true);
            }
            View.OnClickListener mOnClickListener = (View.OnClickListener) onClickListenerField.get(listenerInfoObj);
            //自定义代理事件监听器
            View.OnClickListener onClickListenerProxy = new OnClickListenerProxy(mOnClickListener);
            //更换
            onClickListenerField.set(listenerInfoObj, onClickListenerProxy);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    //自定义的代理事件监听器
    private static class OnClickListenerProxy implements View.OnClickListener { 
   

        private View.OnClickListener object;

        private int MIN_CLICK_DELAY_TIME = 1000;

        private long lastClickTime = 0;

        private OnClickListenerProxy(View.OnClickListener object) {
            this.object = object;
        }

        @Override
        public void onClick(View v) {
            //点击时间控制
            long currentTime = Calendar.getInstance().getTimeInMillis();
            if (currentTime - lastClickTime > MIN_CLICK_DELAY_TIME) {
                lastClickTime = currentTime;
                Log.e("OnClickListenerProxy", "OnClickListenerProxy");
                if (object != null) object.onClick(v);
            }
        }
    }
}

使用起来也是非常简单,首先在MainActivity的View渲染完毕的时候进行注入,即在 getWindow().getDecorView().post()中。

public class MainActivity extends Activity { 
   

    private Button  btn;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        final View btn = findViewById(R.id.btn);

        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.e("MainActivity","Button 被点击了");
            }
        });

        getWindow().getDecorView().post(new Runnable() {
            @Override
            public void run() {
                HookViewClickUtil.hookView(btn);
            }
        });
    }
}

Hook技术看这篇就够了[通俗易懂]

原文出处:https://blog.csdn.net/u013263323/article/details/55094822

    

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/141211.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • pycharm配置解释器显示unsupported python 3.4和pipenv executable is not found

    pycharm配置解释器显示unsupported python 3.4和pipenv executable is not foundunsupportedpython3.4pycharm配置Python3.4解释器显示unsupportedpython3.4的环境变量无效,需要重新添加

    2022年8月26日
    10
  • 查看Redis版本信息

    查看Redis版本信息linux环境下查看redis的版本:查看redis的版本有两种方式:redis-server–version和redis-server-v得到的结果是:Redisserverv=3.0.7sha=00000000:0malloc=jemalloc-3.6.0bits=64build=c4d3f2c7214375c6redis-cli–version和redis-cl

    2022年6月10日
    24
  • stm32直流电机控制—PID算法篇

    stm32直流电机控制—PID算法篇stm32直流电机控制—PID算法篇提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加例如:第一章Python机器学习入门之pandas的使用**加粗样式*提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档文章目录stm32直流电机控制—PID算法篇前言一、pandas是什么?二、使用步骤1.引入库2.读入数据总结前言提示:这里可以添加本文要记录的大概内容:例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了

    2022年5月7日
    46
  • 【SSM – SpringMVC篇】02 – SpringMVC执行流程详解,SpringMVC三大核心组件和使用,SpringMVC头文件模板

    【SSM – SpringMVC篇】02 – SpringMVC执行流程详解,SpringMVC三大核心组件和使用,SpringMVC头文件模板1.SpringMVC执行流1.1SpringMVC三大核心组件HandlerMapping处理器映射器:建立地址与方法的映射。HandlerMapping负责根据用户请求url找到Handler即处理器,springmvc提供了不同的映射器实现不同的映射方式,例如:配置文件方式,实现接口方式,注解方式等。HandlerAdapter处理器适配器:根据地址调用方法。Handler是继DispatcherServlet前端控制器的后端控制器,在DispatcherServlet

    2022年6月28日
    29
  • IDEA 激活服务器破解方法

    IDEA 激活服务器破解方法,https://javaforall.net/100143.html。详细ieda激活码不妨到全栈程序员必看教程网一起来了解一下吧!

    2022年3月15日
    125
  • pycharm安装pyqt5-tools_怎么配置pycharm的环境

    pycharm安装pyqt5-tools_怎么配置pycharm的环境快速配置pyqt5,在pycharm上进行配置。步骤详细

    2022年8月28日
    0

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号