macho

The macho module allows you to create more fine-grained rules for Mach-O files by using attributes and features of the Mach-O file format. This module exposes most of the fields present in a Mach-O header and provides functions which can be used to write more expressive and targeted rules. Let’s see some examples:

import "macho"

rule cpu_type {
  condition:
    macho.cputype == macho.CPU_TYPE_X86_64
}

rule frameworks_rpath {
  condition:
    macho.has_rpath("@loader_path/../Frameworks")
}

rule dylib_hash {
  condition:
    macho.dylib_hash() == "c92070ad210458d5b3e8f048b1578e6d"
}

Functions

file_index_for_arch(type_arg)

Returns the the index of a Mach-O file within a fat binary based on CPU type.

Example

import "macho"

rule file_index_example {
  condition:
    macho.file_index_for_arch(0x00000008) == 0
}

file_index_for_arch(type_arg, subtype_arg)

Returns the index of a Mach-O file within a fat binary based on both CPU type and subtype.

Example

import "macho"

rule file_index_example_sub {
  condition:
    macho.file_index_for_arch(0x00000008, 0x00000004) == 0
}

entry_point_for_arch(type_arg)

Returns the real entry point offset for a specific CPU type within a fat Mach-O binary.

Example

import "macho"

rule entrypoint_example {
  condition:
    macho.entry_point_for_arch(0x01000007) == 0x00004EE0
}

entry_point_for_arch(type_arg, subtype_arg))

Returns the real entry point offset for a specific CPU type and subtype within a fat Mach-O binary.

Example

import "macho"

rule entrypoint_example_sub {
  condition:
    macho.entry_point_for_arch(0x00000007, 0x00000003) == 0x00001EE0
}

has_entitlement(entitlement)

Returns true if the Mach-O parsed entitlements contain entitlement

  • entitlement is case-insensitive.

Example

import "macho"

rule has_entitlement_example {
  condition:
    macho.has_entitlement("com.apple.security.network.client")
}

has_dylib(dylib_name)

Returns true if the Mach-O parsed dylibs contain dylib_name

  • dylib_name is case-insensitive.

Example

import "macho"

rule has_dylib_example {
  condition:
    macho.has_dylib("/usr/lib/libSystem.B.dylib")
}

has_rpath(rpath)

Returns true if the Mach-O parsed rpaths contain rpath

  • rpath is case-insensitive.

Example

import "macho"

rule has_rpath_example {
  condition:
    macho.has_rpath("@loader_path/../Frameworks")
}

has_import(import)

Returns true if the Mach-O parsed imports contain import

  • import is case-insensitive.

Example

import "macho"

rule has_import_example {
  condition:
    macho.has_import("_NSEventTrackingRunLoopMode")
}

has_export(export)

Returns true if the Mach-O parsed exports contain export

  • export is case-insensitive.

Example

import "macho"

rule has_export_example {
  condition:
    macho.has_export("_main")
}

dylib_hash()

Returns an MD5 hash of the dylibs designated in the Mach-O binary.

Notice

The returned hash string is always in lowercase.

Example

import "macho"

rule dylib_hash_example {
  condition:
    macho.dylib_hash() == "c92070ad210458d5b3e8f048b1578e6d"
}

entitlement_hash()

Returns an MD5 hash of the entitlements designated in the Mach-O binary.

Notice

The returned hash string is always in lowercase.

Example

import "macho"

rule entitlement_hash_example {
  condition:
    macho.entitlement_hash() == "cc9486efb0ce73ba411715273658da80"
}

export_hash()

Returns an MD5 hash of the exports designated in the Mach-O binary.

Notice

The returned hash string is always in lowercase.

Example

import "macho"

rule export_hash_example {
  condition:
    macho.export_hash() == "6bfc6e935c71039e6e6abf097830dceb"
}

import_hash()

Returns an MD5 hash of the imports designated in the Mach-O binary.

Notice

The returned hash string is always in lowercase.

Example

import "macho"

rule import_hash_example {
  condition:
    macho.import_hash() == "35ea3b116d319851d93e26f7392e876e"
}

sym_hash()

Returns an MD5 hash of the symbol table entries designated in the Mach-O binary.

Notice

The returned hash string is always in lowercase.

Example

import "macho"

rule sym_hash_example {
  condition:
    macho.sym_hash() == "a9ccc7c7b8bd33a99dc7ede4e8d771b4"
}

Module structure

FieldType
magicinteger
cputypeinteger
cpusubtypeinteger
filetypeinteger
ncmdsinteger
sizeofcmdsinteger
flagsinteger
reservedinteger
number_of_segmentsinteger
dynamic_linkerstring
entry_pointinteger
stack_sizeinteger
source_versionstring
symtabSymtab
dysymtabDysymtab
code_signature_dataLinkedItData
segmentsSegment array
dylibsDylib array
dyld_infoDyldInfo
rpathsstring array
entitlementsstring array
certificatesCertificates
uuidstring
build_versionBuildVersion
min_versionMinVersion
exportsstring array
fat_magicinteger
nfat_archinteger
fat_archFatArch array
fileFile array

