Mach-O


Introduction

Note

The Mach-O format defines the notion of FAT binaries which can embed different architectures into a single file. always returns a with the assumption that a non-fat Mach-O can be represented as a with one architecture.
import lief

# Using filepath
macho: lief.MachO.FatBinary = lief.MachO.parse("/bin/ls")

# Using a Path from pathlib
macho: lief.MachO.FatBinary = lief.MachO.parse(pathlib.Path(r"C:\Users\test.macho"))

# Using a io object
with open("/bin/ssh", 'rb') as f:
  macho: lief.MachO.FatBinary = lief.MachO.parse(f)
fat: lief.MachO.FatBinary

# Iterate
for macho in fat:
    print(macho.entrypoint)
    print(len(macho.commands))

# Pick one at the specified index
macho: lief.MachO.Binary = fat.at(0)

# Pick one based on the architecture
macho: lief.MachO.Binary = fat.take(lief.MachO.Header.CPU_TYPE.ARM64)
macho: lief.MachO.FatBinary = ...

macho.at(0).write("fit.macho")
macho.write("fat.macho") # write-back the whole FAT binary

Advance Parsing/Writing

parser_config = lief.MachO.ParserConfig()
parser_config.parse_dyld_bindings = False

macho: lief.MachO.FatBinary = lief.MachO.parse("my.macho", parser_config)

builder_config = lief.MachO.Builder.config_t()
builder_config.linkedit = False

macho.write("new.macho", builder_config)

Objective-C Support

If a Mach-O binary is compiled from Objetive-C sources, it could contain metadata which are represented by the object.
This metadata can help understand the underlying structures of the binary and LIEF extended provides the support for accessing this information through: .

For more details, you can check the Obj-C section.