HOOK原理与fishhook初探防护

总结

在这里插入图片描述

1.HOOK概述

1、Method Swizzle

利用oc的runtime特性,动态改变SEL(方法编号)和IMP(方法实现)的对应关系,达到oc方法调用流程改变的目的。主要用于oc方法。

2、fishhook

它是Facebook提供的一个动态链接mach-O文件的工具。利用Macho文件加载原理,通过修改懒加载和非懒加载两个表的指针达到C函数Hook的目的

3 cydia Substrate

Cydia Substrte原名为mobile Substrte,它主要的作用是针对OC方法、C函数以及函数地址进行HOOK操作。当然它并不是仅仅针对ios而设计的,安卓也一样可以用。

下图是Method Swizzle和cydia substrte的简单原理图:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.fishHook简单使用

1.获取facehook的源码

1.1 通过登录github 搜索fishhook 可以看到源码并且down下来。
1.2 可终端cd到想要下载的目标文件下,通过输入命令 下载,
在这里插入图片描述
下载后可以看到只有fishhook.h fishhook.c 2个文件,可以看到点h中·只有2个方法和一个结构体。
在这里插入图片描述
方法1:rebind_symbols 针对是c函数
方法2:rebind_symbols_image 主要用于image

2.fishHook简单使用

1.用自定的myNSlog 替换 系统方法NSlog

- (void)viewDidLoad {
    [super viewDidLoad];
    
    
    
    //rebinding结构体
    struct rebinding nslog;
    nslog.name = "NSLog";
    nslog.replacement = myNslog;
    nslog.replaced = (void *)&sys_nslog;
    //rebinding结构体数组
    struct rebinding rebs[1] = {nslog};
    /**
     * 存放rebinding结构体的数组
     * 数组的长度
     */
    rebind_symbols(rebs, 1);
}
//---------------------------------更改NSLog-----------
//函数指针
static void(*sys_nslog)(NSString * format,...);
//定义一个新的函数
void myNslog(NSString * format,...){
    format = [format stringByAppendingString:@"勾上了!\n"];
    //调用原始的
    sys_nslog(format);
}



-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    NSLog(@"点击了屏幕!!");
}

2.如下代码,运行后可以发现点击屏幕,new_func并未替换func方法,原因是因为fishHook只能用于替换“系统函数”,并不能替换自定义的函数,具体原理下面继续探索。

void func(const char * str){
    NSLog(@"%s",str);
}

- (void)viewDidLoad {
    [super viewDidLoad];
    //rebinding结构体
    struct rebinding nslog;
    nslog.name = "func";
    nslog.replacement = new_func;
    nslog.replaced = (void *)&old_func;
    //rebinding结构体数组
    struct rebinding rebs[1] = {nslog};
    /**
     * 存放rebinding结构体的数组
     * 数组的长度
     */
    rebind_symbols(rebs, 1);
}
//---------------------------------更改NSLog-----------
//函数指针
static void(*old_func)(const char * str);
//定义一个新的函数
void new_func(const char * str){
      NSLog(@"%s + 1",str);
}



-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    func("哈哈");
  //  NSLog(@"哈哈!");
}

3 无法交换自定义函数,符号绑定原理

1.c 静态:系统的c函数存在着动态的部分!!
编译时确定:函数的地址!

2.oc 动态
运行时确定:函数的地址!

3.自定义函数的函数实现地址在macho的本地文件中,
而系统函数编译时系统地址不能确定,苹果用PIC技术解决,在macho的数据段中生成符号表,运行时通过dyld链接共享缓存库将真实地址绑定到符号表上符号地址,

我们可以看到nslog在macho中的偏移位置是0x4030,
在这里插入图片描述
我们可以看到macho在内存的起始位置是在这里插入图片描述
然后我们打开电脑段的计算器,command + 3 打开科学计算器,
然后起始位置加 偏移量,得到的16进制的0x10e172030,NSlog内存中的位置,
我们将断点打到viewdidload,如图所示位置:
在这里插入图片描述
然后使用LLDB,读取内存的指令:memory read 0x10e172030.可以看到内存中value是 0xf7ff2081c3b5,然后使用汇编指令dis -s f7ff2081c3b5查看汇编代码,如下显示foundation模块的nslog,(我这里断点过到nslog之下了,上面走到viewdidload时候也同样使用memory read 0x10e172030,可以查看未绑定nslog符号之前,内存value是不同于此处的,同样使用dis -s 0x… 可以看到未绑定之前是我们不识别的汇编,)
在这里插入图片描述
同样我们过了rebing_sysbols后在断点到touch处,同样读内存,和value发现此处已经绑定为myNSlog方法了。
在这里插入图片描述
在这里插入图片描述

4 rebing_sysbols中的结构体如何通过name字符串,查找修改到nslog的交换方法的。

首先在lazy Syymbol表中可以看到NSLog,
在这里插入图片描述
与lazy symbol表对应的表如下,nslog都是在表中首位,看到此处data序号为0x83:
在这里插入图片描述
上面这张表又与下面表对应,0x83十进制是131,我们可以寻找下表中131位置,是nslog,然后data对应value是A1
在这里插入图片描述
在这里插入图片描述
与上表想对应去string表中,寻找起始位置:0x6020 + a1便找到nslog的位置了
![在这里插入图片描述](https://img-blog.csdnimg.cn/20201105175220563.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L09TbWluQ2Fv,size_16,color_FFFFFF,t_70#pic_cent

5 初探防护

我们用fishhook交换了method_exchangeImplementations,之前使用method_exchangeImplementations进攻的代码就会可以被防护住了。

+(void)load
{
    //进攻的代码!
    // getIMP  setIMP
    Method old = class_getInstanceMethod(self, @selector(btnClick1:));
    Method newMethod = class_getInstanceMethod(self, @selector(click1Hook:));
    method_exchangeImplementations(old, newMethod);
    
    //防护代码!
    struct rebinding bd;
    bd.name = "method_exchangeImplementations";
    bd.replacement = myExchange;
    bd.replaced = (void *)&exchangeP;
    struct rebinding rebs[1] = {bd};
    rebind_symbols(rebs, 1);
    
   
}

//防护代码
//函数指针变量
void
(*exchangeP)(Method _Nonnull m1, Method _Nonnull m2);
void myExchange(Method _Nonnull m1, Method _Nonnull m2){
    NSLog(@"检测到HOOK!!");
}


-(void)click1Hook:(id)sender{
    NSLog(@"HOOK成功!!");
}


- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
}

- (IBAction)btnClick1:(id)sender {
    NSLog(@"按钮1调用了!");
    
}


- (IBAction)btnClick2:(id)sender {
    NSLog(@"按钮2调用了!");
    
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值