Mach-O 其实是 Mach Object 文件格式的缩写,在 Mac 和 iOS 上,可执行文件的格式通常都是 Mach-O 格式,但是 Mach-O 格式的文件并非一定是可执行文件
属于Mach-O格式的常见文件:
Mach-O工具# 查看Mach-O的头
otool -h Mach-O文件
# 查看Mach-O的 load commands
| 部分 | 作用 |
|---|---|
Mach-O头部(Header) |
保存了 CPU 架构、大小端序、文件类型、加载命令数量等一些基本信息 |
加载命令(Load Commands) |
指定了文件的逻辑结构与文件在虚拟内存中的布局 |
数据块(Data) |
Load Commands 中定义的 Segment 的原始数据 |
/*
* The 64-bit mach header appears at the very beginning of object files for
* 64-bit architectures.
*/
struct mach_header_64 {
uint32_t magic; /* mach magic number identifier */
int32_t cputype; /* cpu specifier */
int32_t cpusubtype; /* machine specifier */
uint32_t filetype; /* type of file */
uint32_t ncmds; /* number of load commands */
uint32_t sizeofcmds; /* the size of all the load commands */
uint32_t flags; /* flags */
uint32_t reserved; /* reserved */
};
/* Constant for the magic field of the mach_header_64 (64-bit architectures) */
#define MH_MAGIC_64 0xfeedfacf /* the 64-bit mach magic number */
#define MH_CIGAM_64 0xcffaedfe /* NXSwapInt(MH_MAGIC_64) */
| 字段 | 作用 |
|---|---|
| magic | 魔数(特征字段),用于标识当前设备是大端序还是小端序。由于 iOS 是小端序,所以其被定义常量 MH_MAGIC_64,即固定取值为 0xfeedfacf |
| cputype | 标识 CPU 架构,类型为 cpu_type_t,其定义于 mach/machine.h |
| cpusubtype | 标具体的 CPU 架构,区分不同版本的处理器,类型为 cpusubtype,其定义于 mach/machine.h |
| filetype | Mach-O 文件类型(如:可执行文件、库文件等),可在 mach-o/loader.h 中找到具体定义和取值。 |
常见的有 MH_OBJECT(中间目标文件)、MH_EXECUTE(可执行文件)、MH_DYLIB(动态链接库)、MH_DYLINKER(动态链接器) |
|
| ncmds | Load Commands 的数量 |
| sizeofcmds | Load Commands 所占的总字节大小 |
| flags | 一些标识信息,可在 mach-o/loader.h 中找到具体定义和取值。 |
其中 #define MH_PIE 0x200000 值得注意,只会在文件类型为 MH_EXECUTE 时使用,表明开启 ASLR,用来增加程序安全性。 |
|
| reserved | 系统保留字段 |
加载命令(Load Commands)紧跟 Header之后,指定了文件的逻辑结构与文件在虚拟内存中的布局,明确地告诉加载器如何处理二进制数据。有些命令由内核处理,有些由动态链接器(dyld)处理。