Mach-O

格式

Mash-O格式.gif
1. header

header 包含了惕澎,cpu類型,加載command的數(shù)量,文件類型等信息

/*
* The 32-bit mach header appears at the very beginning of the object file for
* 32-bit architectures.
32位 架構(gòu)數(shù)據(jù)結(jié)構(gòu)類型
*/
struct mach_header {
  uint32_t    magic;      /* mach magic number identifier */
  cpu_type_t  cputype;    /* cpu specifier */
  cpu_subtype_t   cpusubtype; /* machine specifier */
  uint32_t    filetype;   /* type of file */
  uint32_t    ncmds;      /* number of load commands */
  uint32_t    sizeofcmds; /* the size of all the load commands */
  uint32_t    flags;      /* flags */
};

/* Constant for the magic field of the mach_header (32-bit architectures) */
#define MH_MAGIC    0xfeedface  /* the mach magic number */
#define MH_CIGAM    0xcefaedfe  /* NXSwapInt(MH_MAGIC) */

/*
* The 64-bit mach header appears at the very beginning of object files for
* 64-bit architectures.
64位架構(gòu)數(shù)據(jù)結(jié)構(gòu)類型
*/
struct mach_header_64 {
  uint32_t    magic;      /* mach magic number identifier */
// 識CPU的架構(gòu) arm x86, i386
  cpu_type_t  cputype;    /* cpu specifier */
// 體的CPU類型颜骤,區(qū)分不同版本的處理器
  cpu_subtype_t   cpusubtype; /* machine specifier */
// 文件類型
  uint32_t    filetype;   /* type of file */
//加載了多少command,每個LoadCommands代表了一種Segment的加載方式
  uint32_t    ncmds;      /* number of load commands */
//LoadCommand的大小唧喉,主要用于劃分Mach-O文件的‘區(qū)域’
  uint32_t    sizeofcmds; /* the size of all the load commands */
  uint32_t    flags;      /* flags */
  uint32_t    reserved;   /* reserved */
};

/* Constant for the magic field of the mach_header_64 (64-bit architectures) */
#define MH_MAGIC_64 0xfeedfacf /* the 64-bit mach magic number */
#define MH_CIGAM_64 0xcffaedfe /* 

經(jīng)常遇見的Mach-O文件類型:

  • MH_OBJECT,這種類型的文件有目標(biāo)文件(.o)、靜態(tài)庫文件(.a) (靜態(tài)庫文件就是N個.o文件合并在一起的)

  • MH_EXECUTE八孝,可執(zhí)行文件董朝,例如上面說的Super文件

  • MH_DYLIB,動態(tài)庫文件干跛,包括.dylib子姜、.framework

  • MH_DYLINKER,動態(tài)鏈接編輯器楼入,例如:位于手機(jī)這里的Device/usr/lib/的dyld程序

MH_DSYM哥捕,存儲二進(jìn)制符號信息的文件,dsym文件常用于分析APP的崩潰信息

loadCommands

用來描述文件在虛擬地址中的布局結(jié)構(gòu),就是存儲著各段數(shù)據(jù)的大小,分段,地址等信息

struct load_command {
    uint32_t cmd;       /* type of load command */
    uint32_t cmdsize;   /* total size of command in bytes */
};
cmd

這些加載指令清晰地告訴加載器如何處理二進(jìn)制數(shù)據(jù)嘉熊,有些命令是由內(nèi)核處理的扭弧,有些是由動態(tài)鏈接器處理的。在源碼中有明顯的注釋來說明這些是動態(tài)連接器處理的记舆。
根據(jù)cmd字段的類型不同鸽捻,使用了不同的函數(shù)來加載.看一看在內(nèi)核代碼中不同的command類型都有哪些作用。

  1. LC-SEGMENT泽腮;LC-SEGMENT-64 在內(nèi)核中由load-segment 函數(shù)處理(將segment中的數(shù)據(jù)加載并映射到進(jìn)程的內(nèi)存空間去)

  2. LC-LOAD-DYLINKER 在內(nèi)核中由load-dylinker 函數(shù)處理(調(diào)用/usr/lib/dyld程序)

  3. LC-UUID 在內(nèi)核中由load-uuid 函數(shù)處理 (加載128-bit的唯一ID)

  4. LC-THREAD 在內(nèi)核中由load-thread 函數(shù)處理 (開啟一個MACH線程御蒲,但是不分配棧空間)

  5. LC-UNIXTHREAD 在內(nèi)核中由load-unixthread 函數(shù)處理 (開啟一個UNIX posix線程)

  6. LC-CODE-SIGNATURE 在內(nèi)核中由load-code-signature 函數(shù)處理 (進(jìn)行數(shù)字簽名)

  7. LC-ENCRYPTION-INFO 在內(nèi)核中由 set-code-unprotect 函數(shù)處理 (加密二進(jìn)制文件)

