ipa包主要由三大部分構(gòu)成:
1、可執(zhí)行文件;2、Asset.car 文件(asset 文件夾中圖片的壓縮文件);3、其他:_CodeSignature文件夾,簽名信息。

- 使用 file 命令查看這個(gè)可執(zhí)行文件:這是個(gè) Mach-O 文件類型,里面包含了兩個(gè)架構(gòu):armv7&arm64。
file DingTalk - 使用otool查看Mach-O文件:
otool -h DingTalk。使用反匯編工具對(duì)執(zhí)行文件進(jìn)行反匯編可以對(duì)Mach-O文件有一個(gè)直觀的認(rèn)識(shí)。
Mach-O:
Mach-O為Mach Object 文件格式的縮寫(xiě),它是一種用于可執(zhí)行文件,目標(biāo)代碼,動(dòng)態(tài)庫(kù),內(nèi)核轉(zhuǎn)儲(chǔ)的文件格式。
是iOS/Mac OS上存儲(chǔ)程序以及庫(kù)的標(biāo)準(zhǔn)格式。
- 常見(jiàn)的Mach-O格式的文件
- MH_OBJECT 目標(biāo)文件:
.o.a/.framework靜態(tài)庫(kù),靜態(tài)庫(kù)即多個(gè).o文件存放在一起實(shí)現(xiàn)特定的功能。 - MH_EXECUTE 可執(zhí)行文件:
.app/MyApp.out - MH_DYLIB 動(dòng)態(tài)庫(kù):
.framework/xxx/dylib - MH_DYLINKER 動(dòng)態(tài)鏈接器:
usr/lib/dyld - MH_DSYM 存儲(chǔ)二進(jìn)制文件符號(hào)信息的文件:
.dYSM/Contents/Resources/DWARF/MyApp
- MH_OBJECT 目標(biāo)文件:
- Mach-O文件的基本結(jié)構(gòu)
- 頭部(header structure):文件類型, 目標(biāo)架構(gòu)。
- 加載命令(load command):描述文件在虛擬內(nèi)存中的邏輯與布局。
- 段(segment)??梢該碛卸鄠€(gè)段(segment),每個(gè)段可以擁有零個(gè)或多個(gè)區(qū)域(section)。每一個(gè)段(segment)都擁有一段虛擬地址映射到進(jìn)程的地址空間。加載命令中定義的原始數(shù)據(jù)。
- 鏈接信息。一個(gè)完整的用戶級(jí) Mach-o 文件的末端是鏈接信息。其中包含了動(dòng)態(tài)加載器用來(lái)鏈接可執(zhí)行文件或者依賴庫(kù)所需使用的符號(hào)表、字符串表等等。
- 分析Mach-O結(jié)構(gòu)
Mach Header(arm64)
Magic Number : 魔數(shù), 表示支持設(shè)備的CPU位數(shù)(oxFEEDFACE : 表示32位二進(jìn)制、oxFEEDFACF : 表示64位二進(jìn)制)
cputype和 cpusubtype: CPU類型和子類型
filetype : Mach-O文件類型
ncmds 和 sizeofcmds: 用于加載器的 加載命令的條數(shù)和大小
flags : 動(dòng)態(tài)鏈接器dyld的標(biāo)志
基本的編譯過(guò)程分為四個(gè)步驟:
- 預(yù)處理(Pre-process):把宏替換,刪除注釋,展開(kāi)頭文件,產(chǎn)生 .i 文件。
- 編譯(Compliling):使用預(yù)處理后的單詞構(gòu)建詞法樹(shù),生成語(yǔ)法樹(shù)輸出 AST(Abstract Syntax Tree),將 AST 轉(zhuǎn)化為更低級(jí)的中間碼(LLVM IR),優(yōu)化中間代碼生成輸出匯編代碼,把之前的 .i 文件轉(zhuǎn)換為匯編語(yǔ)言,產(chǎn)生 .s 文件。
- 匯編(Asembly):把匯編語(yǔ)言文件轉(zhuǎn)換為機(jī)器碼文件,產(chǎn)生 .o 文件。
- 鏈接(Link):對(duì) .o 文件中的對(duì)于其他的庫(kù)的引用的地方進(jìn)行引用,生成最后的可執(zhí)行文件(同時(shí)也包括多個(gè).o文件進(jìn)行 link)。
LinkMap
LinkMap中存放的是app可執(zhí)行文件Mach-O格式組織的各類數(shù)據(jù)的清單,根據(jù)LinkMap展開(kāi)對(duì)Mach-O文件及dyld加載Mach-O可執(zhí)行文件的細(xì)節(jié);
LinkMap文件是xcode link時(shí)產(chǎn)生的中間文件,一般用于調(diào)試,可以精確知道某個(gè)地址對(duì)應(yīng)的函數(shù)。
iOS APP編譯后,除了一些資源文件,剩下的就是一個(gè)可執(zhí)行文件。
1.XCode開(kāi)啟編譯選項(xiàng)Write Link Map File
2.編譯后,到編譯目錄里找到該txt文件,文件名和路徑就是上述的Path to Link Map File
這個(gè)LinkMap里展示了整個(gè)可執(zhí)行文件的全貌,列出了編譯后的每一個(gè).o目標(biāo)文件的信息(包括靜態(tài)鏈接庫(kù).a里的),以及每一個(gè)目標(biāo)文件的代碼段,數(shù)據(jù)段存儲(chǔ)詳情。
1
目標(biāo)文件列表,中括號(hào)里的是這個(gè)文件的編號(hào)。
2
段表:首列是數(shù)據(jù)在文件的偏移位置,第二列是這一段占用大小,第三列是段類型,代碼段和數(shù)據(jù)段,第四列是段名稱。第一行位置+大小 = 第二行位置。
__text表示編譯后的程序執(zhí)行語(yǔ)句
__data表示已初始化的全局變量和局部靜態(tài)變量
__bss表示未初始化的全局變量和局部靜態(tài)變量
__cstring表示代碼里的字符串常量
以下是__TEXT段的section
__text 主程序代碼
__stubs 和__stub_helper 用于動(dòng)態(tài)鏈接庫(kù)的stub
__cstring c語(yǔ)言字符串
__const const修飾的常量
__objc_methname objc的方法名稱
__objc_methtype objc方法類型
__objc_classname objc類方法
以下是__DATA段的section
__objc_ivars objc類的實(shí)例變量
__objc_classlist objc類列表
__objc_protolist objc協(xié)議列表
__objc_imageinfo objc鏡像信息
__objc_const objc常量
__objc_selfrefs objc自引用(self)
__objc_protorefs objc協(xié)議引用
__objc_superrefs objc超類引用
__cfstring 使用Core Foundation字符串
__bss BSS
3
接著就是按上表順序,列出具體的按每個(gè)文件列出每個(gè)對(duì)應(yīng)字段的位置和占用空間。
首列是數(shù)據(jù)在文件的偏移地址,第二列是占用大小,第三列是所屬文件序號(hào),對(duì)應(yīng)上述Object files列表,最后是名字。
4
// 已廢棄&多余重復(fù)的字段
# Dead Stripped Symbols:
自動(dòng)分析LinkMapParser