BuildTool

FieldType
toolinteger
versionstring

BuildVersion

FieldType
platforminteger
minosstring
sdkstring
ntoolsinteger
toolsBuildTool array

Certificates

FieldType
common_namesstring array
signer_namesstring array

DyldInfo

FieldType
rebase_offinteger
rebase_sizeinteger
bind_offinteger
bind_sizeinteger
weak_bind_offinteger
weak_bind_sizeinteger
lazy_bind_offinteger
lazy_bind_sizeinteger
export_offinteger
export_sizeinteger

Dylib

FieldType
namestring
timestampinteger
compatibility_versionstring
current_versionstring

Dysymtab

FieldType
ilocalsyminteger
nlocalsyminteger
iextdefsyminteger
nextdefsyminteger
iundefsyminteger
nundefsyminteger
tocoffinteger
ntocinteger
modtaboffinteger
nmodtabinteger
extrefsymoffinteger
nextrefsymsinteger
indirectsymoffinteger
nindirectsymsinteger
extreloffinteger
nextrelinteger
locreloffinteger
nlocrelinteger

FatArch

FieldType
cputypeinteger
cpusubtypeinteger
offsetinteger
sizeinteger
aligninteger
reservedinteger

File

FieldType
magicinteger
cputypeinteger
cpusubtypeinteger
filetypeinteger
ncmdsinteger
sizeofcmdsinteger
flagsinteger
reservedinteger
number_of_segmentsinteger
dynamic_linkerstring
entry_pointinteger
stack_sizeinteger
source_versionstring
segmentsSegment array
dylibsDylib array
rpathsstring array
entitlementsstring array
symtabSymtab
dysymtabDysymtab
dyld_infoDyldInfo
code_signature_dataLinkedItData
certificatesCertificates
uuidstring
build_versionBuildVersion
min_versionMinVersion

LinkedItData

FieldType
dataoffinteger
datasizeinteger

MinVersion

FieldType
deviceDEVICE_TYPE
versionstring
sdkstring

Section

FieldType
segnamestring
sectnamestring
addrinteger
sizeinteger
offsetinteger
aligninteger
reloffinteger
nrelocinteger
flagsinteger
reserved1integer
reserved2integer
reserved3integer

Segment

FieldType
segnamestring
vmaddrinteger
vmsizeinteger
fileoffinteger
filesizeinteger
maxprotinteger
initprotinteger
nsectsinteger
flagsinteger
sectionsSection array

Symtab

FieldType
symoffinteger
nsymsinteger
stroffinteger
strsizeinteger
entriesstring array

CPU_ARM_64_SUBTYPE

NameNumber
CPU_SUBTYPE_ARM_V5TEJ7
CPU_SUBTYPE_ARM64_ALL0

CPU_ARM_SUBTYPE

NameNumber
CPU_SUBTYPE_ARM_ALL0
CPU_SUBTYPE_ARM_V4T5
CPU_SUBTYPE_ARM_V66
CPU_SUBTYPE_ARM_V57
CPU_SUBTYPE_ARM_XSCALE8
CPU_SUBTYPE_ARM_V79
CPU_SUBTYPE_ARM_V7F10
CPU_SUBTYPE_ARM_V7S11
CPU_SUBTYPE_ARM_V7K12
CPU_SUBTYPE_ARM_V6M14
CPU_SUBTYPE_ARM_V7M15
CPU_SUBTYPE_ARM_V7EM16

CPU_I386_SUBTYPE

NameNumber
CPU_SUBTYPE_I386_ALL3

CPU_I386_TYPE

NameNumber
CPU_TYPE_I3867

CPU_INTEL_PENTIUM_SUBTYPE

NameNumber
CPU_SUBTYPE_PENT5
CPU_SUBTYPE_PENTPRO22
CPU_SUBTYPE_PENTII_M354
CPU_SUBTYPE_PENTII_M586
CPU_SUBTYPE_PENTIUM_38
CPU_SUBTYPE_PENTIUM_3_M24
CPU_SUBTYPE_PENTIUM_3_XEON40
CPU_SUBTYPE_PENTIUM_M9
CPU_SUBTYPE_PENTIUM_410
CPU_SUBTYPE_PENTIUM_4_M26

CPU_INTEL_SUBTYPE

NameNumber
CPU_SUBTYPE_INTEL_MODEL_ALL0
CPU_SUBTYPE_3863
CPU_SUBTYPE_4864
CPU_SUBTYPE_486SX132
CPU_SUBTYPE_5865
CPU_SUBTYPE_CELERON103
CPU_SUBTYPE_CELERON_MOBILE119
CPU_SUBTYPE_ITANIUM11
CPU_SUBTYPE_ITANIUM_227
CPU_SUBTYPE_XEON12
CPU_SUBTYPE_XEON_MP28

CPU_MC_SUBTYPE

NameNumber
CPU_SUBTYPE_MC980000_ALL0
CPU_SUBTYPE_MC986011

CPU_POWERPC_SUBTYPE

