Mach-o 小記

https://opensource.apple.com/source/dyld/dyld-132.13/src/
http://turingh.github.io/2016/03/01/dyld%E4%B8%ADmacho%E5%8A%A0%E8%BD%BD%E7%9A%84%E7%AE%80%E5%8D%95%E5%88%86%E6%9E%90/
https://www.objc.io/issues/6-build-tools/mach-o-executables/
https://lowlevelbits.org/parsing-mach-o-files/

uint64_t FilegetSize(const char *file_path){
    struct stat buf;
    if ( stat(file_path,&buf) < 0 )
    {
        perror(file_path);
        exit(1);
    }
    return buf.st_size;
}

void loadMachO()
{
    char *filePath = [[[NSBundle mainBundle] pathForResource:@"MachOMethodRe" ofType:@""] UTF8String];
    
    FILE *fp_open = fopen(filePath,"r");
    uint64_t file_size = FilegetSize(filePath);
    if(!fp_open){
        printf("file isn't exist\n");
        exit(1);
    }
    printf("file size is 0x%llx\n\n",file_size);
    void *file_buf = malloc(file_size);
    if(fread(file_buf,1,file_size,fp_open)!=file_size){
        printf("fread error\n");
        exit(1);
    }
    fclose(fp_open);
    
    //檢查是否為Fat頭
    struct fat_header* fileStartAsFat = (struct fat_header*)file_buf;
    if(fileStartAsFat->magic == FAT_CIGAM || fileStartAsFat->magic == FAT_MAGIC){
        printf("is fat\n");
        //        exit(1);
    }
    
    //檢查mach-o文件最前面幾個(gè)字節(jié)的內(nèi)容.
    struct mach_header *mh = (struct mach_header*)file_buf;
    int is32 = 1;
    
    if(mh->magic==MH_MAGIC||mh->magic==MH_CIGAM){
        is32 = 1;
    } else if(mh->magic==MH_MAGIC_64||mh->magic==MH_CIGAM_64){
        is32 = 0;
    }
    
    const uint32_t cmd_count = mh->ncmds;
    
    const struct load_command* const startCmds    = (struct load_command*)(((uint8_t*)mh) + sizeof(struct mach_header));
    //獲取command段結(jié)束的地址,endCmds = mach-o地址 + mach-o頭部長度 + cmds所用的長度
    const struct load_command* cmd = startCmds;
    
    unsigned long size;
    
    
    for (uint32_t i = 0; i < cmd_count; ++i) {
        uint32_t cmdLength = cmd->cmdsize;
        struct segment_command * segCmd;
        const struct load_command* const nextCmd = (const struct load_command*)(((char*)cmd)+cmdLength);
        switch (cmd->cmd) {
            case LC_SEGMENT:
            {
                segCmd = (struct segment_command *)cmd;
                NSLog(@"segname = %s",segCmd->segname);
                
                if (strcmp(segCmd->segname, "__TEXT") == 0) {
                    struct section * sectionsStart = NULL;
                    struct section * nextSection = NULL;
                    for (int i = 0; i < segCmd->nsects; i++) {
                        
                        if (i == 0) {
                            sectionsStart = (struct section *)((char *)cmd + sizeof(struct segment_command));
                            nextSection = sectionsStart;
                            
                        } else {
                            nextSection = (struct section *)((char *)nextSection + sizeof(struct section));
                        }
                        
                        if (strncmp(nextSection->sectname, "__objc_methname", strlen("__objc_methname"))==0) {
                            NSLog(@"***** 修改方法名 ****");
                        }
                        if (strncmp(nextSection->sectname, "__objc_classname", strlen("__objc_classname"))==0) {
                            NSLog(@"***** 修改類名 *****");
                        }
                        NSLog(@"sectionName = %s , segName = %s",nextSection->sectname,nextSection->segname);
                    }
                }
            }
                break;
                
            default:
                break;
        }
        cmd = nextCmd;
    }
    
}



unsigned int count;
    const char **classes;
    Dl_info info;
    
    dladdr(&_mh_execute_header, &info);
    classes = objc_copyClassNamesForImage(info.dli_fname, &count);
    
    for (int i = 0; i < count; i++) {
        NSLog(@"Class name: %s", classes[i]);
        Class class = NSClassFromString ([NSString stringWithCString:classes[i] encoding:NSUTF8StringEncoding]);
        // Do something with class
        
    }



最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末喜命,一起剝皮案震驚了整個(gè)濱河市蜡饵,隨后出現(xiàn)的幾起案子唉韭,更是在濱河造成了極大的恐慌践付,老刑警劉巖儡首,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件翘瓮,死亡現(xiàn)場離奇詭異稿茉,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)掏导,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進(jìn)店門窄俏,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人碘菜,你說我怎么就攤上這事。” “怎么了忍啸?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵仰坦,是天一觀的道長。 經(jīng)常有香客問我计雌,道長悄晃,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任凿滤,我火速辦了婚禮妈橄,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘翁脆。我一直安慰自己眷蚓,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布反番。 她就那樣靜靜地躺著沙热,像睡著了一般。 火紅的嫁衣襯著肌膚如雪罢缸。 梳的紋絲不亂的頭發(fā)上篙贸,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天,我揣著相機(jī)與錄音枫疆,去河邊找鬼爵川。 笑死,一個(gè)胖子當(dāng)著我的面吹牛息楔,可吹牛的內(nèi)容都是我干的寝贡。 我是一名探鬼主播,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼钞螟,長吁一口氣:“原來是場噩夢啊……” “哼兔甘!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起鳞滨,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤洞焙,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后拯啦,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體澡匪,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年褒链,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了唁情。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,039評論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡甫匹,死狀恐怖甸鸟,靈堂內(nèi)的尸體忽然破棺而出惦费,到底是詐尸還是另有隱情,我是刑警寧澤抢韭,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布薪贫,位于F島的核電站,受9級特大地震影響刻恭,放射性物質(zhì)發(fā)生泄漏瞧省。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一鳍贾、第九天 我趴在偏房一處隱蔽的房頂上張望鞍匾。 院中可真熱鬧,春花似錦骑科、人聲如沸橡淑。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽梳码。三九已至,卻和暖如春伍掀,著一層夾襖步出監(jiān)牢的瞬間掰茶,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工蜜笤, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留濒蒋,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓把兔,卻偏偏與公主長得像沪伙,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子县好,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,786評論 2 345

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