Documentation
¶
Overview ¶
Package macho provides a parser for untrusted Mach object (Mach-O) files.
See https://en.wikipedia.org/wiki/Mach-O and https://github.com/apple/darwin-xnu/blob/main/EXTERNAL_HEADERS/mach-o/loader.h for documentation on the format.
Index ¶
- Constants
- func IsSingleArchitecture(head []byte) bool
- func IsUniversal(head []byte) bool
- type Alignment
- type CPUType
- type CodeDirectory
- type CodeSignatureBlob
- type CodeSignatureFlags
- type CodeSignatureMagic
- type CommandReader
- type FileHeader
- type HashType
- type LinkeditDataCommand
- type LoadCmd
- type Section
- type SegmentCommand
- type SuperBlob
- type SuperBlobEntry
- type SuperBlobSlot
- type Type
- type UUIDCommand
- type UniversalFileEntry
- type VirtualMemoryProtection
Constants ¶
const CodeSignatureBlobMinSize = 8
CodeSignatureBlobMinSize is the minimum size in bytes of a serialized CodeSignatureBlob.
const LoadCommandMinSize = 8
LoadCommandMinSize is the minimum size (in bytes) of a Mach-O load command.
const MagicNumberSize = 4
MagicNumberSize is the size (in bytes) of the magic number at the start of the Mach-O file.
Variables ¶
This section is empty.
Functions ¶
func IsSingleArchitecture ¶
IsSingleArchitecture reports whether head starts with the Mach-O magic number for a single-architecture Mach-O file. IsSingleArchitecture will always report false if len(head) < MagicNumberSize.
func IsUniversal ¶
IsUniversal reports whether head starts with the Mach-O magic number for a multi-architecture Mach-O file. IsUniversal will always report false if len(head) < MagicNumberSize.
Types ¶
type Alignment ¶
type Alignment uint32
Alignment is an alignment value. Its raw value is the exponent of two.
type CPUType ¶
type CPUType uint32
CPUType is an enumeration of instruction set architectures.
const ( CPUTypeVAX CPUType = 0x00000001 // CPU_TYPE_VAX CPUTypeMC680x0 CPUType = 0x00000006 // CPU_TYPE_MC680x0 CPUTypeI386 CPUType = 0x00000007 // CPU_TYPE_X86 CPUTypeX86_64 CPUType = 0x01000007 // CPU_TYPE_X86_64 CPUTypeMC98000 CPUType = 0x0000000a // CPU_TYPE_MC98000 CPUTypeHPPA CPUType = 0x0000000b // CPU_TYPE_HPPA CPUTypeARM CPUType = 0x0000000c // CPU_TYPE_ARM CPUTypeARM64 CPUType = 0x0100000c // CPU_TYPE_ARM64 CPUTypeARM64_32 CPUType = 0x0200000c // CPU_TYPE_ARM64_32 CPUTypeMC88000 CPUType = 0x0000000d // CPU_TYPE_MC88000 CPUTypeSPARC CPUType = 0x0000000e // CPU_TYPE_SPARC CPUTypeI860 CPUType = 0x0000000f // CPU_TYPE_I860 CPUTypePowerPC CPUType = 0x00000012 // CPU_TYPE_POWERPC CPUTypePowerPC64 CPUType = 0x01000012 // CPU_TYPE_POWERPC64 )
CPUType values defined by Mach-O file format.
type CodeDirectory ¶
type CodeDirectory struct {
Flags CodeSignatureFlags
HashData []byte
Identifier string
SpecialSlotCount uint32
CodeLimit uint64
HashType HashType
Platform uint8
PageSize Alignment
TeamIdentifier string
ExecutableSegmentBase uint64
ExecutableSegmentLimit uint64
ExecutableSegmentFlags uint64
}
CodeDirectory represents a parsed CodeSignatureBlob for the CodeSignatureMagicCodeDirectory magic number.
func (*CodeDirectory) HashSlotCount ¶
func (cd *CodeDirectory) HashSlotCount() int
HashSlotCount returns the number of hash slots present in cd.HashData based on cd.HashType.
func (*CodeDirectory) HashSlots ¶
func (cd *CodeDirectory) HashSlots() iter.Seq2[int, []byte]
HashSlots returns an iterator over the hash slots (including the special ones).
func (*CodeDirectory) UnmarshalBinary ¶
func (cd *CodeDirectory) UnmarshalBinary(data []byte) error
UnmarshalBinary parses a Mach-O code signature blob as a CodeDirectory.
type CodeSignatureBlob ¶
type CodeSignatureBlob struct {
Magic CodeSignatureMagic
Data []byte
}
A CodeSignatureBlob represents a single record in a Mach-O code signature.
func (CodeSignatureBlob) AppendBinary ¶
func (blob CodeSignatureBlob) AppendBinary(dst []byte) ([]byte, error)
AppendBinary marshals blob as a Mach-O code signature blob and appends the result to dst.
func (CodeSignatureBlob) MarshalBinary ¶
func (blob CodeSignatureBlob) MarshalBinary() ([]byte, error)
MarshalBinary marshals blob as a Mach-O code signature blob.
func (*CodeSignatureBlob) UnmarshalBinary ¶
func (blob *CodeSignatureBlob) UnmarshalBinary(data []byte) error
UnmarshalBinary unmarshals the Mach-O code signature blob into blob.
type CodeSignatureFlags ¶
type CodeSignatureFlags uint32
CodeSignatureFlags is a bitset of flags used in CodeDirectory.
const ( // CodeSignatureAdHoc indicates that the bundle is ad hoc signed. CodeSignatureAdHoc CodeSignatureFlags = 0x00000002 // CS_ADHOC // CodeSignatureHard requests to not load invalid pages. CodeSignatureHard CodeSignatureFlags = 0x00000100 // CS_HARD // CodeSignatureKill requests to kill the process if it becomes invalid. CodeSignatureKill CodeSignatureFlags = 0x00000200 // CS_KILL // CodeSignatureCheckExpiration forces expiration checking. CodeSignatureCheckExpiration CodeSignatureFlags = 0x00000400 // CS_CHECK_EXPIRATION // CodeSignatureRestrict tells dyld to treat the bundle as restricted. CodeSignatureRestrict CodeSignatureFlags = 0x00000800 // CS_RESTRICT // CodeSignatureEnforcement indicates that the bundle requires enforcement. CodeSignatureEnforcement CodeSignatureFlags = 0x00001000 // CS_ENFORCEMENT // CodeSignatureRequireLV indicates that the bundle requires library validation CodeSignatureRequireLV CodeSignatureFlags = 0x00002000 // CS_REQUIRE_LV // CodeSignatureRuntime requests to apply hardened runtime policies. CodeSignatureRuntime CodeSignatureFlags = 0x00010000 // CS_RUNTIME // CodeSignatureLinkerSigned indicates the bundle was automatically signed by the linker. CodeSignatureLinkerSigned CodeSignatureFlags = 0x00020000 // CS_LINKER_SIGNED )
CodeSignatureFlags permitted to be used in the Mach-O format.
type CodeSignatureMagic ¶
type CodeSignatureMagic uint32
CodeSignatureMagic is an enumeration of types of CodeSignatureBlob.
const ( CodeSignatureMagicRequirement CodeSignatureMagic = 0xfade0c00 CodeSignatureMagicRequirements CodeSignatureMagic = 0xfade0c01 CodeSignatureMagicCodeDirectory CodeSignatureMagic = 0xfade0c02 CodeSignatureMagicEmbeddedSignature CodeSignatureMagic = 0xfade0cc0 CodeSignatureMagicEmbeddedEntitlements CodeSignatureMagic = 0xfade7171 CodeSignatureMagicDetachedSignature CodeSignatureMagic = 0xfade0cc1 CodeSignatureMagicBlobWrapper CodeSignatureMagic = 0xfade0b01 )
Known CodeSignatureMagic values.
func (CodeSignatureMagic) String ¶
func (i CodeSignatureMagic) String() string
type CommandReader ¶
type CommandReader struct {
// contains filtered or unexported fields
}
A CommandReader reads Mach-O load commands from a stream. CommandReaders do not buffer their reads and will not read past the load command region defined by the FileHeader.
func (*CommandReader) Command ¶
func (r *CommandReader) Command() (_ LoadCmd, ok bool)
Command returns the type of the current command if it has been read. ok will be true if and only if at least 4 bytes of the current command have been read.
func (*CommandReader) Err ¶
func (r *CommandReader) Err() error
Err returns the first non-io.EOF error encountered by r.
func (*CommandReader) Next ¶
func (r *CommandReader) Next() bool
Next advances r to the next load command, which will then be available through *CommandReader.Read. It returns false when there are no more load commands, either by reaching the end of the input or an error. If the previous load command was not fully read, Next will discard the unread bytes. After Next returns false, the *CommandReader.Err method will return any error that occurred during scanning, except that if it was io.EOF, *CommandReader.Err will return nil.
func (*CommandReader) Read ¶
func (r *CommandReader) Read(p []byte) (n int, err error)
Read reads up to the next len(p) bytes of the current load command into p. It returns the number of bytes read (0 <= n <= len(p)) and any error encountered. The first LoadCommandMinSize bytes of a load command are always the its type and size. After reading the first LoadCommandMinSize bytes, use *CommandReader.Command and *CommandReader.Size to parse these values.
Read does not introduce any buffering: each call to Read corresponds to at most one call to r's underlying io.Reader.
func (*CommandReader) Size ¶
func (r *CommandReader) Size() (_ uint32, ok bool)
Size returns the total size of the current command in bytes. ok is false if the first LoadCommandMinSize bytes of the command haven't been read yet or the size is invalid. Size will never return a value less than LoadCommandMinSize.
type FileHeader ¶
type FileHeader struct {
ByteOrder binary.ByteOrder
AddressWidth int
CPUType CPUType
CPUSubtype uint32
Type Type
LoadCommandCount uint32
LoadCommandRegionSize uint32
}
FileHeader represents a Mach-O single-architecture file header.
func ReadFileHeader ¶
func ReadFileHeader(r io.Reader) (*FileHeader, error)
ReadFileHeader reads the header of a Mach-O single architecture file. After a successful call to ReadFileHeader, calling *FileHeader.NewCommandReader on the reader allows iteration over the load commands in the file.
func (*FileHeader) DataOffset ¶
func (hdr *FileHeader) DataOffset() int64
DataOffset returns the offset in bytes from the beginning of the Mach-O file where the data region begins.
func (*FileHeader) LoadCommandsOffset ¶
func (hdr *FileHeader) LoadCommandsOffset() int64
LoadCommandsOffset returns the offset in bytes from the beginning of the Mach-O file where the load commands region begins.
func (*FileHeader) NewCommandReader ¶
func (hdr *FileHeader) NewCommandReader(r io.Reader) *CommandReader
NewCommandReader returns a CommandReader that reads from r. r should read from the part of the Mach-O file directly after the header, as in the state of a reader after calling ReadFileHeader.
type HashType ¶
type HashType uint8
HashType is an enumeration of cryptographic hash algorithms used in CodeDirectory.
const ( HashTypeSHA1 HashType = 1 // CS_HASHTYPE_SHA1 HashTypeSHA256 HashType = 2 // CS_HASHTYPE_SHA256 HashTypeSHA256Truncated HashType = 3 // CS_HASHTYPE_SHA256_TRUNCATED HashTypeSHA384 HashType = 4 // CS_HASHTYPE_SHA384 )
Known HashType values.
type LinkeditDataCommand ¶
type LinkeditDataCommand struct {
Command LoadCmd
// DataOffset is the offset in bytes of the data's start
// relative to the start of the __LINKEDIT segment.
DataOffset uint32
// DataSize is the size in bytes of data in the __LINKEDIT segment.
DataSize uint32
}
LinkeditDataCommand is the structure for LoadCmdCodeSignature, LoadCmdFunctionStarts, and LoadCmdDataInCode.
func (*LinkeditDataCommand) UnmarshalMachO ¶
func (cmd *LinkeditDataCommand) UnmarshalMachO(byteOrder binary.ByteOrder, data []byte) error
UnmarshalMachO unmarshals the load command in data into cmd.
type LoadCmd ¶
type LoadCmd uint32
LoadCmd is an enumeration of load command types.
const ( LoadCmdSegment LoadCmd = 0x1 // LC_SEGMENT LoadCmdSymtab LoadCmd = 0x2 // LC_SYMTAB LoadCmdThread LoadCmd = 0x4 // LC_THREAD LoadCmdUnixThread LoadCmd = 0x5 // LC_UNIXTHREAD LoadCmdDysymtab LoadCmd = 0xb // LC_DYSYMTAB LoadCmdLoadDylib LoadCmd = 0xc // LC_LOAD_DYLIB LoadCmdLoadDylinker LoadCmd = 0xe // LC_LOAD_DYLINKER LoadCmdIDDylinker LoadCmd = 0xf // LC_ID_DYLINKER LoadCmdSegment64 LoadCmd = 0x19 // LC_SEGMENT_64 LoadCmdUUID LoadCmd = 0x1b // LC_UUID LoadCmdRPath LoadCmd = 0x8000001c // LC_RPATH LoadCmdCodeSignature LoadCmd = 0x1d // LC_CODE_SIGNATURE LoadCmdSourceVersion LoadCmd = 0x2a // LC_SOURCE_VERSION LoadCmdDyldInfo LoadCmd = 0x22 // LC_DYLD_INFO LoadCmdDyldInfoOnly LoadCmd = 0x80000022 // LC_DYLD_INFO_ONLY LoadCmdFunctionStarts LoadCmd = 0x26 // LC_FUNCTION_STARTS LoadCmdDataInCode LoadCmd = 0x29 // LC_DATA_IN_CODE LoadCmdMain LoadCmd = 0x80000028 // LC_MAIN LoadCmdBuildVersion LoadCmd = 0x32 // LC_BUILD_VERSION )
type Section ¶
type Section struct {
RawName [16]byte
RawSegmentName [16]byte
// Address is the memory address of this section.
Address uint64
// Size is the size in bytes of this section.
Size uint64
// Offset is the file offset of this section.
Offset uint32
// Alignment is the section's alignment.
Alignment Alignment
// RelocationOffset is the file offset of relocation entries.
RelocationOffset uint32
// RelocationCount is the number of relocation entries.
RelocationCount uint32
// Flags holds the section type and attributes.
Flags uint32
}
Section represents an instruction within a SegmentCommand to load a contiguous chunk of the file into virtual memory.
func (*Section) SegmentName ¶
SegmentName returns the name of the segment that contains the section as a string.
type SegmentCommand ¶
type SegmentCommand struct {
Command LoadCmd
RawName [16]byte
VirtualMemoryAddress uint64
VirtualMemorySize uint64
FileOffset uint64
FileSize uint64
MaxProtection VirtualMemoryProtection
InitProtection VirtualMemoryProtection
Flags uint32
Sections []Section
}
SegmentCommand is the structure for LoadCmdSegment and LoadCmdSegment64.
func (*SegmentCommand) Name ¶
func (cmd *SegmentCommand) Name() string
Name returns the segment's name as a string.
func (*SegmentCommand) UnmarshalMachO ¶
func (cmd *SegmentCommand) UnmarshalMachO(byteOrder binary.ByteOrder, data []byte) error
UnmarshalMachO unmarshals the load command in data into cmd.
type SuperBlob ¶
type SuperBlob struct {
Magic CodeSignatureMagic
Blobs []SuperBlobEntry
}
SuperBlob is a container of CodeSignatureBlob.
type SuperBlobEntry ¶
type SuperBlobEntry struct {
Type SuperBlobSlot
Blob CodeSignatureBlob
}
SuperBlobEntry is a CodeSignatureBlob with a "slot" (its intended usage).
type SuperBlobSlot ¶
type SuperBlobSlot uint32
SuperBlobSlot is an enumeration of types used in SuperBlobEntry.
const ( SuperBlobCodeDirectorySlot SuperBlobSlot = 0 // CSSLOT_CODEDIRECTORY SuperBlobInfoSlot SuperBlobSlot = 1 // CSSLOT_INFOSLOT SuperBlobRequirementsSlot SuperBlobSlot = 2 // CSSLOT_REQUIREMENTS SuperBlobResourceDirSlot SuperBlobSlot = 3 // CSSLOT_RESOURCEDIR SuperBlobApplicationSlot SuperBlobSlot = 4 // CSSLOT_APPLICATION SuperBlobEntitlementsSlot SuperBlobSlot = 5 // CSSLOT_ENTITLEMENTS )
Known SuperBlobSlot values.
func (SuperBlobSlot) String ¶
func (i SuperBlobSlot) String() string
type UUIDCommand ¶
UUIDCommand is the structure for LoadCmdUUID.
func (*UUIDCommand) UnmarshalMachO ¶
func (cmd *UUIDCommand) UnmarshalMachO(byteOrder binary.ByteOrder, data []byte) error
UnmarshalMachO unmarshals the UUID command in data into cmd.
type UniversalFileEntry ¶
type UniversalFileEntry struct {
CPU CPUType
CPUSubtype uint32
// Offset is the offset in bytes from the beginning of the Mach-O file
// that this image starts at.
Offset uint32
// Size is the size of the image in bytes.
Size uint32
Alignment Alignment
}
UniversalFileEntry is a single record from a Mach-O multi-architecture file.
func ReadUniversalHeader ¶
func ReadUniversalHeader(r io.Reader) ([]UniversalFileEntry, error)
ReadUniversalHeader reads a Mach-O multi-architecture header and all of its entries.
func (*UniversalFileEntry) UnmarshalBinary ¶
func (ent *UniversalFileEntry) UnmarshalBinary(data []byte) error
UnmarshalBinary unmarshals a universal file entry in Mach-O format.
type VirtualMemoryProtection ¶
type VirtualMemoryProtection uint32
VirtualMemoryProtection is a set of bitflags used to indicate permissions on a SegmentCommand.
const ( VirtualMemoryReadPermission VirtualMemoryProtection = 0x1 VirtualMemoryWritePermission VirtualMemoryProtection = 0x2 VirtualMemoryExecutePermission VirtualMemoryProtection = 0x4 )
Virtual memory permissions.