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 */
// 識(shí)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,每個(gè)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)常遇見(jiàn)的Mach-O文件類型:

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

  • MH_EXECUTE,可執(zhí)行文件,例如上面說(shuō)的Super文件

  • MH_DYLIB,動(dòng)態(tài)庫(kù)文件,包括.dylib、.framework

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

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

loadCommands

用來(lái)描述文件在虛擬地址中的布局結(jié)構(gòu),就是存儲(chǔ)著各段數(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)核處理的,有些是由動(dòng)態(tài)鏈接器處理的。在源碼中有明顯的注釋來(lái)說(shuō)明這些是動(dòng)態(tài)連接器處理的。
根據(jù)cmd字段的類型不同,使用了不同的函數(shù)來(lái)加載.看一看在內(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ù)處理 (開(kāi)啟一個(gè)MACH線程,但是不分配??臻g)

  5. LC-UNIXTHREAD 在內(nèi)核中由load-unixthread 函數(shù)處理 (開(kāi)啟一個(gè)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、定義一個(gè)mach_header,將原來(lái)的mach_header寫(xiě)到新定義的mach_header中;

3、 在新定義的mach_header中依需將ncmds加1,sizeofcmds加上要注入的dylib庫(kù)的大?。?/p>

4、將新定義并修改好的mach_header從Mach-O最開(kāi)始部分覆蓋原文件的mach_header;

5、指針跳過(guò)sizeofcmds大小內(nèi)存;

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

7、回退(新mach_header中sizeofcmds已包含要注入dylib的大?。┎⒏采w、寫(xiě)入 path 信息。

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

1、(__TEXT,__text)

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

2、(__DATA,__data)

存儲(chǔ)數(shù)據(jù)的section,static在進(jìn)行非零賦值后會(huì)存儲(chǔ)在這里,如果static 變量沒(méi)有賦值或者賦值為0,那么它會(huì)存儲(chǔ)在(__DATA,__bss)中。

3、Symbol Table

符號(hào)表,這個(gè)是重點(diǎn)中的重點(diǎn),符號(hào)表是將地址和符號(hào)聯(lián)系起來(lái)的橋梁。符號(hào)表并不能直接存儲(chǔ)符號(hào),而是存儲(chǔ)符號(hào)位于字符串表的位置。

4、String Table

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

5、動(dòng)態(tài)符號(hào)表

動(dòng)態(tài)符號(hào)表存儲(chǔ)的是動(dòng)態(tài)庫(kù)函數(shù)位于符號(hào)表的偏移信息。(__DATA,__la_symbol_ptr) section 可以從動(dòng)態(tài)符號(hào)表中獲取到該section位于符號(hào)表的索引數(shù)組。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 概述 ??本文檔描述了Mach-O文件格式的結(jié)構(gòu),它被用來(lái)存儲(chǔ)程序和庫(kù)到硬盤(pán)中,作為Mac OS X程序的二進(jìn)制接...
    VenpleD閱讀 1,662評(píng)論 0 5
  • 上一篇說(shuō)到源碼經(jīng)過(guò)預(yù)處理、編譯、匯編之后生成目標(biāo)文件,這一章介紹一下iOS、Mac OS中目標(biāo)文件的格式Mach-...
    Tenloy閱讀 2,226評(píng)論 2 9
  • Mach-o文件 Mach-O 是iOS/macOS系統(tǒng)上應(yīng)用程序的格式 通用二進(jìn)制文件(胖二進(jìn)制文件) 因?yàn)镸a...
    CharType閱讀 1,232評(píng)論 0 2
  • 一、什么是Mach-O文件? Mach-O是 Mach Object文件格式的縮寫(xiě),是 mac以及 iOS上可執(zhí)行...
    黑白森林無(wú)間道閱讀 1,254評(píng)論 1 2
  • 一、什么是Mach-O文件? Mach-O是Mach Object文件格式的縮寫(xiě),是mac以及iOS上可執(zhí)行文件的...
    yahibo閱讀 634評(píng)論 0 1

友情鏈接更多精彩內(nèi)容