Mach-O 其实是 Mach Object 文件格式的缩写,在 Mac 和 iOS 上,可执行文件的格式通常都是 Mach-O 格式,但是 Mach-O 格式的文件并非一定是可执行文件

属于Mach-O格式的常见文件:

分析Mach-O工具

otool

# 查看Mach-O的头
otool -h Mach-O文件
# 查看Mach-O的 load commands

MachOView

Mach-O结构

Notion 2025-09-22 13.25.13.tiff

部分 作用
Mach-O头部(Header 保存了 CPU 架构、大小端序、文件类型、加载命令数量等一些基本信息
加载命令(Load Commands 指定了文件的逻辑结构与文件在虚拟内存中的布局
数据块(Data Load Commands 中定义的 Segment 的原始数据

Header

/*
 * 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

加载命令(Load Commands)紧跟 Header之后,指定了文件的逻辑结构与文件在虚拟内存中的布局,明确地告诉加载器如何处理二进制数据。有些命令由内核处理,有些由动态链接器(dyld)处理。