A Swift library for parsing mach-o files to obtain Swift information. οΌTypes/Protocol/ProtocolConformance infoοΌ
It may be the most powerful swift dump you can find so far, as it uses a custom Demangler to parse symbolic references and restore the original logic of the Swift Runtime as much as possible.
Note
This library is developed as an extension of MachOKit for Swift
- Swift 6.2+
- Xcode 26.0+
- macOS 10.15+ / iOS 13+ / tvOS 13+ / watchOS 6+ / visionOS 1+
- Protocol Descriptors
- Protocol Conformance Descriptors
- Type Context Descriptors
- Associated Type Descriptors
- Method Symbol For Dyld Caches
- Builtin Type Descriptors
- Swift Interface Support
- Runtime Metadata Inspection (
SwiftInspection) - Type Member Layout (WIP, MachOImage only)
- Swift Section MCP
Add the package to your Package.swift:
dependencies: [
.package(url: "https://github.com/MxIris-Reverse-Engineering/MachOSwiftSection", from: "0.10.0"),
],
targets: [
.target(
name: "YourTarget",
dependencies: [
.product(name: "MachOSwiftSection", package: "MachOSwiftSection"),
// Optional higher-level products:
.product(name: "SwiftInspection", package: "MachOSwiftSection"),
.product(name: "SwiftDump", package: "MachOSwiftSection"),
.product(name: "SwiftInterface", package: "MachOSwiftSection"),
.product(name: "TypeIndexing", package: "MachOSwiftSection"),
]
),
]| Product | Purpose |
|---|---|
MachOSwiftSection |
Low-level parsing of __swift5_* sections (raw descriptors). |
SwiftInspection |
Runtime metadata inspection β EnumLayoutCalculator (multi-payload enum layouts), ClassHierarchyDumper, MetadataReader. |
SwiftDump |
High-level type wrappers (Struct, Enum, Class, Protocol, ProtocolConformance, β¦). |
SwiftInterface |
End-to-end Swift interface generation. |
TypeIndexing |
Index types / extensions / conformances for cross-binary analysis. |
Swift information from MachOImage or MachOFile can be retrieved via the swift property.
import MachOKit
import MachOSwiftSection
let machO //` MachOFile` or `MachOImage`
// Protocol Descriptors
let protocolDescriptors = try machO.swift.protocolDescriptors
for protocolDescriptor in protocolDescriptors {
let protocolType = try Protocol(descriptor: protocolDescriptor, in: machO)
// do somethings ...
}
// Protocol Conformance Descriptors
let protocolConformanceDescriptors = try machO.swift.protocolConformanceDescriptors
for protocolConformanceDescriptor in protocolConformanceDescriptors {
let protocolConformance = try ProtocolConformance(descriptor: protocolConformanceDescriptor, in: machO)
// do somethings ...
}
// Type/Nominal Descriptors
let typeContextDescriptors = try machO.swift.typesContextDescriptors
for typeContextDescriptor in typeContextDescriptors {
switch typeContextDescriptor {
case .type(let typeContextDescriptorWrapper):
switch typeContextDescriptorWrapper {
case .enum(let enumDescriptor):
let enumType = try Enum(descriptor: enumDescriptor, in: machO)
// do somethings ...
case .struct(let structDescriptor):
let structType = try Struct(descriptor: structDescriptor, in: machO)
// do somethings ...
case .class(let classDescriptor):
let classType = try Class(descriptor: classDescriptor, in: machO)
// do somethings ...
}
default:
break
}
}For generating complete Swift interface files, you can use the SwiftInterface library which provides a more comprehensive interface generation capability.
import MachOKit
import SwiftInterface
let builder = try SwiftInterfaceBuilder(configuration: .init(), eventHandlers: [], in: machO)
try await builder.prepare()
let result = try await builder.printRoot()Generated interfaces reflect a wide range of Swift language features:
- Type / member attributes:
@objc,@nonobjc,dynamic,@retroactive,@globalActor,@escaping,consuming/borrowingparameter modifiers distributed actordeclarations anddistributed funcmembersdeinitfor classes and noncopyable types- VTable offset comments alongside class members, ordered to match the on-disk layout
- Expanded field offsets for nested struct fields, rendered as a tree
- Inverted protocols (
~Copyable,~Escapable) on types and generic requirements
SwiftInspection exposes higher-level inspection utilities built on top of MachOSwiftSection:
EnumLayoutCalculatorβ compute the on-disk layout of Swift enums, including single-payload and multi-payload (tagged and untagged) cases. Mirrors the ABI rules inswift/ABI/Enum.h.ClassHierarchyDumperβ walk a class's inheritance chain across Swift/ObjC boundaries (requires@_spi(Internals) import SwiftInspection,MachOImageonly).MetadataReaderβ demangle types, symbols, context descriptors, and build generic signatures against a Mach-O.
You can get the swift-section CLI tool in three ways:
- GitHub Releases: Download from GitHub releases
- Homebrew: Install via
brew install swift-section - Build from Source: Build with
./build-executable-product.sh(requires Xcode 26.0 / Swift 6.2+ toolchain)
The swift-section CLI tool provides two main subcommands: dump, and interface.
Important
As of 0.10.0, when the input is a fat / universal binary you must pass --architecture <arch>. The tool no longer picks a default slice silently.
Dump Swift information from a Mach-O file or dyld shared cache.
swift-section dump [options] [file-path]Basic usage:
# Dump all Swift information from a Mach-O file
swift-section dump /path/to/binary
# Dump only types and protocols
swift-section dump --sections types,protocols /path/to/binary
# Save output to file
swift-section dump --output-path output.txt /path/to/binary
# Use specific architecture (required for fat binaries)
swift-section dump --architecture arm64 /path/to/binaryWorking with dyld shared cache:
# Dump from system dyld shared cache
swift-section dump --uses-system-dyld-shared-cache --cache-image-name SwiftUICore
# Dump from specific dyld shared cache
swift-section dump --dyld-shared-cache --cache-image-path /path/to/cache /path/to/dyld_shared_cacheDump output includes richer annotations:
- Protocol witness table (PWT) entries are annotated with the requirement they satisfy
- Inverted protocol constraints (
~Copyable,~Escapable) are rendered on types and generic requirements - Protocol conformances can include the PWT address
Generate a complete Swift interface file from a Mach-O file, similar to Swift's generated interfaces.
swift-section interface [options] [file-path]Basic usage:
# Generate Swift interface from a Mach-O file
swift-section interface /path/to/binary
# Save interface to file
swift-section interface --output-path interface.swiftinterface /path/to/binary
# Use specific architecture (required for fat binaries)
swift-section interface --architecture arm64 /path/to/binaryWorking with dyld shared cache:
# Dump from system dyld shared cache
swift-section interface --uses-system-dyld-shared-cache --cache-image-name SwiftUICore
# Dump from specific dyld shared cache
swift-section interface --dyld-shared-cache --cache-image-path /path/to/cache /path/to/dyld_shared_cacheThe snapshot tests in this repository rely on a fixture framework (SymbolTestsCore) built from an Xcode project in Tests/Projects/SymbolTests/. The framework binary is not checked in β rebuild it once after cloning:
./Scripts/build-test-fixtures.shThen run the tests:
swift package update
swift testSkipping the fixture build causes MachOFileTests to throw a "file not found" error at Tests/Projects/SymbolTests/DerivedData/.../SymbolTestsCore during test init(), before any assertions run.
To regenerate snapshots after a legitimate Swift-compiler / metadata change:
SNAPSHOT_TESTING_RECORD=all swift test \
--filter SymbolTestsCoreDumpSnapshotTests \
--filter SymbolTestsCoreInterfaceSnapshotTestsCommit the updated __Snapshots__/ files alongside the source change that prompted the regeneration.
MachOSwiftSection is released under the MIT License. See LICENSE