Mach-O !les start with a Mach-O header, which identi!es the !le as a Mach-O and speci!es the target CPU architecture and type of Mach-O binary

The header also contains the number and size of the load commands.

A Mach-O header is a structure of type mach_header_64, or for 32-bit binaries, mach_header, de!ned in Apple’s developer SDK !le, mach-o/loader.h

struct mach_header_64 { 
	uint32_t magic; /* mach magic number identifier */ 
	cpu_type_t cputype; /* cpu specifier */ 
	cpu_subtype_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 */ 
};

The cputype member of the structure speci!es the CPU architecture that is compatible with Mach-O binary. You’ll likely encounter constants such as I386, X86_64, or ARM64.

The filetype member describes the type of Mach-O binary. It can have several possible values, including MH_EXECUTE (0x2), which identi!es a standard Mach-O executable; MH_DYLIB (0x6), which identi!es a Mach-O dynamic linked library; and MH_BUNDLE (0x8), which identi!es a Mach-O bundle.

As the vast majority of malicious Mach-O binaries are standalone executables, their type will be the former: MH_EXECUTE.

Next in the mach_header_64 structure are members that describe both the number and size of load command

The otool utility can be used to parse Mach-O binaries.

Universal binaries start with a header (fat_header), a variable number of fat_arch structures that describe the supported architectures, and then the architecture-speci!c Mach-O binaries concatenated together. You can dump the fat_header by using the otool utility with the -f ag