美文网首页
iOS逆向-15:Hook原理

iOS逆向-15:Hook原理

作者: 恍然如梦_b700 | 来源:发表于2021-05-17 16:00 被阅读0次

    Hook概述

    HOOK,中文译为“挂钩”或“钩子”。在iOS逆向中是指改变程序运行流程的一种技术。通过hook可以让别人的程序执行自己所写的代码。在逆向中经常使用这种技术。所以在学习过程中,我们重点要了解其原理,这样能够对恶意代码进行有效的防护。

    Hook示意

    比如说我们收到红包消息,我们进行hook,执行自定义的恶意代码、看看抢红包需要哪些参数,准备好参数调用抢红包代码。就不需要等待用户点开红包,点击抢红包等一一系列操作了

    iOS中HOOK技术的几种方式

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

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

    3. Cydia Substrate

    Cydia Substrate 原名为 Mobile Substrate ,它的主要作用是针对OC方法、C函数以及函数地址进行HOOK操作。当然它并不是仅仅针对iOS而设计的,安卓一样可以用。官方地址:http://www.cydiasubstrate.com/

    fishhook

    接口函数:

    struct rebinding {
      const char *name;//需要HOOK的函数名称,C字符串
      void *replacement;//新函数的地址
      void **replaced;//原始函数地址的指针!
    };
    FISHHOOK_VISIBILITY
    int rebind_symbols(struct rebinding rebindings[], size_t rebindings_nel);
    
    /*
     * Rebinds as above, but only in the specified image. The header should point
     * to the mach-o header, the slide should be the slide offset. Others as above.
     */
    FISHHOOK_VISIBILITY
    int rebind_symbols_image(void *header,
                             intptr_t slide,
                             struct rebinding rebindings[],
                             size_t rebindings_nel);
    

    demo:

    - (void)viewDidLoad {
        [super viewDidLoad];
        //创建rebinding 结构体
        struct rebinding myNslog;
        myNslog.name = "NSLog";
        myNslog.replacement = my_NSLog;
        myNslog.replaced = (void *)&sysLog;
        struct rebinding bds[] = {myNslog};
        rebind_symbols(bds, 1);
        
    }
    
    //原函数
    static void (*sysLog)(NSString *format, ...);
    //新函数
    void my_NSLog(NSString *format, ...) {
        format = [format stringByAppendingFormat:@"\nhook成功~!!!"];
        //回到系统的nslog里
        sysLog(format);
    }
    
    
    -(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
    {
        NSLog(@"hello");
    }
    

    结果:


    image.png

    用法比较简单,那么fishhook是如何hook函数的呢
    我们知道:
    OC动态语言特性 方法通过sel找imp
    而C语言是静态语言 直接通过函数地址访问

    那么我们猜想一下,fishhook是不是先保存原函数的地址,然后bl到自己的函数地址呢?
    其实这个过程并没有那么简单:
    MachO Text段(只读\可执行!)
    Data段(可读\可写) 所以这里面包含了符号,及符号表
    首先编译时NSLog的地址我们不知道,NSLog在foundation共享缓存库中
    在访问NSLog的时候,使用的其实是PIC技术(位置无关代码),首先访问占位符占位符就叫做符号,占8个字节,dlyd 进行对符号里的数据修改就叫做符号绑定!!而所有的符号列表就叫做符号表,
    因为外部符号地址不确定所以使用PIC技术

    image.png

    把符号里的地址修改了,做到修改符号对应地址的关系
    外部的c函数是动态调用的,通过符号找地址,也可以重绑定
    函数名变量名,方法名,编译完就生成一张符号表

    内部符号,本mach内的符号
    外部符号,也叫间接符号表
    可以通过 symbol table查看

    本地符号 我自己内部使用的,去符号去的是本地符号
    全局符号 暴露给外界使用的,比如第三方库,
    objcdump --macho -t SymbolDemo 可以看到符号
    l 本地
    g 全局

    indirect symbols间接符号表

    外部符号的是在懒加载符号,在第一次调用才绑定,我们通过汇编看一下流程
    首先我们在第一调用nslog的地方打一个断点,看汇编


    image.png

    通过image list 找到macho的偏移是 0x0000000104454000,也就是pagezero+ASLR
    此次运行时的ASLR是0x4454000,将0x10445a4a8 - 0x4454000 = 0x00000001000064a8 就是macho文件bl的位置:


    image.png
    发现是跳到外部符号的桩,桩里面有一段代码,汇编CTRL + Stepinto点击去看汇编:
    image.png
    br x16 0x000000010445a55c - 0x4454000 = 0x000000010000655c:
    image.png

    br去符号表里的地址执行665c,找655c:


    image.png
    发现执行的是上面红框出来的代码, 本地的一行代码 ldr #1008000,即符号绑定
    image.png
    绑定之后,懒加载符号表里的data就修改了。

    总结

    外部符号绑定过程

    • 外部函数调用执行桩里面的代码 (Text stubs)
      通过懒加载符号表里面的地址去执行
    • 懒加载符号表里面默认存储的是寻找binder的代码
      binder函数在非懒加载符号表里(程序运行就绑定好了)

    相关文章

      网友评论

          本文标题:iOS逆向-15:Hook原理

          本文链接:https://www.haomeiwen.com/subject/lyydjltx.html