美文网首页ios专题iOS 逆向开发ios基础
iOS逆向之HOOK原理(十一)

iOS逆向之HOOK原理(十一)

作者: Colin_狂奔的蚂蚁 | 来源:发表于2018-05-13 23:44 被阅读509次

    HOOK概述

    HOOK(钩子) 其实就是改变程序执行流程的一种技术的统称!

    HOOK原理图.jpg

    iOS中HOOK技术的几种方式

    1、Method Swizzle

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

    2、fishhook

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

    ==fishhook在OC中的使用:==

    @interface ViewController ()
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        
        NSLog(@"123");
        
        //定义rebinding结构体
        struct rebinding nslogBind;
        //函数的名称
        nslogBind.name = "NSLog";
        //新的函数地址
        nslogBind.replacement = myLog;
        //保存原始函数地址的变量的指针
        nslogBind.replaced = (void *)&old_mylog;
    
        //定义数组
        struct rebinding rebindings[] = {nslogBind};
    
        /*
         arg1 : 存放rebinding结构体的数组
         arg2 : 数组的长度
         */
        rebind_symbols(rebindings, 1);
    }
    
    //函数指针,用来保存原始的函数地址
    static void (*old_mylog)(NSString *format, ...);
    
    //新的NSLog
    void myLog(NSString *format, ...) {
        format = [format stringByAppendingString:@"\n勾上了!"];
        //再调用原来的
        old_mylog(format);
    }
    
    - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
        NSLog(@"点击了屏幕!!!");
    }
    
    @end
    

    ==NSLog的绑定过程:==

    在MachO文件中查看NSLog的内存地址

    屏幕快照 2018-05-13 下午10.28.35.png
    (lldb) image list
    [  0] D92A4EC1-406D-3C26-9F39-C3D4A46A2948 0x00000001049f4000 /Users/yaoqi/Library/Developer/Xcode/DerivedData/001-fishHookDemo-cwtlojyvecrawmdgeiokwkgwddql/Build/Products/Debug-iphoneos/001-fishHookDemo.app/001-fishHookDemo 
    [  1] 477A8A1F-098B-3A80-860D-656A3F4918EA 0x0000000104d38000 /Users/yaoqi/Library/Developer/Xcode/iOS DeviceSupport/11.2.1 (15C153)/Symbols/usr/lib/dyld 
    [  2] B0F8DF97-77EC-3600-8A9F-35035B889EFD 0x0000000184dd9000 /Users/yaoqi/Library/Developer/Xcode/iOS DeviceSupport/11.2.1 (15C153)/Symbols/System/Library/Frameworks/Foundation.framework/Foundation 
    (lldb) x 0x00000001049f4000+0x8018
    0x1049fc018: 24 af de 84 01 00 00 00 34 b9 dd 84 01 00 00 00  $.......4.......
    0x1049fc028: 90 f5 a2 8d 01 00 00 00 58 ab 9f 04 01 00 00 00  ........X.......
    (lldb) dis -s 0x0184deaf24
    Foundation`NSLog:
        0x184deaf24 <+0>:  sub    sp, sp, #0x20             ; =0x20 
        0x184deaf28 <+4>:  stp    x29, x30, [sp, #0x10]
        0x184deaf2c <+8>:  add    x29, sp, #0x10            ; =0x10 
        0x184deaf30 <+12>: add    x8, x29, #0x10            ; =0x10 
        0x184deaf34 <+16>: str    x8, [sp, #0x8]
        0x184deaf38 <+20>: add    x1, x29, #0x10            ; =0x10 
        0x184deaf3c <+24>: mov    x2, x30
        0x184deaf40 <+28>: bl     0x184ec6d38               ; _NSLogv
    (lldb) ni
    (lldb) ni
    (lldb) ni
    (lldb) ni
    (lldb) ni
    (lldb) ni
    (lldb) x 0x00000001049f4000+0x8018
    0x1049fc018: bc 9d 9f 04 01 00 00 00 34 b9 dd 84 01 00 00 00  ........4.......
    0x1049fc028: 90 f5 a2 8d 01 00 00 00 3c ee f7 83 01 00 00 00  ........<.......
    (lldb) dis -s 0x01049f9dbc
    001-fishHookDemo`myLog:
        0x1049f9dbc <+0>:  sub    sp, sp, #0x30             ; =0x30 
        0x1049f9dc0 <+4>:  stp    x29, x30, [sp, #0x20]
        0x1049f9dc4 <+8>:  add    x29, sp, #0x20            ; =0x20 
        0x1049f9dc8 <+12>: mov    x8, #0x0
        0x1049f9dcc <+16>: stur   x8, [x29, #-0x8]
        0x1049f9dd0 <+20>: sub    x9, x29, #0x8             ; =0x8 
        0x1049f9dd4 <+24>: str    x0, [sp, #0x10]
        0x1049f9dd8 <+28>: mov    x0, x9
    (lldb) 
    

    ==NSLog在MachO文件中的反向查找过程:==

    MachO文件的查找过程.png

    3、Cydia Substrate

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

    Cydia Substrate主要由3部分组成:

    • MobileHooker

    MobileHooker顾名思义用于HOOK。它定义一系列的宏和函数,底层调用objc的runtime和fishhook来替换系统或者目标应用的函数.
    其中有两个函数:

    MSHookMessageEx 主要作用于Objective-C方法

    void MSHookMessageEx(Class class, SEL selector, IMP replacement, IMP result)
    

    MSHookFunction 主要作用于C和C++函数

    void MSHookFunction(voidfunction,void* replacement,void** p_original)
    

    Logos语法的%hook 就是对此函数做了一层封装

    • MobileLoader

    MobileLoader用于加载第三方dylib在运行的应用程序中。启动时MobileLoader会根据规则把指定目录的第三方的动态库加载进去,第三方的动态库也就是我们写的破解程序.

    • safe mode

    因为APP程序质量参差不齐崩溃再所难免,破解程序本质是dylib,寄生在别人进程里。 系统进程一旦出错,可能导致整个进程崩溃,崩溃后就会造成iOS瘫痪。所以CydiaSubstrate引入了安全模式,在安全模 式下所有基于CydiaSubstratede 的三方dylib都会被禁用,便于查错与修复。

    代码的基本防护

    ==注入的Framework库中的Hook代码:==

    #import "hookMgr.h"
    #import "fishhook.h"
    #import <objc/message.h>
    
    @implementation hookMgr
    //专门HOOK
    +(void)load
    {
        NSLog(@"hookMgr--Load");
        //内部用到的交换代码!
        Method old = class_getInstanceMethod(objc_getClass("ViewController"), @selector(btnClick1:));
        Method new = class_getInstanceMethod(self, @selector(click1Hook:));
        method_exchangeImplementations(old, new);
        
        
        //基本防护
        struct rebinding bd;
        bd.name = "method_exchangeImplementations";
        bd.replacement = myExchang;
        bd.replaced = (void *)&exchangeP;
        
        struct rebinding bd1;
        bd1.name = "method_getImplementation";
        bd1.replacement = myExchang;
        bd1.replaced = (void *)&getIMP;
        
        struct rebinding bd2;
        bd2.name = "method_setImplementation";
        bd2.replacement = myExchang;
        bd2.replaced = (void *)&setIMP;
        
    //    method_getImplementation
    //    method_setImplementation
        
        struct rebinding rebindings[] = {bd,bd1,bd2};
        rebind_symbols(rebindings, 3);
    }
    
    //保留原来的交换函数
    IMP _Nonnull (*setIMP)(Method _Nonnull m, IMP _Nonnull imp);
    IMP _Nonnull (*getIMP)(Method _Nonnull m);
    void (*exchangeP)(Method _Nonnull m1, Method _Nonnull m2);
    
    //新的函数
    void myExchang(Method _Nonnull m1, Method _Nonnull m2){
        NSLog(@"检测到了HOOK!!!");
        //强制退出!
        exit(1);
    }
    
    
    -(void)click1Hook:(id)sendr{
        NSLog(@"原来APP的HOOK保留!!");
    }
    
    @end
    

    ==使用Monkey创建的工程去Hook App中的代码:==

    如果别人要Hook自己写的App中的代码,就会闪退。

    // 修改 MachO
    
    #import <UIKit/UIKit.h>
    
    %hook ViewController
    
    - (void)btnClick2:(id)org
    {
        NSLog(@"🍺🍺🍺🍺🍺🍺🍺🍺🍺🍺🍺🍺🍺🍺🍺");
        exit(0);
    }
    
    %end
    

    HOOK原理总结

    1. MachO文件是被谁加载?DYLD(负责加载系统动态库)加载
    2. ASLR技术 MachO文件加载的时候是随机地址
    3. PIC位置代码独立

    如果MachO内部需要调用系统的库函数
    现在_DATA段(可读可写)中建立一个指针,指向外部函数
    DYLD会动态的进行绑定,将MachO中的_DATA中的指针,指向外部函数
    _DATA中的指针就是一个symbols

    相关文章

      网友评论

      本文标题:iOS逆向之HOOK原理(十一)

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