美文网首页
注入检测,越狱检测笔记

注入检测,越狱检测笔记

作者: Jody526 | 来源:发表于2019-12-14 14:59 被阅读0次
    + (void)load {
        _dyld_register_func_for_add_image(&image_added);
        _dyld_register_func_for_remove_image(&image_removed);
    }
    
    #pragma mark - Callbacks
    
    static void image_added(const struct mach_header *mh, intptr_t slide) {
        _print_image(mh, true);
    }
    
    static void image_removed(const struct mach_header *mh, intptr_t slide) {
        _print_image(mh, false);
    }
    
    #pragma mark - Logger
    
    static void _print_image(const struct mach_header *mh, bool added) {
        Dl_info image_info;
        int result = dladdr(mh, &image_info);
        
        if (result == 0) {
            printf("Could not print info for mach_header: %p\n\n", mh);
            return;
        }
        
        const char *image_name = image_info.dli_fname;
        
        const intptr_t image_base_address = (intptr_t)image_info.dli_fbase;
        const uint64_t image_text_size = _image_text_segment_size(mh);
        
        char image_uuid[37];
        const uuid_t *image_uuid_bytes = _image_retrieve_uuid(mh);
        uuid_unparse(*image_uuid_bytes, image_uuid);
        
        const char *log = added ? "Added" : "Removed";
        printf("%s: 0x%02lx (0x%02llx) %s <%s>\n\n", log, image_base_address, image_text_size, image_name, image_uuid);
        
        /*
        if (strstr(image_name, "MobileSubstrate.dylib")) {
            // 自由发挥
            exit();
        }
        */
    }
    
    #pragma mark - Private
    
    static uint32_t _image_header_size(const struct mach_header *mh) {
        bool is_header_64_bit = (mh->magic == MH_MAGIC_64 || mh->magic == MH_CIGAM_64);
        return (is_header_64_bit ? sizeof(struct mach_header_64) : sizeof(struct mach_header));
    }
    
    static void _image_visit_load_commands(const struct mach_header *mh, void (^visitor)(struct load_command *lc, bool *stop)) {
        assert(visitor != NULL);
        
        uintptr_t lc_cursor = (uintptr_t)mh + _image_header_size(mh);
        
        for (uint32_t idx = 0; idx < mh->ncmds; idx++) {
            struct load_command *lc = (struct load_command *)lc_cursor;
            
            bool stop = false;
            visitor(lc, &stop);
            
            if (stop) {
                return;
            }
            
            lc_cursor += lc->cmdsize;
        }
    }
    
    static uint64_t _image_text_segment_size(const struct mach_header *mh) {
        static const char *text_segment_name = "__TEXT";
        
        __block uint64_t text_size = 0;
        
        _image_visit_load_commands(mh, ^ (struct load_command *lc, bool *stop) {
            if (lc->cmdsize == 0) {
                return;
            }
            if (lc->cmd == LC_SEGMENT) {
                struct segment_command *seg_cmd = (struct segment_command *)lc;
                if (strcmp(seg_cmd->segname, text_segment_name) == 0) {
                    text_size = seg_cmd->vmsize;
                    *stop = true;
                    return;
                }
            }
            if (lc->cmd == LC_SEGMENT_64) {
                struct segment_command_64 *seg_cmd = (struct segment_command_64 *)lc;
                if (strcmp(seg_cmd->segname, text_segment_name) == 0) {
                    text_size = seg_cmd->vmsize;
                    *stop = true;
                    return;
                }
            }
        });
        
        return text_size;
    }
    
    static const uuid_t *_image_retrieve_uuid(const struct mach_header *mh) {
        __block const struct uuid_command *uuid_cmd = NULL;
        
        _image_visit_load_commands(mh, ^ (struct load_command *lc, bool *stop) {
            if (lc->cmdsize == 0) {
                return;
            }
            if (lc->cmd == LC_UUID) {
                uuid_cmd = (const struct uuid_command *)lc;
                *stop = true;
            }
        });
        
        if (uuid_cmd == NULL) {
            return NULL;
        }
        
        return &uuid_cmd->uuid;
    }
    
    越狱检测 
    
    extern char ** environ;
    
    + (BOOL)mgjpf_isJailbroken{//越狱检测
        //以下检测的过程是越往下,越狱越高级
        
        //    /Applications/Cydia.app, /privte/var/stash
        NSString *cydiaPath = @"/Applications/Cydia.app";
        NSString *aptPath = @"/private/var/lib/apt/";
        if ([[NSFileManager defaultManager] fileExistsAtPath:cydiaPath]) {
            return YES;
        }
        if ([[NSFileManager defaultManager] fileExistsAtPath:aptPath]) {
            return YES;
        }
        
        //可能存在hook了NSFileManager方法,此处用底层C stat去检测
        struct stat stat_info;
        if (0 == stat("/Library/MobileSubstrate/MobileSubstrate.dylib", &stat_info)) {
             return YES;
        }
        if (0 == stat("/Applications/Cydia.app", &stat_info)) {
             return YES;
        }
        if (0 == stat("/var/lib/cydia/", &stat_info)) {
             return YES;
        }
        if (0 == stat("/var/cache/apt", &stat_info)) {
             return YES;
        }   
     
        char ** envir = environ;
        int index = 0;
        
        while(*envir)
        {
            int n;
            char *s1 = *envir;
            char *s2 = "MobileSubstrate";
            while (*s1)
            {
                for (n = 0; *(s1 + n) == *(s2 + n); n ++)
                {
                    if (!*(s2 + n + 1))
                        index++;
                }
                s1++;
            }
            envir++;
        }
        
        if (index >0) {
            return YES;
        }
    
        //如果攻击者给MobileSubstrate改名,但是原理都是通过DYLD_INSERT_LIBRARIES注入动态库
        //那么可以,检测当前程序运行的环境变量
        char *env = getenv("DYLD_INSERT_LIBRARIES");
        if (env != NULL) {
            return YES;
        }
        
        return NO;
    }
    
    想在main之前执行
    __attribute__((constructor)) void initFuc0()
    {
     printf("initFuc0 \n");
    }
    
    系统重启时间
    + (long)bootTime{
    #define MIB_SIZE 2
        int mib[2];
        size_t size;
        struct timeval  boottime;
        
        mib[0] = CTL_KERN;
        mib[1] = KERN_BOOTTIME;
        size = sizeof(boottime);
        if (sysctl(mib, MIB_SIZE, &boottime, &size, NULL, 0) != -1)
        {
            return boottime.tv_sec;
        }
        return 0;
    }
    
    

    参考
    https://www.jianshu.com/p/1de663f64c05
    https://www.dllhook.com/post/154.html

    相关文章

      网友评论

          本文标题:注入检测,越狱检测笔记

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