##### 1.通用二进制文件
所谓的通用二进制文件,实质上是支持的各种架构的二进制文件打包在一起的文件,通常也称为胖二进制文件。
其共享一个header,系统会根据cputype和subtype匹配合适的二进制文件,可以通过lipo来提取、删除中指定架构部分的二进制代码。由于其与单个架构的Mach-O文件并无本质区别,本文不对此进行深入讨论。
##### 2. 64位架构下的Mach-O
##### 3. Header
bin目录下是可以直接运行的二进制文件,此处以date为例,使用MachOView打开 /bin/date,其结构如下
![Mach-O分段数据](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,其作用是确保二进制文件且可在当前架构下运行。继续往下是filetype,也就是Mach-O的文件类型,根据apple官方文件的定义,共有以下几种
继续往下,来到Number of Load Commands,和 Size of Load Commands,其提供了加载器加载命令所需的条数和大小,后面的flags则是动态连接器(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)
其第一个参数是Command,为Load Commands的类型,其值为LC_SEGMENT_64,该参数的作用是用于将文件中的段映射到进程的地址空间中。
##### 5.LC_SEGMENT_64/LC_SEGMENT
这是最常见的一种LoadCommand,其作用是指导内核如何设置新运行的进程的内存空间,在载入的时候,这些段会从Mach-O文件中载入到内存中。每条LC_SEGMENT_64都提供了段布局所需要的必要信息:
VM Address是描述段的虚拟内存地址,
VM Size是段分配的虚拟内存大小;
File Offset表示段在内存中的偏移量;
File Size表示段在文件中所占的大小;
Max VM Protection为段的页面所需要的最高内存保护,其表示方法是八进制(r=4,w=2,x=1);
Initial Max VM Protection为段的页面最初的内存保护;
Number of Sections表示段中的Section的数量
flags 用于杂项
设想一下,有了LC_SEGMENT_64之后,程序载入内存时,对于每个段,只需要按照偏移量,从File Offset处加载File Size大小的内容到虚拟内存的VM Address处,其大小为VM Size。根据Initial Max VM Protection设置了段的保护级别,后面可以动态改变,前提是不大于Max VM Protection。
先来看第一个_PAGEZERO,其提供了空指针陷阱机制。
_TEXT段是用于存放程序代码的,
_DATA段是用于存放程序数据
_LINKEDIT存放了连接器使用的符号表和其他表