美文网首页
越狱-相关防护

越狱-相关防护

作者: king_jensen | 来源:发表于2019-01-29 21:59 被阅读6次

    一.通过DYLD的dyld_insert_library环境变量防护

    1.原理(查看dyld-519.2.2源码)
    // load any inserted libraries
            if  ( sEnv.DYLD_INSERT_LIBRARIES != NULL ) {
                for (const char* const* lib = sEnv.DYLD_INSERT_LIBRARIES; *lib != NULL; ++lib) 
                    loadInsertedDylib(*lib);
            }
    

    源码中通过判断DYLD_INSERT_LIBRARIES,如果不是NULL,就直接调用loadInsertedDylib进行动态库的插入。
    在调用以上代码插入动态库之前,DYLD还是有对DYLD_INSERT_LIBRARIES进行限制的:

      if ( gLinkContext.processIsRestricted ) {
            pruneEnvironmentVariables(envp, &apple);
            // set again because envp and apple may have changed or moved
            setContext(mainExecutableMH, argc, argv, envp, apple);
        }
    

    首先调用 gLinkContext.processIsRestricted判断DYLD_INSERT_LIBRARIES,如果是受限制, 就直接移除环境变量。
    直接全局搜索 processIsRestricted = true查看什么情况下会受限制.

    static bool hasRestrictedSegment(const macho_header* mh)
    {
        const uint32_t cmd_count = mh->ncmds;
        const struct load_command* const cmds = (struct load_command*)(((char*)mh)+sizeof(macho_header));
        const struct load_command* cmd = cmds;
        for (uint32_t i = 0; i < cmd_count; ++i) {
            switch (cmd->cmd) {
                case LC_SEGMENT_COMMAND:
                {
                    const struct macho_segment_command* seg = (struct macho_segment_command*)cmd;
                    
                    //dyld::log("seg name: %s\n", seg->segname);
                    if (strcmp(seg->segname, "__RESTRICT") == 0) {
                        const struct macho_section* const sectionsStart = (struct macho_section*)((char*)seg + sizeof(struct macho_segment_command));
                        const struct macho_section* const sectionsEnd = &sectionsStart[seg->nsects];
                        for (const struct macho_section* sect=sectionsStart; sect < sectionsEnd; ++sect) {
                            if (strcmp(sect->sectname, "__restrict") == 0) 
                                return true;
                        }
                    }
                }
                break;
            }
            cmd = (const struct load_command*)(((char*)cmd)+cmd->cmdsize);
        }
            
        return false;
    }
    

    通过上述DYLD代码,我们知道matchO中需要有segment为__RESTRICT,且段中需要有section为__restrict,即可限制动态库的插入。

    2.实现防护

    (1)配置环境变量


    7C76F593F390673B235597B98893ED5F.png

    (2)编译,查看MatchO


    0CA90C42DEE61B26A394275784566DD8.png

    这样就能防止插入动态库了。但是如果仅仅只是这只环境变量的话,黑客只需要修改MatchO的这个段,就可以破解这个防护了。
    为了增加破解难度,我们可以自己检测这个段是否被修改。
    (3)检测段是否被修改,增加破解难度。

    #import "ViewController.h"
    #import <mach-o/loader.h>
    #import <mach-o/dyld.h>
    
    @interface ViewController ()
    
    @end
    
    #if __LP64__
    #define macho_header               mach_header_64
    #define LC_SEGMENT_COMMAND        LC_SEGMENT_64
    #define LC_SEGMENT_COMMAND_WRONG LC_SEGMENT
    #define LC_ENCRYPT_COMMAND        LC_ENCRYPTION_INFO
    #define macho_segment_command    segment_command_64
    #define macho_section            section_64
    #else
    #define macho_header               mach_header
    #define LC_SEGMENT_COMMAND        LC_SEGMENT
    #define LC_SEGMENT_COMMAND_WRONG LC_SEGMENT_64
    #define LC_ENCRYPT_COMMAND        LC_ENCRYPTION_INFO_64
    #define macho_segment_command    segment_command
    #define macho_section            section
    #endif
    
    @implementation ViewController
    +(void)load
    {
        const struct mach_header_64 * header = _dyld_get_image_header(0);
        if (hasRestrictedSegment(header)) {
            NSLog(@"正常");
        }else{
            NSLog(@"Restrict被修改了");
        }
    }
    
    static bool hasRestrictedSegment(const struct macho_header* mh)
    {
        const uint32_t cmd_count = mh->ncmds;
        const struct load_command* const cmds = (struct load_command*)(((char*)mh)+sizeof(struct macho_header));
        const struct load_command* cmd = cmds;
        for (uint32_t i = 0; i < cmd_count; ++i) {
            switch (cmd->cmd) {
                case LC_SEGMENT_COMMAND:
                {
                    const struct macho_segment_command* seg = (struct macho_segment_command*)cmd;
                    
                    printf("seg name: %s\n", seg->segname);
                    if (strcmp(seg->segname, "__RESTRICT") == 0) {
                        const struct macho_section* const sectionsStart = (struct macho_section*)((char*)seg + sizeof(struct macho_segment_command));
                        const struct macho_section* const sectionsEnd = &sectionsStart[seg->nsects];
                        for (const struct macho_section* sect=sectionsStart; sect < sectionsEnd; ++sect) {
                            if (strcmp(sect->sectname, "__restrict") == 0)
                                return true;
                        }
                    }
                }
                    break;
            }
            cmd = (const struct load_command*)(((char*)cmd)+cmd->cmdsize);
        }
        
        return false;
    }
    @end
    

    (4).总结:支付宝早期的版本也有使用这种方式防护。但是很遗憾,从iOS 10以后,dyld已不在检测__RESCRICT这个段,因此这种防护在iOS 10以后,已经失效。
    那么iOS 10以后如何防护呢?

    二.白名单检测

    (1).获取到APP中需要的所有库,保存下来。
    (2).APP启动后,检测所有第三方库,并查找每个库是否在之前保存的库中,如果找到不存在的库,即认为是有风险的。

    bool HKCheckWhitelist(){
        int count = _dyld_image_count();//加载了多少数量
        for (int i = 1; i < count; i++) { 
            //遍历拿到库名称!
           const char * imageName = _dyld_get_image_name(i);
            if (!strstr(libraries, imageName)) {
                printf("该库非白名单之内!!\n%s",imageName);
               return NO;
            }
        }
        return YES;
    }
    

    判断是否越狱手机的方式(判断DYLD_INSERT_LIBRARY是否有值)

      char * dlname = getenv("DYLD_INSERT_LIBRARY");
        if (dlname) {
            NSLog(@"越狱设备");
        }
    

    注意点:不同系统,不同型号的设备,所依赖的库可能不一样,因此需要进行处理。

    三、越狱检测

        char * dlname = getenv("DYLD_INSERT_LIBRARIES");
        if (dlname) {
            NSLog(@"越狱手机,关闭部分功能");
        }else{
            NSLog(@"正常手机!");
        }
    

    相关文章

      网友评论

          本文标题:越狱-相关防护

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