美文网首页
各种Hook开发代码集锦

各种Hook开发代码集锦

作者: D_8270 | 来源:发表于2020-07-14 14:44 被阅读0次

    MonkeyDev的MonkeyApp模板的开发

    fishhook Hook带符号的C函数

    XXX.m文件
    
    #include <mach-o/dyld.h>
    #include "fishhook/fishhook.h"
    
    /*以_dyld_get_image_name为例,该函数为获取当前应用的二进制文件中所有的镜像完整路径,配合_dyld_image_count函数使用*/
    static char *(*dyld_get_image_name_old123)(uint32_t index);
    char *dyld_get_image_name_mine(uint32_t index);
    char *dyld_get_image_name_mine(uint32_t index)
    {
        char *imageName = dyld_get_image_name_old123(index);
        printf("hook到了 \n%s",imageName);
        return imageName;
    }
    
    CHConstructor{
        MSHookFunction((void *)_dyld_get_image_name,(void *)dyld_get_image_name_mine, (void **)&dyld_get_image_name_old123);
        struct rebinding bind;//要HOOK系统函数的函数名称
        bind.name = "_dyld_get_image_name";
        bind.replacement = (void *)dyld_get_image_name_mine;//新的函数去替换系统的函数
        bind.replaced = (void **)&dyld_get_image_name_old123;//把真正的系统函数地址保存到dyld_get_image_name_old123
        struct rebinding rebs[] = {bind};
        rebind_symbols(rebs, 1);
    }
    

    Theos开发

    MSHookFunction Hook带符号的C函数

    XXX.m文件
    
    #include <mach-o/dyld.h>
    #import <CydiaSubstrate/CydiaSubstrate.h>
    
    /*以_dyld_get_image_name为例,该函数为获取当前应用的二进制文件中所有的镜像完整路径,配合_dyld_image_count函数使用*/
    static char *(*dyld_get_image_name_old123)(uint32_t index);
    char *dyld_get_image_name_mine(uint32_t index);
    char *dyld_get_image_name_mine(uint32_t index)
    {
        char *imageName = dyld_get_image_name_old123(index);
        printf("hook到了 \n%s",imageName);
        return imageName;
    }
    
    CHConstructor{
        MSHookFunction((void *)_dyld_get_image_name,(void *)dyld_get_image_name_mine, (void **)&dyld_get_image_name_old123);
    }
    

    MSHookFunction Hook无符号的C函数

    XXX.m文件
    
    #include <mach-o/dyld.h>
    #import <CydiaSubstrate/CydiaSubstrate.h>
    
    //偏移量
    intptr_t g_slide;
    
    //保存模块偏移基地址的值
    static void _register_func_for_add_image(const struct mach_header *header, intptr_t slide) {
        Dl_info image_info;
        int result = dladdr(header, &image_info);
        if (result == 0) {
            NSLog(@"load mach_header failed");
            return;
        }
        //获取当前的可执行文件路径
        NSString *execName = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleExecutable"];
        NSString *execPath = [[[NSBundle mainBundle] bundlePath] stringByAppendingFormat:@"/%@", execName];
        if (strcmp([execPath UTF8String], image_info.dli_fname) == 0) {
            g_slide = slide;
        }
        
        //如果需要获取可执行文件中引入的某一个模块(如你加入的XXX.dylib)在内存中的偏移量
        //则需要判断image_info.dli_fname中是否h包含字符串XXX.dylib
    //    NSString *fname = [NSString stringWithUTF8String:image_info.dli_fname];
    //    if ([fname containsString:@"XXX.dylib"]) {
    //        g_slide = slide
    //    }
    }
    
    void (*orig_testMethod)(void);
    void hook_testMethod(void);
    
    //hook后会来到这里
    void hook_testMethod(void) {
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"hook了我" message:@"message" delegate:nil cancelButtonTitle:nil otherButtonTitles:@"other", nil];
        [alert show];
    }
    
    CHConstructor{
      //注册添加镜像回调,应用每加载一个模块时都会产生一个回调,此处我们提供这样一个回调函数,以接收每个模块的信息
        _dyld_register_func_for_add_image(_register_func_for_add_image);
        //通过 模块偏移前的基地址 + ASLR偏移量 找到函数真正的地址进行hook
      /*解释:一个应用的可执行文件也属于一个模块,也会被加载进内存中,其内部引入的所有系统库或者是第三方库都会被加载进内存中,每个可执行文件或是dylib在IDA/Hopper中打开地址都是从0开始的,注意要正确选择在IDA/Hopper中打开时选择的armv7或arm64架构类型,当这些模块被加载进内存时,这些模块中的所有方法的地址都会改变,改变的就是这个ASLR偏移量,所以我们定位到某个函数的地址时,只需找到其在IDA/Hopper中对应的地址再加上ASLR偏移量就是该函数最终真正在内存中的地址*/
     //这个0x1000065f0就是testMethod在Hopper中打开时显示的地址,注意选择正确的架构
        MSHookFunction((void *)(0x1000065f0+g_slide), (void *)hook_testMethod, (void **)&orig_testMethod);
    }
    
    

    如何处理sub_xxx函数(非越狱环境)?

    如果分析到目标sub_xxx函数之后,可以直接静态修改二进制文件,用Hopper打开目标二进制文件,注意选择正确的架构,然后定位到调用sub_xxx函数的地方(一般是bl sub_xxx这样的),在要修改的语句上按Alt + A,将当前汇编指令修改为nop(nop是arm汇编里的一条空指令,即什么也不做)即可,但这样只能完全阻止调用sub_xxx,如果只是需要在sub_xxx函数中插入一点逻辑,则需另外想办法,然后Hopper->File->Produce New Executable... 保存为新的二进制文件或lib,现在大部分只有arm64,如果还需要armv7的,则将原二进制文件以armv7的架构打开,找到sub_xxx执行上述的操作并保存, 将上面两个得到的二进制文件合并lipo

    相关文章

      网友评论

          本文标题:各种Hook开发代码集锦

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