iOS逆向之HOOK原理介绍
-
上一篇文章地址: iOS逆向之动态调试 (LLDB)介绍
-
上篇文章讲了如何使用LLDB进行动态调试.
-
如果你对文章有疑问,或者不清楚的地方,欢迎留言.
-
本篇文章对HOOK原理进行介绍.还记得,前几篇文章,我们介绍了有关HOOK内容,我们本篇介绍一下Hook的原理.
-
我们通过砸壳,class-dump 到 实现tweak工程,进行hook某个类等一系列操作后,实现我们想要的功能.因此,我们不仅要熟练使用如何hook,也要明白它应用的原理.
1.HOOK本质
-
HOOK
,我们称之为钩子.
注意
其实就是通过改变程序运行流程的一种技术.
怎么理解这句话?
在这里举个例子,我们所看的视频广告.如果你不是会员,那就要看60秒的广告,我们通过HOOK技术进行代码修改,达到广告拦截的目的. 这里只谈研究
如果你想拦截广告,也有别的办法可以实现.以后有机会把技术分享给大家.
2.HOOK原理
-
1.
HOOK原理第一种方式,通过Method Swizzle进行实现.
从图中可以看到,Method Swizzle 离不开运行行时Runtime OC runtime 特性
. 还有一点,在越狱平台和非越狱平台都可以使用.
-
2.
通过交换两个selector实现,可以达到方法交换调用
2.1
一个方法的实现是保存在IMP里面的.
2.2
runtime提供了修改IMP的方法和交换两个IMP实现的方法.
案例
ViewController.m
#import "ViewController.h"
#import <Objc/Runtime.h>
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
[self originalMehtod];
[self newMethod];
}
+ (void)load{
Class class = [self class];
SEL originalSelector = @selector(originalMehtod);
SEL newSelector = @selector(newMethod);
Method originalMethod = class_getInstanceMethod(class, originalSelector);
Method newMethod = class_getInstanceMethod(class, newSelector);
method_exchangeImplementations(originalMethod,newMethod);
}
-(void)originalMehtod{
NSLog(@"原方法");
}
-(void)newMethod{
NSLog(@"新方法");
}
@end
结果
2020-02-27 15:50:24.226036+0800 SwizzleMethod[4372:221449] 新方法
2020-02-27 15:50:24.226125+0800 SwizzleMethod[4372:221449] 原方法
我们通过方法的交换实现,修改了方法的调用.
-
3.
如果我们在新方法调用自己,会不会循环呢?
我们改变一下代码,看一下结果.
-(void)newMethod{
NSLog(@"新方法");
[self newMethod];
}
打印结果
2020-02-27 15:54:47.515105+0800 SwizzleMethod[4475:226449] 新方法
2020-02-27 15:54:47.515193+0800 SwizzleMethod[4475:226449] 原方法
2020-02-27 15:54:47.515261+0800 SwizzleMethod[4475:226449] 原方法
通过结果,我们可以看到方法是不存在循环调用,我们已经通过方法交换,修改了调用的方法.
采用Method Swizzling 可以在用户无感知的情况下拦截某个方法进行统计处理.
3. Cydia Substrate
Cydia SubstrateCydia Substrate地址: Cydia Substrate
To install Substrate, you will need to "jailbreak" your device, as making
changes to other software is not something that Apple normally allows.
要安装Substrate,你需要“jailbreak”你的设备,因为修改其他软件不是苹果通常允许的。
Depending on your iOS version and device, you will need to use one of a
few different jailbreaking tools such as redsn0w or evasi0n.
根据你的iOS版本和设备,你需要使用一些不同的越狱工具,如redsn0w或evasi0n。
The various jailbreaking tools install Cydia Installer, which you can then
use to install Substrate and any of thousands of Substrate extensions.
各种越狱工具安装Cydia安装程序,然后您可以使用它们来安装Substrate和数千个Substrate扩展中的任何一个。
- Cydia Substrate
针对OC方法
,C函数
以及函数地址进行HOOK操作.从上图可以看到,Android和iOS都可以使用.
1.
MobileHooker
MobileHooker 替换系统函数
void MSHookMessageEx(Class _class, SEL message, IMP hook, IMP *old);
void MSHookFunction(void *symbol, void *hook, void **old);
-
MSHookMessageEx 主要作用于OC函数,Logos语法主要是对MSHookFunction函数进行了封装.
-
关于
Logos语法
的文章在这里: iOS逆向之Logos语法介绍,大家可以了解一下. -
MSHookFunction 主要作用于C和C++函数
2.
MSHookMessageEx的使用
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
MSHookMessageEx([NSObject class], @selector(description), &newDescription, &oldDescription);
}
NSString * (* oldDescription)(id self , SEL _cmd);
NSString *newDescription(id self, SEL _cmd){
NSString * description = (*oldDescription)(self,_cmd);
description = [description stringByAppendingString:@"!"];
return description;
}
我们首先创建oldDescription
用于保存原来的NSString类description方法的地址,通过实现新的newDescription
.
最后通过MSHookMessageEX函数替换原来的description方法,实现Hook.
刚才有提到,其实Logos语法是对MSHookMessageEx函数的封装.
3.
MSHookFunction
MSHookFunction函数的作用对象是C,C++函数,然后C,C++并不提供runtime这种高级的API
,所以我们想HOOK更加困难.
void MSHookFunction(void *symbol, void *hook, void **old);
- MSHookFunction 三个参数分别是 替换的原函数,替换函数,MobileHooker保存的原函数.
void (*oldFunction)(void);
void newFunction(void){
MSImageRef image = MSGetImageByName("");
void * symbol = MSFindSymbol(image, "symbol");
if (symbol) {
MSHookFunction((void *)symbol, (void *)&newFunction,(void **)&oldFunction);
}else{
NSLog(@"没有symbol");
}
}
我们通过定义原方法用户保存要HOOK函数被替换的指令,
接着实现新的newFunction方法,使用MSHookFunction
来对修改的函数进行Hook.
4.
MobileLoader
MobileLoader 加载第三方dylib在运行的应用程序中.
4.1
MobileLoader主要是系统启动时由Launchd进程将Mobileloader加载进内存
4.2
Moblieloader会通过环境变量(DYLD_INSERT_LIBRARIES
)将自己加载进设备各个进程
4.3
并遍历 /Library/MobileSubstrate/DynamicLibraries/目录下的文件,如下图
4.4
每个dylib及plist文件来确定dylib的作用范围.如果当前进程满足该作用范围,则会使用dlopen函数加载对应的dylib.
5.
SafeMode
注入应用进程,修改应用的逻辑存在一定风险.因为寄生在应用进程中,系统进程很容易造成崩溃.如果崩溃的是SpringBoard等系统进程,则会造成系统瘫痪.
我们可以在安全模式下进行第三方插件的禁用,卸载,从而帮助系统修复.
4.Fishhook
Fishhook github 地址: fishhook地址
注意
本篇文章不过多介绍Fishhook内容,下一篇文章会针对Fishhook进行单独介绍.
总结
-
1.
本篇文章,主要介绍了HOOK原理内容. -
2.
三种方式通过HOOK,Method Swizzle(通过runtime机制进行hook
),Cydia Substrate,FishHook. -
3.
相信你对HOOK原理有一定了解了. -
4.
欢迎大家关注文章,也希望大家支持.