iOS中如何hook消息
在windows下可以通过API轻松的hook很多消息,IOS里面貌似还没有现成的API(可能是我还没发现吧),前段时间碰巧看到Objective-C运行时的一些东西,于是心想着是不是可以尝试一下实现hook的功能。
为什么要hook消息呢,因为有些时候我们可能无法直接去继承一个类,却又想先截获某些消息做一些处理,然后再接着进行正常的处理流程。今天使用运行时的一些API实现了基本的hook功能。
下面先直接上源码:
下面我们来逐行分析一下上面的代码:
首先我们来看19行,这一行主要目的是获取到UIWindow原生的sendEvent的Method(一个结构体,用来对方法进行描述),接着第20行是获取到我们自己定义的类中的sendEvent的Method(这两个方法的签名必须一样,否则运行时报错)。第23行我们通过UIWindow原生的sendEvent的Method获取到对应的IMP(一个函数指针),第24行使用运行时API Class_addMethod给UIWindow类添加了一个叫sendEventOriginal的方法,该方法使用UIWindow原生的sendEvent的实现,并且有着相同的方法签名(必须相同,否则运行时报错)。27行是获取我们自定义类中的sendEventMySelf的IMP,28行是关键的一行,这一行的主要目的是为UIWindow原生的sendEvent指定一个新的实现,我们看到我们将该实现指定到了我们自己定义的sendEventMySelf上。到了这儿我们就完成了偷梁换柱,大功告成。
执行上面这些行以后,我们就成功的将UIWindow的sendEvent重定向到了我们自己的写的sendEventMySelf的实现,然后将其原本的实现重定向到了我们给它新添加的方法sendEventOriginal中。而sendEventMySelf中,我们首先可以对这个消息进行我们想要的处理,然后再通过41行调用sendEventOriginal方法转到正常的执行流程。
这块儿你可能有个困惑 “我们自定义类中明明是没有sendEventOriginal方法的啊?”
以上就是Hook的实现,使用时我们只需要让TestHookObject类执行一次初始话操作就可以了,执行完以后。UIWindow的sendEvent消息就会会hook到我们的sendEventMySelf中了。
下面是调用代码:
参考资料:
Objective-C运行时源代码
Objective-C Runtime Reference