美文网首页
iOS逆向之四-FishHook的简单使用

iOS逆向之四-FishHook的简单使用

作者: aron1992 | 来源:发表于2017-12-09 21:07 被阅读34次

    iOS逆向之二-FishHook的简单使用

    FishHook用于hook C函数,是Facebook提供的一个动态修改链接mach-O文件的工具,项目地址:fishhook

    官方例子

    一个官方的小例子:
    用于监控某个进程的文件的读写事件,相当于hook C语言的open/close函数,OC底层是使用C语言实现的,所以hook C语言的open/close函数 可以达到监控程序的文件操作情况。

    #import <dlfcn.h>
    
    #import <UIKit/UIKit.h>
    
    #import "AppDelegate.h"
    #import "fishhook.h"
    
    // 定义函数的指针变量,用户保存原来的函数指针(函数其实也是一个地址)
    static int (*orig_close)(int);
    static int (*orig_open)(const char *, int, ...);
    
    // 自定义的close函数
    int my_close(int fd) {
      printf("Calling real close(%d)\n", fd);
      return orig_close(fd);
    }
     
    // 自定义的open函数
    int my_open(const char *path, int oflag, ...) {
      va_list ap = {0};
      mode_t mode = 0;
     
      if ((oflag & O_CREAT) != 0) {
        // mode only applies to O_CREAT
        va_start(ap, oflag);
        mode = va_arg(ap, int);
        va_end(ap);
        printf("Calling real open('%s', %d, %d)\n", path, oflag, mode);
        return orig_open(path, oflag, mode);
      } else {
        printf("Calling real open('%s', %d)\n", path, oflag);
        return orig_open(path, oflag, mode);
      }
    }
     
    int main(int argc, char * argv[])
    {
        @autoreleasepool {
            
            // rebind_symbols((struct rebinding[2]){{"close", my_close, (void *)&orig_close}, {"open", my_open, (void *)&orig_open}}, 2);
            // 转换为:=====>
            
            struct rebinding binds[2];
            // orig_close是一个函数指针,(void *)&orig_close 是一个返回参数,所以用取地址,(void *)&orig_open也是类似的
            struct rebinding bind1 = {"close", my_close, (void *)&orig_close};
            binds[0] = bind1;
            binds[1] = (struct rebinding){"open", my_open, (void *)&orig_open};
            rebind_symbols(binds, 2);
            
            // Open our own binary and print out first 4 bytes (which is the same
            // for all Mach-O binaries on a given architecture)
            int fd = open(argv[0], O_RDONLY);
            uint32_t magic_number = 0;
            read(fd, &magic_number, 4);
            printf("Mach-O Magic Number: %x \n", magic_number);
            close(fd);
            
            return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
        }
    }
    

    运行项目,可以看到以下的日志,这是一个iOS项目,这些日志记录了一个简单的IOS项目运行文件的操作记录。

    Calling real open('/Users/aron/Library/Developer/CoreSimulator/Devices/51EAB81B-E4BF-4A9A-A007-CEA9A9A3278F/data/Containers/Bundle/Application/32081135-98DF-415D-AFEB-C87E7B584F6C/FishHookDemo.app/FishHookDemo', 0)
    Mach-O Magic Number: feedfacf 
    Calling real close(3)
    Calling real open('/Users/aron/Library/Developer/CoreSimulator/Devices/51EAB81B-E4BF-4A9A-A007-CEA9A9A3278F/data/Containers/Bundle/Application/32081135-98DF-415D-AFEB-C87E7B584F6C/FishHookDemo.app/Info.plist', 0)
    Calling real close(3)
    Calling real open('/Users/aron/Library/Developer/CoreSimulator/Devices/51EAB81B-E4BF-4A9A-A007-CEA9A9A3278F/data/Containers/Bundle/Application/32081135-98DF-415D-AFEB-C87E7B584F6C/FishHookDemo.app/FishHookDemo', 0)
    Calling real close(3)
    Calling real open('/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/System/Library/ColorSync/Profiles/sRGB Profile.icc', 0)
    Calling real close(5)
    Calling real open('/Users/aron/Library/Developer/CoreSimulator/Devices/51EAB81B-E4BF-4A9A-A007-CEA9A9A3278F/data/Containers/Bundle/Application/32081135-98DF-415D-AFEB-C87E7B584F6C/FishHookDemo.app/FishHookDemo', 0)
    Calling real close(5)
    ...
    

    Tweak插件上使用FishHook

    可以把这段代码移植到tweak插件上,xm文件支持logos/c/c++/OC语法,所以移植的过程很方便。下面的例子展示的是把这段代码注入到 今日头条 中,使用class-dump查找 今日头条 的入口类是 AppDelegate ,所以把这段代码注入到 - (BOOL)application:(id)arg1 didFinishLaunchingWithOptions:(id)arg2 方法中就行了。

    tweak.xm 源文件:

    #include "fishhook.h"
    #import <dlfcn.h>
    
    
    static int (*orig_close)(int);
    static int (*orig_open)(const char *, int, ...);
    
    int my_close(int fd) {
        NSLog(@"Calling real close(%d)\n", fd);
        return orig_close(fd);
    }
    
    int my_open(const char *path, int oflag, ...) {
        va_list ap = {0};
        mode_t mode = 0;
        
        if ((oflag & O_CREAT) != 0) {
            // mode only applies to O_CREAT
            va_start(ap, oflag);
            mode = va_arg(ap, int);
            va_end(ap);
            NSLog(@"Calling real open('%s', %d, %d)\n", path, oflag, mode);
            return orig_open(path, oflag, mode);
        } else {
            NSLog(@"Calling real open('%s', %d)\n", path, oflag);
            return orig_open(path, oflag, mode);
        }
    }
    
    
    %hook AppDelegate
    - (BOOL)application:(id)arg1 didFinishLaunchingWithOptions:(id)arg2 {
    
        // fishfook use
        struct rebinding binds[2];
        // orig_close是一个函数指针,(void *)&orig_close 是一个返回参数,所以用取地址,(void *)&orig_open也是类似的
        struct rebinding bind1 = {"close", (void *)my_close, (void **)&orig_close};
        binds[0] = bind1;
        binds[1] = (struct rebinding){"open", (void *)my_open, (void **)&orig_open};
    
        // rebind_symbols((struct rebinding[2]){{"close", my_close, (void *)&orig_close}, {"open", my_open, (void *)&orig_open}}, 2);
        // 转换为:
        rebind_symbols(binds, 2);
    
        return %orig; 
    }
    
    %end
    

    对应的make文件,注意需要引入FishHook的源文件fishhook.c

    
    #编译debug或者release
    DEBUG = 0
        
    #越狱iPhone的ip地址
    # 需要添加到环境变量中才能生效,命令: "export THEOS_DEVICE_IP=192.168.8.220"
    #THEOS_DEVICE_IP = 192.168.1.122
    THEOS_DEVICE_IP = 192.168.8.215
    
    #指定支持的处理器架构
    ARCHS = armv7 arm64
    
    #指定需要的SDK版本iphone:Base SDK:Deployment Target
    #最新的SDK,程序发布在iOS8.0以上
    TARGET = iphone:latest:8.0
    
    include /opt/theos/makefiles/common.mk
    
    TWEAK_NAME = TouTiaoNewsTweak
    TouTiaoNewsTweak_FILES = Tweak.xm fishhook.c
    
    include $(THEOS_MAKE_PATH)/tweak.mk
    
    #make clean
    clean::
        rm -rf ./packages/*
    
    after-install::
        install.exec "killall -9 News"
    

    启动 今日头条 App,可以监控到该进程的所有的文件操作记录

    Sep  4 21:00:41 iPhone News[1366]: CGContextRestoreGState: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable.
    Sep  4 21:00:41 iPhone News[1366]: Calling real open('/var/mobile/Containers/Data/Application/9462F701-C44A-49BF-83AF-335EDCC9F6B0/Library/Caches/LauchProcess/launchPatch.js', 0)
    Sep  4 21:00:41 iPhone News[1366]: Calling real open('/var/mobile/Containers/Data/Application/9462F701-C44A-49BF-83AF-335EDCC9F6B0/Library/Caches/LauchProcess/activePatch.js', 0)
    Sep  4 21:00:41 iPhone News[1366]: Calling real open('/var/mobile/Containers/Data/Application/9462F701-C44A-49BF-83AF-335EDCC9F6B0/Library/Application Support/com.crashlytics/CLSUserDefaults.plist', 0)
    Sep  4 21:00:41 iPhone News[1366]: Calling real close(4)
    Sep  4 21:00:41 iPhone News[1366]: Calling real open('/var/mobile/Containers/Bundle/Application/7891D858-95FA-4EFF-A1BA-83DCC8099FB6/News.app/News', 0)
    Sep  4 21:00:41 iPhone News[1366]: Calling real close(4)
    Sep  4 21:00:41 iPhone News[1366]: Calling real open('/var/mobile/Containers/Bundle/Application/7891D858-95FA-4EFF-A1BA-83DCC8099FB6/News.app/AppIcon-News60x60@2x~ipad.png', 0)
    

    总结

    FishHook实现的进程文件监控只是一个FishHook一个简单例子,还可以监控进程的其他操作,可以作为逆向的另一个切入点。

    相关文章

      网友评论

          本文标题:iOS逆向之四-FishHook的简单使用

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