8、代码注入
一、代码注入
- 一般修改原始的程序,是利用代码注入的方式,注入代码就会选择利用Framework和Dylib等三方库的方式注入.
1.1 Framework注入
-
- 通过Xcode新建Framework,将库安装进入App包.
- 通过yololib注入Framework库路径.命令: $yololib MachO文件路径 库路径.
- 所有的Framework加载都是由DYLD加载进入内存被执行的.
- 注入成功的库路径会写入MachO文件的LC_LOAD_DYLIB字段中.
1.2 Dylib注入
-
- 通过Xcode新建Dylib库(注意: Dylib属于MacOS所以需要修改属性).
- 添加Target依赖, 让Xcode将自定义Dylib文件打包进入App包.
- 利用yololib进行注入.
二、Method Swizzle
利用OC的Runtime特性,动态改变SEL(方法编号)和IMP(方法实现)的对应关系,达到OC方法调用流程改变的目的.主要用于OC方法.
-
- 在OC中, SEL和IMP之间的关系,就好像一本书的“目录”
- SEL是方法编号,就像“标题”一样
- IMP是方法实现的真实地址,就像“页码”一样.他们是一一对应的关系
Runtime提供了两个SEL和IMP对应关系的函数
OBJC_EXPORT void method_exchangeImplementations(Method _Nonnull m1, Method _Nonnull m2) OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);
-
- 通过这个函数交换两个SEL和IMP对应关系的技术,我们称之为Method Swizzle(方法欺骗)
2.1 多种HOOK方式
class_addMethod方式
-
- 利用addMethod方法,让原始方法可以被调用,不至于因为找不到SEL而崩溃
class_replaceMethod方式:
-
- 利用class_replaceMethod, 直接给原始的方法替换IMP
method_setImplementation方式
-
- 利用method_setImplementation,直接重新赋值原始的新的IMP
三、总结
- Framework注入、Dylib注入
- Xcode自动打包进入App包
- MachO中Load Commands里面需要有LC_LOAD_DYLIB字段
- DYLD加载我们的动态
- 案例:
- 分析思路
- 动态调试: 界面入手
- 静态分析: class-dump: (头文件) OC的类、方法列表
- MethodSwizzle(Runtime)
- exchange函数去交换SEL与IMP的对应关系
- 隐患: 回不去了(没调用原来的实现)
- 解决方法:
- 添加方法列表,解决--过程比较复杂 不推荐
- replace函数替换IMP
- getIMP和setIMP配合,推荐: 逻辑清晰(大部分HOOK框架使用这个方式)
- exchange函数去交换SEL与IMP的对应关系