MachOKit
June 21, 2026 · View on GitHub
Library for parsing MachO files to obtain various information.
In addition to file reading, parsing of images in memory by _dyld_get_image_header is also supported.
Features
- parse load commands
- symbol list
- get all cstrings
- rebase operations
- binding operations
- export tries
- ...
Usage
Load from memory
For reading from memory, use the MachOImage structure.
It can be initialized by using the Mach-O Header pointer obtained by _dyld_get_image_header.
guard let mh = _dyld_get_image_header(0) else { return }
let machO = MachOImage(ptr: mh)
Alternatively, it can be initialized using the name.
// /System/Library/Frameworks/Foundation.framework/Versions/C/Foundation
guard let machO = MachOImage(name: "Foundation") else { return }
Load from file
For reading from file, use the MachOFile structure.
Reading from a file can be as follows. There is a case of a Fat file and a single MachO file, so a conditional branching process is required.
let path = "Path to MachO file"
let url = URL(string: path)
let file = try MachOKit.loadFromFile(url: url)
switch file {
case .machO(let machOFile): // single MachO file
print(machOFile)
case .fat(let fatFile): // Fat file
let machOFiles = try fatFile.machOFiles()
print(machOFiles)
}
Main properties and methods
Both MachOImage and MachOFile can use essentially the same properties and methods.
The available methods are defined in the following file as the MachORepresentable protocol.
Dyld Cache
Loading of dyld_shared_cache is also supported.
The available methods are defined in the following file as the DyldCacheRepresentable protocol.
Dyld Cache (File)
let path = "/System/Volumes/Preboot/Cryptexes/OS/System/Library/dyld/dyld_shared_cache_arm64e"
let url = URL(fileURLWithPath: path)
let cache = try! DyldCache(url: url)
It is also possible to extract machO information contained in dyld_shared_cache.
The machO extracted is of type MachOFile.
As with reading from a single MachO file, various analyses are possible.
let machOs = cache.machOFiles()
for machO in machOs {
print(
String(machO.headerStartOffsetInCache, radix: 16),
machO.imagePath,
machO.header.ncmds
)
}
// 5c000 /usr/lib/libobjc.A.dylib 22
// 98000 /usr/lib/dyld 15
// 131000 /usr/lib/system/libsystem_blocks.dylib 24
// ...
Full Dyld Cache (File)
In addition to DyldCache, FullDyldCache can be used to handle multiple dyld cache files (main cache and subcaches) as a single unified cache.
let path = "/System/Volumes/Preboot/Cryptexes/OS/System/Library/dyld/dyld_shared_cache_arm64e"
let url = URL(fileURLWithPath: path)
let fullCache = try! FullDyldCache(url: url)
// Access all Mach-O files across main and subcaches
let machOs = fullCache.machOFiles()
for machO in machOs {
print(
String(machO.headerStartOffsetInCache, radix: 16),
machO.imagePath,
machO.header.ncmds
)
}
The FullDyldCache type provides properties like mainCache, subCaches, allCaches, and urls to access each component cache file.
Dyld Cache (on memory)
On the Apple platform, the dyld cache is deployed in memory.
var size = 0
guard let ptr = _dyld_get_shared_cache_range(&size) else {
return
}
let cache = try! DyldCacheLoaded(ptr: ptr)
It is also possible to extract machO information contained in dyld_shared_cache.
The machO extracted is of type MachOImage.
As with reading from a single MachO image, various analyses are possible.
let machOs = cache.machOImages()
for machO in machOs {
print(
String(Int(bitPattern: machO.ptr), radix: 16),
machO.path!,
machO.header.ncmds
)
}
// 193438000 /usr/lib/libobjc.A.dylib 24
// 193489000 /usr/lib/dyld 15
// 193513000 /usr/lib/system/libsystem_blocks.dylib 24
// ...
UI-friendly labels
MachOKit keeps description values close to C header constants (for example LC_MAIN).
If you need user-facing labels, import MachOKitReadable and use readableDescription.
import MachOKit
import MachOKitReadable
let type = FileType.execute
print(type.description) // MH_EXECUTE
print(type.readableDescription) // Executable
Example Codes
There are a variety of uses, but most show a basic example that prints output to the Test directory.
Load from memory
The following file contains sample code. MachOPrintTests
Load from file
The following file contains sample code. MachOFilePrintTests
Dyld Cache (file)
The following file contains sample code. DyldCachePrintTests
Dyld Cache (on memory)
The following file contains sample code. DyldCacheLoadedPrintTests
Related Projects
- MachOKitSPM Pre-built version of MachOKit
- SwiftHook ⚓️ A Swift Library for hooking swift methods and functions.
- FishHook Re-implementation of facebook/fishhook with Swift using MachOKit
- AntiFishHook A Swift library to deactivate fishhook. (Anti-FishHook)
- dyld-shared-cache-extractor A CLI tool to extract dylib from dyld_shared_cache
- inject-o A CLI tool for injecting dependent dylibs into the Mach-O file.
Runtime Metadata
Utilities for extracting higher-level language metadata from Mach-O binaries.
-
MachOObjCSection Objective-C metadata parser for classes, methods, protocols, properties, categories, and related runtime structures.
-
MachOSwiftSection Swift metadata parser for types, protocols, protocol conformances, and other Swift runtime information. (Developed by Mx-Iris.)
Debug Information
- swift-dwarf A Swift library for parsing DWARF debug information.
Other binary type
License
MachOKit is released under the MIT License. See LICENSE