简介

什么是 Hook

Hook 又叫“钩子”,它可以在事件传送的过程中截获并监控事件的传输,将自身的代码与系统方法进行融入。这样当这些方法被调用时,也就可以执行我们自己的代码,这也是面向切面编程的思想(AOP)。

Hook 分类

1.根据Android开发模式,Native模式(C/C++)和Java模式(Java)区分,在Android平台上

  • Java层级的Hook;
  • Native层级的Hook;

2.根 Hook 对象与 Hook 后处理事件方式不同,Hook还分为:

  • 消息Hook;
  • API Hook;

3.针对Hook的不同进程上来说,还可以分为:

  • 全局Hook;
  • 单个进程Hook;

常见 Hook 框架

在Android开发中,有以下常见的一些Hook框架:

  • Xposed
    通过替换 /system/bin/app_process 程序控制 Zygote 进程,使得 app_process 在启动过程中会加载 XposedBridge.jar 这个 Jar 包,从而完成对 Zygote 进程及其创建的 Dalvik 虚拟机的劫持。
    Xposed 在开机的时候完成对所有的 Hook Function 的劫持,在原 Function 执行的前后加上自定义代码。

  • Cydia Substrate
    Cydia Substrate 框架为苹果用户提供了越狱相关的服务框架,当然也推出了 Android 版 。Cydia Substrate 是一个代码修改平台,它可以修改任何进程的代码。不管是用 Java 还是 C/C++(native代码)编写的,而 Xposed 只支持 Hook app_process 中的 Java 函数。

  • Legend
    Legend 是 Android 免 Root 环境下的一个 Apk Hook 框架,该框架代码设计简洁,通用性高,适合逆向工程时一些 Hook 场景。大部分的功能都放到了 Java 层,这样的兼容性就非常好。
    原理是这样的,直接构造出新旧方法对应的虚拟机数据结构,然后替换信息写到内存中即可。

Hook 必须掌握的知识

  • 反射
    如果你对反射还不是很熟悉的话,建议你先复习一下 java 反射的相关知识。反射机制详解

  • java 的动态代理
    动态代理是指在运行时动态生成代理类,不需要我们像静态代理那个去手动写一个个的代理类。在 java 中,我们可以使用 InvocationHandler 实现动态代理。动态代理模式

Hook 使用实例

Hook选择的关键点

  • Hook 的选择点:尽量静态变量和单例,因为一旦创建对象,它们不容易变化,非常容易定位。
  • Hook 过程:
    • 寻找 Hook 点,原则是尽量静态台变亮或者单例对象,尽量 Hook public 的对象和方法。
    • 选择合适的代理方式,如果是接口可以使用动态代理。
    • 偷梁换柱——用代理对象替换原始对象。
  • Android 的 API 版本较多,方法和类可能不一样,所以要做好 API 的兼容。

案例一:使用 Hook 修改 View.OnClickListener 事件

  • 查看 OnClickListener 源码,寻找合适的 Hook 点。
public void setOnClickListener(@Nullable OnClickListener l){    if (!isClickable()) {        setClickable(true);     }     getListenerInfo().mOnClickListener = l;}    static class ListenerInfo {     ---    ListenerInfo getListenerInfo() {        if (mListenerInfo != null) {            return mListenerInfo;        }        mListenerInfo = new ListenerInfo();        return mListenerInfo;    }    ---}

Hook View.OnClickListener 事件。大概分 3 步:

1、获取 ListenerInfo 对象
2、获取原始的 OnClickListener 事件方法
3、偷梁换柱,用 Hook 代理类 替换原始的 OnClickListener

   button1.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                Log.i(TAG, "onClick: ---- get");            }        });        try {            hookOnClickListener(button1);        } catch (NoSuchMethodException e) {            e.printStackTrace();        } catch (InvocationTargetException e) {            e.printStackTrace();        } catch (IllegalAccessException e) {            e.printStackTrace();        } catch (ClassNotFoundException e) {            e.printStackTrace();        } catch (NoSuchFieldException e) {            e.printStackTrace();        }            public static void hookOnClickListener(View view) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException, ClassNotFoundException, NoSuchFieldException {        //1 得到 ListenerInfo 对象        Method getListenerInfo = View.class.getDeclaredMethod("getListenerInfo");        getListenerInfo.setAccessible(true);        Object objListenerInfo = getListenerInfo.invoke(view);        //2 得到原始的 OnClickListener 事件的方法 的对象        Class<?> listenerInfoClz  = Class.forName("android.view.View$ListenerInfo");        Field mOnClickListener = listenerInfoClz.getDeclaredField("mOnClickListener");        mOnClickListener.setAccessible(true);        View.OnClickListener originOnClickListener = (View.OnClickListener) mOnClickListener.get(objListenerInfo);        //3 用 Hook 代理类 替换原始的 OnClickListener        HookedClickListenerProxy hookedClickListenerProxy = new HookedClickListenerProxy(originOnClickListener);        mOnClickListener.set(objListenerInfo,hookedClickListenerProxy);    }class HookedClickListenerProxy implements View.OnClickListener{    private View.OnClickListener originOnClickListener;    public HookedClickListenerProxy(View.OnClickListener originOnClickListener) {        this.originOnClickListener = originOnClickListener;    }    @Override    public void onClick(View v) {        Log.i(this.getClass().getSimpleName(), "onClick: ---- hook");        Toast.makeText(v.getContext(),"Hook Click Listener",Toast.LENGTH_SHORT).show();        if (originOnClickListener!=null){            originOnClickListener.onClick(v);        }    }}

参考文章:
https://blog.csdn.net/gdutxiaoxu/article/details/81459830

https://blog.csdn.net/csdn_aiyang/article/details/79085039

更多相关文章

  1. Android模拟产生事件
  2. Android中事件分发机制
  3. Android智能指针
  4. Java中的WeakReference 和 SoftReference
  5. Android(安卓)RxJava:一步步带你源码分析 RxJava
  6. android 内存优化
  7. VC++实现android的Toast消息框的功能
  8. android为HttpClient和HttpURLConnection添加中国移动代理
  9. Android(安卓)Hook 机制之实战模拟

随机推荐

  1. Android 之 发送邮件
  2. Android通过onTouch事件实现单击,双击,长按
  3. Android 8.0 启动后台service 出错 Illeg
  4. android 编译问题解决
  5. android 打开word pdf excle 进行预览 (
  6. Android文件权限(Linux的权限)
  7. Android --- 取得电话簿信息,并保存为Vcard格
  8. Android Studio报错:the minSdk version s
  9. Installation error: INSTALL_FAILED_CON
  10. Android ImageView设置边框