Mach-O文件結構

Mach-O類型的文件

  • Mach-O是一種文件的格式; 是iOS/Mac OS上存儲程序以及庫的標準格式

    • Mach Object
  • Mach-O格式的文件

#define MH_OBJECT   0x1     /* 目標文件*/
#define MH_EXECUTE  0x2     /* 可執行文件 */
#define MH_FVMLIB   0x3     /* fixed VM shared library file */
#define MH_CORE     0x4     /*核心轉儲文件 */
#define MH_PRELOAD  0x5     /* preloaded executable file */
#define MH_DYLIB    0x6     /* dynamically bound shared library */
#define MH_DYLINKER 0x7     /* dynamic link editor */
#define MH_BUNDLE   0x8     /* dynamically bound bundle file */
#define MH_DYLIB_STUB   0x9     /* shared library stub for static */
                    /*  linking only, no section contents */
#define MH_DSYM     0xa     /* companion file with only debug */
                    /*  sections */
#define MH_KEXT_BUNDLE  0xb     /* x86_64 kexts */
  • 常見的Mach-O格式的文件

    • MH_OBJECT 目標文件

      • .o

      • .a/ .framework靜態庫

        • 靜態庫即多個.o文件存放在一起實現特定的功能
    • MH_EXECUTE 可執行文件

      • .app/MyApp

      • .out

    • MH_DYLIB 動態庫

      • .framework/xxx

      • /dylib

    • MH_DYLINKER 動態鏈接器

      • usr/lib/dyld
    • MH_DSYM 存儲二進制文件符號信息的文件

      • .dYSM/Contents/Resources/DWARF/MyApp
    image.png
  • 查看項目targetMach-O文件的類型

    • MH_EXECUTE類型
    image.png

Mach-O文件的基本結構

  • Mach-O包含三個主要區域

    • Header: 文件類型, 目標架構

    • Load command: 描述文件在虛擬內存中的邏輯與布局

    • Raw segment date: Load command中定義的原始數據

image.png
  • 使用otool查看Mach-O文件
? otool -h  DingTalk
Mach header
      magic cputype cpusubtype  caps    filetype ncmds sizeofcmds      flags
 0xfeedface      12          9  0x00           2    79       7860 0x00218085
Mach header
      magic cputype cpusubtype  caps    filetype ncmds sizeofcmds      flags
 0xfeedfacf 16777228          0  0x00           2    79       8672 0x00218085
  • 使用file查看Mach-O文件
# 該Mach-O文件類型是 executable  只有armv7指令集
?  HomeDesign3D China.app file HomeDesign3D\ China
HomeDesign3D China: Mach-O executable arm_v7

# 該Mach-O文件 類型是 executable;  有armv7, arm64指令集是一個通用二進制文件
?  DingTalk.app file DingTalk
DingTalk: Mach-O universal binary with 2 architectures: [arm_v7: Mach-O executable arm_v7] [arm64]
DingTalk (for architecture armv7):  Mach-O executable arm_v7
DingTalk (for architecture arm64):  Mach-O 64-bit executable arm64
  • 通用二進制文件

    • universal binary或者Fat binary

    • 含有多個不同架構的獨立二進制文件; 故體積較大

    • 執行時, 只會選擇一種架構的二進制文件

    image.png
  • 使用MachOView查看Mach-O文件

    • 以查看DingTalk為例
image.png
image.png
image.png
  • RAWRVA

    • RV: 虛擬地址

    • RAW: 文件偏移地址(物理地址)

    • RVA: 相對虛擬地址的偏移

Mach-O結構詳解

Mach Header(arm64)
  • Magic Number : 魔數, 表示支持設備的CPU位數

    • oxFEEDFACE : 表示32位二進制

    • oxFEEDFACF : 表示64位二進制

  • cputypecpusubtype: CPU類型和子類型

  • filetype : Mach-O文件類型

  • ncmdssizeofcmds: 用于加載器的 加載命令的條數和大小

  • flags : 動態鏈接器dyld的標志

image.png

LC_SEGMENT / LC_SEGMENT_64段的詳解

  • 常見段

    • __PAGEZERO: 空指針陷阱段

    • _TEXT: 程序代碼段

    • __DATA: 程序數據段

    • __RODATA: read only程序只讀數據段

    • __LINKEDIT: 鏈接器使用段

