Hook英文意思为钩子,顾名思义就是像钩子同样改变程序原有的运行流程。好比一段程序的执行流程是 A --> B --> C,如今咱们在 A 和 B 之间插入一段代码或者直接改变 B ,这样程序原有的执行流程就发生了改变。以下图所示: app
iOS逆向中,若是咱们但愿对一个OC方法进行Hook,主要应用了OC的运行时特性,在程序运行时动态改变方法的实现。在OC中,用于实现运行时特性的是一套基于C/C++以及汇编的API,即咱们常说的Runtime。而咱们Hook过程当中用到的主要是一下几个方法:函数
一、方法交换
OBJC_EXPORT void
method_exchangeImplementations(Method _Nonnull m1, Method _Nonnull m2)
OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);
二、替换方法
OBJC_EXPORT IMP _Nullable
class_replaceMethod(Class _Nullable cls, SEL _Nonnull name, IMP _Nonnull imp,
const char * _Nullable types)
OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);
三、setIMP & getIMP
OBJC_EXPORT IMP _Nonnull
method_setImplementation(Method _Nonnull m, IMP _Nonnull imp)
OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);
OBJC_EXPORT IMP _Nullable
class_getMethodImplementation(Class _Nullable cls, SEL _Nonnull name)
OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);
复制代码
在平时的开发中,咱们也会用到这几个方法,但它们是怎么实现方法交换/替换的呢?观察这几个方法的参数,咱们发现主要有 Class、SEL、IMP、Method 这几种类型,咱们分别来看一下this
一、Class 一个 objc_class 类型的结构体指针,用于说明对象是哪一个类;spa
二、Method 一个 objc_method 类型的结构体指针,用于定义一个方法,在objc源码中定义以下:3d
三、SEL 能够发如今 Method 的定义中,也能看见SEL。咱们看下在苹果官方文档中如何定义这种类型指针
四、IMP 一样在 Method 的定义中也能看到,在苹果官方文档的定义以下: code
咱们发现其实上诉方法都包含 SEL 和 IMP 这两种类型的信息。根据上文中苹果文档中的介绍咱们能够发现cdn
SEL: Method selectors are used to represent the name of a method at runtime. A method selector is a C string that has been registered (or “mapped“) with the Objective-C runtime.对象
IMP: This data type is a pointer to the start of the function that implements the method. This function uses standard C calling conventions as implemented for the current CPU architecture. The first argument is a pointer to self (that is, the memory for the particular instance of this class, or, for a class method, a pointer to the metaclass). The second argument is the method selector. The method arguments follow.blog
SEL是一个C String,用于表示一个方法的名称,IMP是一个方法实现首地址,默认有两个参数 self 和 _cmd。其实SEL和IMP的关系咱们能够类比一本书的目录,SEL就是目录中的内容标题,IMP是后面的页码。一个方法调用时,经过SEL找到对应的IMP,进而找到方法的实现。以下图:
逆向中,Hook一个OC方法其实就是改变其SEL所指向的IMP,从而找到另外一个实现地址,执行另外一个方法实现。但这种方法的局限在于,其只能针对OC方法进行Hook,对于C函数则没法Hook。在下一篇文章中,咱们将探索如何Hook一个C函数以及fishhook库的使用及原理。