注入檢測,越獄檢測筆記

+ (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")) {
        // 自由發(fā)揮
        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{//越獄檢測
    //以下檢測的過程是越往下魁莉,越獄越高級(jí)
    
    //    /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注入動(dòng)態(tài)庫
    //那么可以爆班,檢測當(dāng)前程序運(yùn)行的環(huán)境變量
    char *env = getenv("DYLD_INSERT_LIBRARIES");
    if (env != NULL) {
        return YES;
    }
    
    return NO;
}

想在main之前執(zhí)行
__attribute__((constructor)) void initFuc0()
{
 printf("initFuc0 \n");
}

系統(tǒng)重啟時(shí)間
+ (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;
}

參考
http://www.reibang.com/p/1de663f64c05
https://www.dllhook.com/post/154.html

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末甚颂,一起剝皮案震驚了整個(gè)濱河市蜜猾,隨后出現(xiàn)的幾起案子秀菱,更是在濱河造成了極大的恐慌,老刑警劉巖蹭睡,帶你破解...
    沈念sama閱讀 211,123評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件衍菱,死亡現(xiàn)場離奇詭異,居然都是意外死亡肩豁,警方通過查閱死者的電腦和手機(jī)脊串,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來清钥,“玉大人洪规,你說我怎么就攤上這事⊙啵” “怎么了斩例?”我有些...
    開封第一講書人閱讀 156,723評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長从橘。 經(jīng)常有香客問我念赶,道長,這世上最難降的妖魔是什么恰力? 我笑而不...
    開封第一講書人閱讀 56,357評(píng)論 1 283
  • 正文 為了忘掉前任叉谜,我火速辦了婚禮,結(jié)果婚禮上踩萎,老公的妹妹穿的比我還像新娘停局。我一直安慰自己,他們只是感情好香府,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,412評(píng)論 5 384
  • 文/花漫 我一把揭開白布董栽。 她就那樣靜靜地躺著,像睡著了一般企孩。 火紅的嫁衣襯著肌膚如雪锭碳。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,760評(píng)論 1 289
  • 那天勿璃,我揣著相機(jī)與錄音擒抛,去河邊找鬼。 笑死补疑,一個(gè)胖子當(dāng)著我的面吹牛歧沪,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播莲组,決...
    沈念sama閱讀 38,904評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼诊胞,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了胁编?” 一聲冷哼從身側(cè)響起厢钧,我...
    開封第一講書人閱讀 37,672評(píng)論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎嬉橙,沒想到半個(gè)月后早直,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,118評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡市框,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,456評(píng)論 2 325
  • 正文 我和宋清朗相戀三年霞扬,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片枫振。...
    茶點(diǎn)故事閱讀 38,599評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡喻圃,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出粪滤,到底是詐尸還是另有隱情斧拍,我是刑警寧澤,帶...
    沈念sama閱讀 34,264評(píng)論 4 328
  • 正文 年R本政府宣布杖小,位于F島的核電站肆汹,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏予权。R本人自食惡果不足惜昂勉,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,857評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望扫腺。 院中可真熱鬧岗照,春花似錦、人聲如沸笆环。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,731評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽躁劣。三九已至嗓袱,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間习绢,已是汗流浹背渠抹。 一陣腳步聲響...
    開封第一講書人閱讀 31,956評(píng)論 1 264
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留闪萄,地道東北人梧却。 一個(gè)月前我還...
    沈念sama閱讀 46,286評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像败去,于是被迫代替她去往敵國和親放航。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,465評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容