一、HOOK
1.1 HOOK简介
1.2 Hook的应用场景
二、iOS中HOOK技术的几种方式
2.1 Method Swizzle
/**
* Exchanges the implementations of two methods.
* @param m1 Method to exchange with second method.
* @param m2 Method to exchange with first method.
* @note This is an atomic version of the following:
* \code
* IMP imp1 = method_getImplementation(m1);
* IMP imp2 = method_getImplementation(m2);
* method_setImplementation(m1, imp2);
* method_setImplementation(m2, imp1);
* \endcode
*/
OBJC_EXPORT void
method_exchangeImplementations(Method _Nonnull m1, Method _Nonnull m2)
OBJC_AVAILABLE(10.5, 2.0, 9.0, 1.0, 2.0);
2.2 fishhook
2.3 Cydia Substrate
2.3.1 Cydia Substrate简介
2.3.2 MobileHooker
void MSHookMessageEx(Class class,SEL selector, IMP replacement,IMP result)
void MSHookFunction(void function,void*replacement,void **p_original)
2.3.3 MobileLoader
2.3.4 Safe Mode
三、fishHook简单使用
3.1 获取fishhook代码
git clone https://github.com/facebook/fishhook.git
3.2 fishhook关键函数
struct rebinding {
const char *name;//需要Hook的函数名称,字符串
void *replacement; // 替换到哪个新的函数上(函数指针,也就是函数名称)
void **replaced;//保存原始函数指针变量的指针(它是一个二级指针)
};
//用来重新绑定符号表的函数,使用它来交换
// 参数一: 存放rebinding结构体的数组(可以同时交换多个函数)
// 参数二: rebindings数组的长度
FISHHOOK_VISIBILITY
int rebind_symbols(struct rebinding rebindings[], size_t rebindings_nel);
3.3 fishhook使用:
3.3.1 下面看一个HOOK 系统NSLog函数的案例
//------------HOOK NSLog------------
- (void)viewDidLoad {
[super viewDidLoad];
//创建rebinding 结构体
struct rebinding nslog;
nslog.name = "NSLog";
nslog.replacement = my_NSLog;
//保存NSLog系统函数地址的指针!
nslog.replaced = (void *)&sys_nslog;
//需求:HOOK NSLog
struct rebinding bds[] = {nslog};
rebind_symbols(bds, 1);
NSLog(@"end");
}
//函数指针!
static void (*sys_nslog)(NSString *format, ...);
//新函数!
void my_NSLog(NSString *format, ...){
format = [format stringByAppendingString:@"\n我HOOK到了!"];
//走到系统的nslog里面去!
sys_nslog(format);
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
//编译的时候,知不知道NSLog 的真实地址!
NSLog(@"hello");//PIC
//bl 本地代码地址.(ASLR)
//MachO Text(只读\可执行!)
//Data(可读\可写) 符号!! 符号表!!
//符号绑定!!
}
3.3.2 接着看一个HOOK自定义函数的案例
//----------HOOK Func -------
void func(const char * str){
NSLog(@"%s",str);
}
static void (*func_p)(const char * str);
void my_func(const char * str){
NSLog(@"HOOK了!!");
func_p(str);
}
- (void)viewDidLoad {
[super viewDidLoad];
//创建rebinding 结构体
struct rebinding func;
func.name = "func";
func.replacement = my_func;
//保存NSLog系统函数地址的指针!
func.replaced = (void *)&func_p;
//需求:HOOK NSLog
struct rebinding bds[] = {func};
rebind_symbols(bds, 1);
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
func("HOOK Func");
}
3.3.3 静态链接与动态链接
1、静态链接的特点是将一个进程中用到的库都加载进内存,而不管内存中是否加载过。
2、动态链接发生在加载可执行文件到内存时,系统先检测应用程序依赖的库中有没有已经加载的,若有则直接去内存取,不会重复加载。
3.3.4 fishhook原理-- 符号重新绑定
3.3.5 fishhook如何通过符号找到函数
3.3.6 fishhook总结