以一個簡單的iOS項目缤灵,只有NSLog輸出語句伦籍,然后編譯(最好真機器)蓝晒,將編譯后的MachO文件使用MachOView打開,分析其中內(nèi)容:
從圖1可知MachO文件簡單來區(qū)分可以分為4部分
1帖鸦、Header 頭部
? ? ? ? 用于快速確認CPU信息芝薇、文件類型等信息
2、Load Commands 加載命令
? ? ? ? 告訴loader如何設(shè)置并加載二進制數(shù)據(jù)
3作儿、Segment段(分兩部分)
? ? 3.1洛二、Section Text 代碼段(由代碼編譯成的指令集)
? ? 3.2、Section Data 數(shù)據(jù)段(含堆立倍、棧灭红、全局和靜態(tài)變量)
? ? 存放:代碼、字符常量口注、類变擒、方法等
? ? 每個segment可以有0到多個section;每個段都有虛擬地址映射到進程的地址空間
4寝志、Loader Info 鏈接信息
? ? ? ? 完整的MacO文件末端是一系列鏈接信息娇斑。其中包含了動態(tài)鏈接器用來鏈接可執(zhí)行文件或者依賴所需的符號表、字符串表等
詳細說明
一材部、Header
從圖中可知毫缆,通過Header可以獲得CPU架構(gòu)信息、文件類型等信息
Magic Number:魔數(shù)用來確定是32位還是64位 (MH_MAGIC_64乐导,說明當(dāng)前是64位)
CPU Type:CPU類型 (本例中是arm64)
CPU Subtype:CPU子類型()
File Type:用來確定文件類型(MH_EXECUTE, 可執(zhí)行文件)
Number of Load Command:加載命令的數(shù)量苦丁,本例子中位23個加載命令(詳解2中可對應(yīng)下)
Size of Load Command:表示23個加載命令的總字節(jié)數(shù)為2888字節(jié)
Flags:表示二進制文件支持的功能,主要與系統(tǒng)的加載物臂、鏈接有關(guān)
二旺拉、Load Commands 加載命令(本例子中共23條加載命令)
告訴loader如何設(shè)置并加載二進制數(shù)據(jù)
命令詳解
1-5、LC_SEGMENT_64(xxx) 將該段映射到進程地址空間中
6棵磷、 LC_DYLD_INFO_ONLY 加載動態(tài)鏈接庫
7蛾狗、LC_SYMTAB 載入符號表地址
8、LC_DYSYMTAB 載入動態(tài)符號表地址
9仪媒、LC_LOAD_DYLINKER 加載動態(tài)加載庫
10沉桌、LC_UUID 確定文件的唯一標識(crash文件中也會有,用來檢查crash文件與dysm文件是否匹配)
11算吩、
12留凭、LC_SOURCE_VERSION?構(gòu)建該二進制文件使用的源代碼版本
13、LC_MAIN?設(shè)置程序主線程的入口地址和棧大小
14赌莺、LC_ENCRYPTION_INFO_64?獲取加密信息
15-19冰抢、LC_LOAD_DYLIB(xxx)?加載額外的動態(tài)庫
20、LC_RPATH?Dyld維護一個稱為運行路徑列表的路徑的當(dāng)前堆棧艘狭。當(dāng)遇到@rpath時挎扰,它會被替換為運行路徑列表中的每個路徑翠订,直到找到可加載的dylib
21、LC_FUNCTION_STARTS?定義一個函數(shù)起始地址表,使調(diào)試器和其他程序易于看到一個地址是否在函數(shù)內(nèi)
22遵倦、LC_DATA_IN_CODE?定義在代碼段內(nèi)的非指令的表
23尽超、LC_CODE_SIGNATURE?獲取應(yīng)用簽名信息
說明:一、二兩部分讓kernel知道如何讀取MachO文件梧躺,并制定MachO文件的動態(tài)鏈接器用來完成后續(xù)的動態(tài)庫加載似谁,然后設(shè)置好程序的入口信息;后面的部分就相當(dāng)于run起來之后掠哥,為每一個映射到虛擬內(nèi)存中的指令操作提供真實的物理地址支持
三巩踏、Section Text代碼段
從text段可以看到具體的類名、方法名等信息
圖中紅色部分续搀,代表非懶加載符號表與懶加載符號表塞琼,這兩個指針表,保存著與字符串標對應(yīng)的函數(shù)指針
四:Loader Info 鏈接信息
一共分四個區(qū):
1禁舷、Rebase Info: ?pointer rebase的信息
2彪杉、Binding Info:non-lazy symbol pointer綁定需要的信息
3、Lazy Binding Info:lazy symbol pointer綁定需要的信息
4牵咙、Export Info:暴露給外部的符號的信息
該部分在hook代碼中非常有用派近,根據(jù)mach-o的符號動態(tài)鏈接原理,讓non-lazy/lazy symbol 指針重新指向?qū)?yīng)的symbol stub代碼位置洁桌,起到在runtime的hook