struct segment_command_64 { /* for 64-bit architectures */
    uint32_t    cmd;        /* LC_SEGMENT_64 */
    uint32_t    cmdsize;    /* includes sizeof section_64 structs */
    char        segname[16];    /* segment name */
    uint64_t    vmaddr;     /* memory address of this segment */
    uint64_t    vmsize;     /* memory size of this segment */
    uint64_t    fileoff;    /* file offset of this segment */
    uint64_t    filesize;   /* amount to map from the file */
    vm_prot_t   maxprot;    /* maximum VM protection */
    vm_prot_t   initprot;   /* initial VM protection */
    uint32_t    nsects;     /* number of sections in segment */
    uint32_t    flags;      /* flags */
};
struct section_64 { /* for 64-bit architectures */
    char        sectname[16];   /* name of this section */
    char        segname[16];    /* segment this section goes in */
    uint64_t    addr;       /* memory address of this section */
    uint64_t    size;       /* size in bytes of this section */
    uint32_t    offset;     /* file offset of this section */
    uint32_t    align;      /* section alignment (power of 2) */
    uint32_t    reloff;     /* file offset of relocation entries */
    uint32_t    nreloc;     /* number of relocation entries */
    uint32_t    flags;      /* flags (section type and attributes)*/
    uint32_t    reserved1;  /* reserved (for offset or index) */
    uint32_t    reserved2;  /* reserved (for count or sizeof) */
    uint32_t    reserved3;  /* reserved */
};

section段

存放著各段的原始數(shù)據(jù)诊赊,就是Load commands區(qū)域描述的地址所指向的數(shù)據(jù)

注入dylib整體思路

1厚满、讀取Mach-O文件信息到內(nèi)存中;

2碧磅、定義一個mach_header碘箍,將原來的mach_header寫到新定義的mach_header中;

3鲸郊、 在新定義的mach_header中依需將ncmds加1丰榴,sizeofcmds加上要注入的dylib庫的大小秆撮;

4四濒、將新定義并修改好的mach_header從Mach-O最開始部分覆蓋原文件的mach_header;

5职辨、指針跳過sizeofcmds大小內(nèi)存盗蟆;

6、定義一個dylib結(jié)構(gòu)體并賦值舒裤,即注入的 dylib 信息喳资;

7、回退(新mach_header中sizeofcmds已包含要注入dylib的大刑诠)并覆蓋仆邓、寫入 path 信息鲜滩。

命令 數(shù)據(jù)結(jié)構(gòu) 用途
LC_UUID uuid_command(page 20) 指定圖像或其對應(yīng)的dSYM文件的128位UUID
LC_SEGMENT segment_command 加載此文件時,定義映射到進(jìn)程地址空間中所需的文件段宏赘。而且每個段中包含了所有的節(jié)
LC_SYMTAB symtab_command 指定了文件的符號表绒北。靜態(tài)鏈接器和動態(tài)連接器連接文件的時候都需要用到這些信息,還可以通過調(diào)試器將符號映射到生成符號的原始源代碼文件察署。
LC_DYSYMTAB dysymtab_command 指定了動態(tài)連接器用到的附帶符號表信息
LC_THREAD LC_UNIXTHREAD thread_command 對于可執(zhí)行文件闷游,LC_UNIXTHREAD命令定義了進(jìn)程主線程的線程狀態(tài)。LC_THREAD和LC_UNIXTHREAD一樣贴汪,但是LC_THREAD不會引起內(nèi)核分配堆棧
LC_LOAD_DYLIB dylib_command 定義此文件鏈接的動態(tài)共享庫的名稱脐往。
LC_ID_DYLIB dylib_command 定義了動態(tài)共享庫安裝名稱
LC_PREBOUND_DYLIB prebound_dylib_command 對于此可執(zhí)行文件鏈接預(yù)綁定的共享庫,指定使用的共享庫中的模塊扳埂。
LC_LOAD_DYLINKER dylinker_command 指定內(nèi)核執(zhí)行加載文件所需的動態(tài)連接器
LC_ID_DYLINKER dylinker_command 標(biāo)志這個文件可以作為動態(tài)連接器
LC_ROUTINES routines_command 包含共享庫初始化例行程序的地址(由鏈接器的-init選項(xiàng)指定)业簿。
LC_ROUTINES_64 routines_command_64 包含共享庫64位初始化例行程序的地址(由鏈接器的-init選項(xiàng)指定)。
LC_TWOLEVEL_HINTS twolevel_hints_command 包含兩級命名空間查詢提示表阳懂。
LC_SUB_FRAMEWORK sub_framework_command 將此文件標(biāo)識為傘形框架的子框架的實(shí)現(xiàn)梅尤。傘形框架的名稱存儲在字符串參數(shù)中。(傘形框架可以包含多個子框架岩调,蘋果不推薦這樣使用)
LC_SUB_UMBRELLA sub_umbrella_command 指定此文件作為傘框架的子傘
LC_SUB_LIBRARY sub_library_command 標(biāo)志這個文件可以作為傘框架的一個字庫的實(shí)現(xiàn)巷燥。請注意,Apple尚未為子庫定義受支持的位置号枕。
LC_SUB_CLIENT sub_client_command 子框架可以明確地允許另一個框架或包鏈接到它缰揪,方法是包含一個LC_SUB_CLIENT load命令,該命令包含框架的名稱或包的客戶端名稱葱淳。

