当前位置:网站首页 > Java基础 > 正文

java基于什么基础



一. 什么是 Hook

Hook 英文翻译过来就是「钩子」的意思,那我们在什么时候使用这个「钩子」呢?在 Android 操作系统中系统维护着自己的一套事件分发机制。应用程序,包括应用触发事件和后台逻辑处理,也是根据事件流程一步步地向下执行。而「钩子」的意思,就是在事件传送到终点前截获并监控事件的传输,像个钩子钩上事件一样,并且能够在钩上事件时,处理一些自己特定的事件。

image

Hook 的这个本领,使它能够将自身的代码「融入」被勾住(Hook)的程序的进程中,成为目标进程的一个部分。API Hook 技术是一种用于改变 API 执行结果的技术,能够将系统的 API 函数执行重定向。在 Android 系统中使用了沙箱机制,普通用户程序的进程空间都是独立的,程序的运行互不干扰。这就使我们希望通过一个程序改变其他程序的某些行为的想法java基于什么基础不能直接实现,但是 Hook 的出现给我们开拓了解决此类问题的道路。

什么是沙箱机制

沙箱是一个虚拟系统程序,沙箱提供的环境相对于每一个运行的程序的进程空间都是独立的,程序的运行互不干扰,而且不会对现有的系统产生影响。

二、Hook 分类

1、根据Android开发模式

2、根 Hook 对象与 Hook 后处理事件方式

3、针对Hook的不同进程上来说

四. API Hook 原理

通过对 Android 平台的虚拟机注入与 Java 反射的方式,来改变 Android 虚拟机调用函数的方式(ClassLoader),从而达到 Java 函数重定向的目的,这里我们将此类操作称为 Java API Hook。

基础知识

由此可见,Hook的基础知识,是反射及基于反射的动态代理

  • 反射
    反射(Reflection)是什么呢?

反射有时候也被称为内省(Introspection),事实上,反射,就是一种内省的方式,Java不允许在运行时改变程序结构或类型变量的结构,但它允许在运行时去探知、加载、调用在编译期完全未知的class,可以在运行时加载该class,生成实例对象(instance object),调用method,或对field赋值。这种类似于“看透”了class的特性被称为反射(Reflection),我们可以将反射直接理解为:可以看到自己在水中的倒影,这种操作与直接操作源代码效果相同,但灵活性高得多。

在之前学习热更新的时候有介绍过反射,详见 Android热更新二:理解Java反射 。

  • java 的动态代理
    首先了解一些代理模式的定义。

为其他对象提供一种代理以控制这个对象的访问。

从代码的角度来分,代理可以分为两种:一种是静态代理,另一种是动态代理。

之前讲设计模式的时候,也讲过动态代理,详见 Android常见设计模式五:代理模式。

五、Hook Activity 的 startActivity

原理知道后,还是实战来得舒畅,下面以startActivity启动一个activity为例,在Activity中启动另一个Activity,首先我们需要了解activity的启动流程,一步步跟踪,发现最终在Activity.startActivityForResult中以如下方式启动:

 

如果你对Activity启动熟悉的话会发现,此处的mInstrumentation就是ActivityThread通过ativity.attach传过来的,而ActivityThread一个app唯一的,而mInstrumentation就是在ActivityThread创建后马上创建的,此时,是不是感觉这个mInstrumentation符合hook点,ok,先hook一把

 

其中InstrumentProxy如下:

 

此处,先获取ActivityThread中的mInstrumentation属性,然后再采用静态代理将其替换掉,这样就hook住系统的方法,我们也就可以在InstrumentProxy中任意插桩。

倘若你没有发现mInstrumentation符合hook点,你可以继续跟踪Instrumentation.execStartActivity方法,里面有个非常明显的hook点:

 

对,就是ActivityManagerNative.getDefault(),我们可以进入ActivityManagerNative类,发现getDefault方法实现如下:

 

其中gDefault是个static属性,完全符合hook要求,具体hook如下:

 

其中ProxyHandler如下:

 

采用动态代理的方法对IActivityManager进行了接管,同样完成了startActivity的hook。

