##### 1.通用二進制文件
所謂的通用二進制文件遭笋,實質(zhì)上是支持的各種架構(gòu)的二進制文件打包在一起的文件坝冕,通常也稱為胖二進制文件徒探。
其共享一個header瓦呼,系統(tǒng)會根據(jù)cputype和subtype匹配合適的二進制文件,可以通過lipo來提取测暗、刪除中指定架構(gòu)部分的二進制代碼央串。由于其與單個架構(gòu)的Mach-O文件并無本質(zhì)區(qū)別,本文不對此進行深入討論碗啄。
##### 2. 64位架構(gòu)下的Mach-O
##### 3. Header
bin目錄下是可以直接運行的二進制文件质和,此處以date為例,使用MachOView打開 /bin/date稚字,其結(jié)構(gòu)如下
![Mach-O分段數(shù)據(jù)](https://upload-images.jianshu.io/upload_images/1712059-b35992843eb42874.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
首先看Header部分
![Mach-O Header](https://upload-images.jianshu.io/upload_images/1712059-1c3936cad543e04c.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
文件頭一開始是一個Magic Number饲宿,在32位下值是0xFEEDFACE,64位下是0xFEEDFACF胆描,再往下是CPU Type 和 CPU SubType瘫想,其作用是確保二進制文件且可在當前架構(gòu)下運行。繼續(xù)往下是filetype昌讲,也就是Mach-O的文件類型国夜,根據(jù)apple官方文件的定義,共有以下幾種
繼續(xù)往下短绸,來到Number of Load Commands车吹,和 Size of Load Commands,其提供了加載器加載命令所需的條數(shù)和大小醋闭,后面的flags則是動態(tài)連接器(dyld)的標志窄驹,最后的保留位是64位獨有,供未來使用证逻。
##### 3. Load Commands(加載命令)
Header之后緊接著的是Load Command乐埠,如下
![Load Commands分段](https://upload-images.jianshu.io/upload_images/1712059-906bf65309c658fd.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
以_TEXT為例
![_TEXT](https://upload-images.jianshu.io/upload_images/1712059-aa6d7c42f11652aa.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
![image.png](https://upload-images.jianshu.io/upload_images/1712059-a4d37d1e0d1c23c9.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
其第一個參數(shù)是Command,為Load Commands的類型瑟曲,其值為LC_SEGMENT_64饮戳,該參數(shù)的作用是用于將文件中的段映射到進程的地址空間中。
##### 5.LC_SEGMENT_64/LC_SEGMENT
這是最常見的一種LoadCommand洞拨,其作用是指導內(nèi)核如何設(shè)置新運行的進程的內(nèi)存空間扯罐,在載入的時候,這些段會從Mach-O文件中載入到內(nèi)存中烦衣。每條LC_SEGMENT_64都提供了段布局所需要的必要信息:
VM Address是描述段的虛擬內(nèi)存地址歹河,
VM Size是段分配的虛擬內(nèi)存大醒谡恪;
File Offset表示段在內(nèi)存中的偏移量秸歧;
File Size表示段在文件中所占的大谐Α;
Max VM Protection為段的頁面所需要的最高內(nèi)存保護键菱,其表示方法是八進制(r=4,w=2,x=1)谬墙;
Initial Max VM Protection為段的頁面最初的內(nèi)存保護;
Number of Sections表示段中的Section的數(shù)量
flags 用于雜項
設(shè)想一下经备,有了LC_SEGMENT_64之后拭抬,程序載入內(nèi)存時,對于每個段侵蒙,只需要按照偏移量造虎,從File Offset處加載File Size大小的內(nèi)容到虛擬內(nèi)存的VM Address處,其大小為VM Size纷闺。根據(jù)Initial Max VM Protection設(shè)置了段的保護級別算凿,后面可以動態(tài)改變,前提是不大于Max VM Protection犁功。
先來看第一個_PAGEZERO氓轰,其提供了空指針陷阱機制。
_TEXT段是用于存放程序代碼的波桩,
_DATA段是用于存放程序數(shù)據(jù)
_LINKEDIT存放了連接器使用的符號表和其他表