1钝腺、(__TEXT,__text)

這里存放的是匯編后的代碼,當(dāng)我們進(jìn)行編譯時赞厕,每個.m文件會經(jīng)過預(yù)編譯->編譯->匯編形成.o文件艳狐,稱之為目標(biāo)文件。匯編后坑傅,所有的代碼會形成匯編指令存儲在.o文件的(__TEXT,__text)區(qū)((__DATA,__data)也是類似)僵驰。鏈接后,所有的.o文件會合并成一個文件唁毒,所有.o文件的(__TEXT,__text)數(shù)據(jù)都會按鏈接順序存放到應(yīng)用文件的(__TEXT,__text)中。

2星爪、(__DATA,__data)

存儲數(shù)據(jù)的section浆西,static在進(jìn)行非零賦值后會存儲在這里,如果static 變量沒有賦值或者賦值為0顽腾,那么它會存儲在(__DATA,__bss)中近零。

3诺核、Symbol Table

符號表,這個是重點(diǎn)中的重點(diǎn)久信,符號表是將地址和符號聯(lián)系起來的橋梁窖杀。符號表并不能直接存儲符號,而是存儲符號位于字符串表的位置裙士。

4入客、String Table

字符串表所有的變量名、函數(shù)名等腿椎,都以字符串的形式存儲在字符串表中桌硫。

5、動態(tài)符號表

動態(tài)符號表存儲的是動態(tài)庫函數(shù)位于符號表的偏移信息啃炸。(__DATA,__la_symbol_ptr) section 可以從動態(tài)符號表中獲取到該section位于符號表的索引數(shù)組铆隘。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市南用,隨后出現(xiàn)的幾起案子膀钠,更是在濱河造成了極大的恐慌,老刑警劉巖裹虫,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件肿嘲,死亡現(xiàn)場離奇詭異,居然都是意外死亡恒界,警方通過查閱死者的電腦和手機(jī)睦刃,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來十酣,“玉大人涩拙,你說我怎么就攤上這事∷什桑” “怎么了兴泥?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長虾宇。 經(jīng)常有香客問我搓彻,道長,這世上最難降的妖魔是什么嘱朽? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任旭贬,我火速辦了婚禮,結(jié)果婚禮上搪泳,老公的妹妹穿的比我還像新娘稀轨。我一直安慰自己,他們只是感情好岸军,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布奋刽。 她就那樣靜靜地躺著瓦侮,像睡著了一般。 火紅的嫁衣襯著肌膚如雪佣谐。 梳的紋絲不亂的頭發(fā)上肚吏,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天,我揣著相機(jī)與錄音狭魂,去河邊找鬼罚攀。 笑死,一個胖子當(dāng)著我的面吹牛趁蕊,可吹牛的內(nèi)容都是我干的坞生。 我是一名探鬼主播,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼掷伙,長吁一口氣:“原來是場噩夢啊……” “哼是己!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起任柜,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤卒废,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后宙地,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體摔认,經(jīng)...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年宅粥,在試婚紗的時候發(fā)現(xiàn)自己被綠了参袱。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,161評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡秽梅,死狀恐怖抹蚀,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情企垦,我是刑警寧澤环壤,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站钞诡,受9級特大地震影響郑现,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜荧降,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一接箫、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧朵诫,春花似錦列牺、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至随夸,卻和暖如春九默,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背宾毒。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工驼修, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人诈铛。 一個月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓乙各,卻偏偏與公主長得像,于是被迫代替她去往敵國和親幢竹。 傳聞我的和親對象是個殘疾皇子耳峦,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,916評論 2 344

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

  • 概述 ??本文檔描述了Mach-O文件格式的結(jié)構(gòu),它被用來存儲程序和庫到硬盤中焕毫,作為Mac OS X程序的二進(jìn)制接...
    VenpleD閱讀 1,411評論 0 5
  • 上一篇說到源碼經(jīng)過預(yù)處理蹲坷、編譯、匯編之后生成目標(biāo)文件邑飒,這一章介紹一下iOS循签、Mac OS中目標(biāo)文件的格式Mach-...
    Tenloy閱讀 2,008評論 2 9
  • Mach-o文件 Mach-O 是iOS/macOS系統(tǒng)上應(yīng)用程序的格式 通用二進(jìn)制文件(胖二進(jìn)制文件) 因?yàn)镸a...
    CharType閱讀 954評論 0 2
  • 一、什么是Mach-O文件疙咸? Mach-O是 Mach Object文件格式的縮寫县匠,是 mac以及 iOS上可執(zhí)行...
    黑白森林無間道閱讀 1,023評論 1 2
  • 一、什么是Mach-O文件撒轮? Mach-O是Mach Object文件格式的縮寫乞旦,是mac以及iOS上可執(zhí)行文件的...
    yahibo閱讀 486評論 0 1