其实不选单例、静态属性或共有属性,整个private的也是可以的,还以启动startActivity为例,考虑到Activity是继承ContextWrapper,而ContextWrapper中有个属性mBase,如果我们能对mBase hook也是可以的,这样就需要对ContextImpl来个代理就可以了,代码可以如下:

 

这样尽管可以,但是启动activity就需要注意了,只要能走到mBase.startActivity(intent)接口才生效,如果没走它,就hook失效啰,所以hook点选择很关键,尽管都hook到了东西,但是是不是hook住了全部,还需要验证。

六、Hook View 的 OnClickListener

下面通过 Hook View 的 OnClickListener 来说明 Hook 的使用方法。

首先进入 View 的 setOnClickListener 方法,我们看到 OnClickListener 对象被保存在了一个叫做 ListenerInfo 的内部类里,其中 mListenerInfo 是 View 的成员变量。ListeneInfo 里面保存了 View 的各种监听事件,比如 OnClickListener、OnLongClickListener、OnKeyListener 等等。

 

我们的目标是 Hook OnClickListener,所以就要在给 View 设置监听事件后,替换 OnClickListener 对象,注入自定义的操作。

 

到这里,我们成功 Hook 了 OnClickListener,在点击之前和点击之后可以执行某些操作,达到了我们的目的。下面是调用的部分,在给 Button 设置 OnClickListener 后,执行 Hook 操作。点击按钮后,日志的打印结果是:Before click → onClick → After click。

 

七、使用 Hook 拦截应用内的通知

当应用内接入了众多的 SDK,SDK 内部会使用系统服务 NotificationManager 发送通知,这就导致通知难以管理和控制。现在我们就用 Hook 技术拦截部分通知,限制应用内的通知发送操作。

发送通知使用的是 NotificationManager 的 notify 方法,我们跟随 API 进去看看。它会使用 INotificationManager 类型的对象,并调用其 enqueueNotificationWithTag 方法完成通知的发送。

 
 

INotificationManager 是跨进程通信的 Binder 类,sService 是 NMS(NotificationManagerService) 在客户端的代理,发送通知要委托给 sService,由它传递给 NMS,具体的原理在这里不再细究,感兴趣的可以了解系统服务和应用的通信过程。

我们发现 sService 是个静态成员变量,而且只会初始化一次。只要把 sService 替换成自定义的不就行了么,确实如此。下面用到大量的 Java 反射和动态代理,特别要注意代码的书写。

 

Hook 的时机还是尽量要早,我们在 attachBaseContext 里面操作。

 

这样我们就完成了对通知的拦截,可见 Hook 技术真的是非常强大,好多插件化的原理都是建立在 Hook 之上的。

八、结语

以上,我们知道,hook技术涉及到的知识点主要有反射、代理及android的一些底层知识,如果想要较好地掌握好hook相关的内容,就需要花更多的时间去学习和总结。

下面总结一下注意点:

  1. Hook 的选择点:静态变量和单例,因为一旦创建对象,它们不容易变化,非常容易定位。
  1. Hook 过程:

寻找 Hook 点,原则是静态变量或者单例对象,尽量 Hook public 的对象和方法。
选择合适的代理方式,如果是接口可以用动态代理。
偷梁换柱——用代理对象替换原始对象。

  1. Android 的 API 版本比较多,方法和类可能不一样,所以要做好 API 的兼容工作。

另外,市面上游几个比较成熟的Hook 方案,如果有需要大量使用此技术的不妨参考参考:

  • Xposed
  • Cydia Substrate

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

  • Legend

  • 上一篇: Java基础工作经验
  • 下一篇: 无it基础学java
  • 版权声明


    相关文章:

  • Java基础工作经验2024-11-01 09:34:01
  • java基础语句结构2024-11-01 09:34:01
  • java数据库基础笔记2024-11-01 09:34:01
  • 传智杯java基础题2024-11-01 09:34:01
  • java大数据0基础难学吗2024-11-01 09:34:01
  • 无it基础学java2024-11-01 09:34:01
  • 大连北大青鸟0基础学java2024-11-01 09:34:01
  • Java基础入门之玫瑰花数2024-11-01 09:34:01
  • java前端开发需要java基础吗2024-11-01 09:34:01
  • Java基础网络编程重要吗2024-11-01 09:34:01