NameNumber
CPU_SUBTYPE_POWERPC_ALL0
CPU_SUBTYPE_POWERPC_6011
CPU_SUBTYPE_POWERPC_6022
CPU_SUBTYPE_POWERPC_6033
CPU_SUBTYPE_POWERPC_603e4
CPU_SUBTYPE_POWERPC_603ev5
CPU_SUBTYPE_POWERPC_6046
CPU_SUBTYPE_POWERPC_604e7
CPU_SUBTYPE_POWERPC_6208
CPU_SUBTYPE_POWERPC_7509
CPU_SUBTYPE_POWERPC_740010
CPU_SUBTYPE_POWERPC_745011
CPU_SUBTYPE_POWERPC_970100

CPU_SPARC_SUBTYPE

NameNumber
CPU_SUBTYPE_SPARC_ALL0

CPU_TYPE

NameNumber
CPU_TYPE_MC680X06
CPU_TYPE_X867
CPU_TYPE_X86_6416777223
CPU_TYPE_MIPS8
CPU_TYPE_MC9800010
CPU_TYPE_ARM12
CPU_TYPE_ARM6416777228
CPU_TYPE_MC8800013
CPU_TYPE_SPARC14
CPU_TYPE_POWERPC18
CPU_TYPE_POWERPC6416777234

CPU_X86_SUBTYPE

NameNumber
CPU_SUBTYPE_X86_64_ALL3

DEVICE_TYPE

NameNumber
MACOSX36
IPHONEOS37
TVOS47
WATCHOS48

FAT_HEADER

NameNumber
FAT_MAGIC0
FAT_CIGAM1
FAT_MAGIC_642
FAT_CIGAM_643

FILE_FLAG

NameNumber
MH_NOUNDEFS1
MH_INCRLINK2
MH_DYLDLINK4
MH_BINDATLOAD8
MH_PREBOUND16
MH_SPLIT_SEGS32
MH_LAZY_INIT64
MH_TWOLEVEL128
MH_FORCE_FLAT256
MH_NOMULTIDEFS512
MH_NOFIXPREBINDING1024
MH_PREBINDABLE2048
MH_ALLMODSBOUND4096
MH_SUBSECTIONS_VIA_SYMBOLS8192
MH_CANONICAL16384
MH_WEAK_DEFINES32768
MH_BINDS_TO_WEAK65536
MH_ALLOW_STACK_EXECUTION131072
MH_ROOT_SAFE262144
MH_SETUID_SAFE524288
MH_NO_REEXPORTED_DYLIBS1048576
MH_PIE2097152
MH_DEAD_STRIPPABLE_DYLIB4194304
MH_HAS_TLV_DESCRIPTORS8388608
MH_NO_HEAP_EXECUTION16777216
MH_APP_EXTENSION_SAFE33554432

FILE_TYPE

NameNumber
MH_OBJECT1
MH_EXECUTE2
MH_FVMLIB3
MH_CORE4
MH_PRELOAD5
MH_DYLIB6
MH_DYLINKER7
MH_BUNDLE8
MH_DYLIB_STUB9
MH_DSYM10
MH_KEXT_BUNDLE11
NameNumber
MH_MAGIC0
MH_CIGAM1
MH_MAGIC_642
MH_CIGAM_643

MASK_64BIT

NameNumber
CPU_ARCH_ABI6416777216
CPU_SUBTYPE_LIB640

SECTION_ATTRIBUTES

NameNumber
S_ATTR_PURE_INSTRUCTIONS0
S_ATTR_NO_TOC1073741824
S_ATTR_STRIP_STATIC_SYMS536870912
S_ATTR_NO_DEAD_STRIP268435456
S_ATTR_LIVE_SUPPORT134217728
S_ATTR_SELF_MODIFYING_CODE67108864
S_ATTR_DEBUG33554432
S_ATTR_SOME_INSTRUCTIONS1024
S_ATTR_EXT_RELOC512
S_ATTR_LOC_RELOC256

SECTION_TYPE

NameNumber
S_REGULAR0
S_ZEROFILL1
S_CSTRING_LITERALS2
S_4BYTE_LITERALS3
S_8BYTE_LITERALS4
S_LITERAL_POINTERS5
S_NON_LAZY_SYMBOL_POINTERS6
S_LAZY_SYMBOL_POINTERS7
S_SYMBOL_STUBS8
S_MOD_INIT_FUNC_POINTERS9
S_MOD_TERM_FUNC_POINTERS10
S_COALESCED11
S_GB_ZEROFILL12
S_INTERPOSING13
S_16BYTE_LITERALS14
S_DTRACE_DOF15
S_LAZY_DYLIB_SYMBOL_POINTERS16
S_THREAD_LOCAL_REGULAR17
S_THREAD_LOCAL_ZEROFILL18
S_THREAD_LOCAL_VARIABLES19
S_THREAD_LOCAL_VARIABLE_POINTERS20
S_THREAD_LOCAL_INIT_FUNCTION_POINTERS21

SEGMENT_FLAG

NameNumber
SG_HIGHVM1
SG_FVMLIB2
SG_NORELOC4
SG_PROTECTED_VERSION_18