image.png
  • section段常見字段

    • Segment Name: 該Segment的名稱, 用于load_segment

    • VM Address: 該段的虛擬物理地址

    • VM Size: 該段所需要分配的虛擬內存大小(字節)

    • File Offset: 該段在文件中的偏移量

    • File Size: 該段在文件中占據的字節數

    • Maximum VM Protection: 段的頁面所需要的最高內存保護

      • ox1: x 執行

      • ox2: w 寫

      • 0x4: r 讀

    • Initial VM Protection: 段頁面初始化的內存保護

    • Number of Sections: 段中section區的數量

    • Flags: 其他標志位

tips: 小結:

根據LC_SEGMENT命令 設置進程虛擬內存

對于每一個段, 將其內容從Mach-O文件加載到內存中

即從Mach-O文件中的偏移量為 File Offset處加載File Size字節內容到虛擬內存地址VM AddressVM Size字節空間內

image.png

段中區section詳解

  • 常見區section

    • __text: 主程序代碼

    • __stubs, __stub_helper: 用于動態鏈接的樁

    • __cstring: 程序中c語言字符串

    • __const: 常量

    • __RODATA,__objc_methname: OC方法名稱

    • __RODATA,__objc_methntype: OC方法類型

    • __RODATA,__objc_classname: OC類名

    • __DATA,__objc_classlist: OC類列表

    • __DATA,__objc_protollist: OC原型列表

    • __DATA,__objc_imageinfo: OC鏡像信息

    • __DATA,__objc_const: OC常量

    • __DATA,__objc_selfrefs: OC類自引用(self)

    • __DATA,__objc_superrefs: OC類超類引用(super)

    • __DATA,__objc_protolrefs: OC原型引用

    • __DATA, __bss: 沒有初始化和初始化為0 的全局變量

image.png

Load Commmands加載命令中其他信息

  • LC_MAIN

    • 設置程序主線程入口地址棧大小
image.png
  • LC_CODE_SIGNATURE

    • 包含Mach-O文件的代碼簽名

    • 沒有簽名簽名不正確, 該進程會被kill, 程序崩潰

image.png

Mach-O中動態庫的加載

  • 動態庫來源

    • 系統提供的動態庫

    • 第三方動態庫

  • 如圖: DingTalk使用大量的系統動態庫

    • Mach-O鏡像中有很多對外部庫以及符號的引用

    • 這些引用將在程序啟動時, 由動態鏈接器 /usr/lib/dyld來執行符號綁定

image.png
  • 加載動態鏈接器

    • LC_LOAD_DYLINKER: 內核執行該命令時, 啟動dyld
image.png
  • 獲取符號表

    • LC_SYMTAB: 符號地址表

    • LC_DYSYMTAB: 動態符號地址表

  • 加載動態庫

    • LC_LOAD_WEAK_DYLIB

    • LC_LOAD_DYLIB

動態庫加載流程小結

1.0 首先啟動dyld動態鏈接器; 內核根據LC_LOAD_DYLINKER啟動/usr/lib/dyld

2.0 如果Mach-O文件中使用了外部定義的符號或函數, 則會在文本段__TEXT__stubs, __stub_helper區; 區內放著本地未被定義的符號; 編譯器在編譯源碼時會創建對這些未定義符號樁區的調用

3.0 dyld運行時, 會在符號樁區調用地址上; 添加JMP 到 真實函數地址的指令

4.0 至于dyld怎么找到指定的動態庫中指定的函數地址? 此時dyld將加載Load Command中的LC_LOAD_DYLIB命令

5.0 LC_LOAD_DYLIB(動態庫), dyld將加載每一個指定的庫且搜尋匹配的符號

6.0 當符號匹配時, 將在符號表(由dyld加載LC_SYMTAB, LC_DYSYMTAB獲取)查找對應的函數/符號地址

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,327評論 6 537
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,996評論 3 423
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,316評論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,406評論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,128評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,524評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,576評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,759評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,310評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,065評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,249評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,821評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,479評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,909評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,140評論 1 290
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,984評論 3 395
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,228評論 2 375

推薦閱讀更多精彩內容