How to Mount and Analyze APFS, HFS+, and DMG Images with ipsw
Use ipsw mount to treat Apple disk images as regular filesystems, leveraging utils.MountDMG to auto-detect APFS vs HFS+ and mount via apfs-fuse or native kernel drivers.
The blacktop/ipsw toolkit provides native Go utilities to mount and inspect Apple filesystems without manual conversion. Whether you are analyzing a raw DMG from an IPSW firmware package or a standalone APFS container, ipsw abstracts the underlying complexity through a unified mounting interface.
Detecting Disk Image Types Automatically
Before mounting, ipsw identifies the filesystem type by inspecting magic numbers in the image header. The detection logic resides in internal/magic/magic.go and distinguishes between modern APFS containers and legacy HFS+ volumes.
- APFS detection:
magic.IsAPFSatinternal/magic/magic.go#L253checks for the APFS container magic (NXSB). - HFS+ detection:
magic.IsHFSPlusatinternal/magic/magic.go#L272validates the HFS+ signature (H+orHX).
These helpers return boolean flags that the mounting dispatcher uses to select the appropriate driver.
Mounting APFS, HFS+, and DMG Images
The central entry point for all disk image operations is utils.MountDMG in internal/utils/macos.go#L651. This function acts as a dispatcher that automatically routes APFS images to FUSE-based handlers and HFS+ images to native kernel drivers.
APFS Mounting with apfs-fuse
For APFS containers, ipsw invokes mountWithAPFSFuse at internal/utils/macos.go#L564. This requires the user-installed apfs-fuse binary to be available in $PATH. The function handles container unlocking (if encrypted) and volume selection before exposing the filesystem at a temporary mount point.
HFS+ Mounting with Native Drivers
For HFS+ volumes, mountWithHFSPlus at internal/utils/macos.go#L578 leverages the native Linux HFS+ kernel driver. On macOS hosts, this falls back to hdiutil attach for seamless integration with the host operating system.
Mount Point Management
utils.MountDMG returns three values: the mount point path, a boolean indicating if the image was already mounted (idempotent operation), and an error. This allows downstream tools to safely unmount resources when analysis completes.
CLI Commands for Image Analysis
The ipsw CLI exposes mounting functionality through several specialized commands that target specific DMG types within IPSW firmware packages.
Mounting Specific Firmware Partitions
The ipsw mount command (defined in cmd/ipsw/cmd/mount.go) supports multiple DMG types:
# Mount the Filesystem DMG (user data partition)
ipsw mount fs iPhone15,2_16.5_20F66_Restore.ipsw
# Mount the SystemOS DMG with custom mount point and detach
ipsw mount sys iPhone.ipsw --mount-point /mnt/ios-system --detach
# Mount the App DMG (pre-installed apps)
ipsw mount app iPhone.ipsw
Available types include fs (Filesystem), sys (SystemOS), app (Applications), exc (Exclave), and rdisk (Restore ramdisk).
Extracting Binaries from Mounted Images
The ipsw extract command automatically mounts DMGs to extract specific artifacts:
# Extract dyld_shared_cache from SystemOS DMG
ipsw extract iPhone.ipsw --arch arm64
Internally, this calls utils.MountDMG then walks the mount point to locate cache files (internal/search/search.go).
Diffing System Versions
The ipsw sb diff command mounts two SystemOS DMGs to compare dyld_shared_cache contents:
ipsw sb diff old.ipsw new.ipsw
This leverages pkg/dyld/extract.go to mount both images simultaneously before performing the differential analysis.
Inspecting Wallpapers
The ipsw wp command mounts the Filesystem DMG to extract wallpaper assets:
ipsw wp iPhone.ipsw --output ./wallpapers
Programmatic Usage in Go
You can integrate disk image mounting directly into Go applications using the internal/utils package.
Complete Mounting Workflow
package main
import (
"fmt"
"log"
"os"
"path/filepath"
"strings"
"github.com/blacktop/ipsw/internal/utils"
)
func analyzeDMG(dmgPath string) error {
// Mount the image (auto-detects APFS vs HFS+)
mountPoint, alreadyMounted, err := utils.MountDMG(dmgPath, "")
if err != nil {
return fmt.Errorf("mount failed: %w", err)
}
status := "newly mounted"
if alreadyMounted {
status = "already mounted"
}
fmt.Printf("Image %s at %s\n", status, mountPoint)
// Walk the filesystem to find dynamic libraries
err = utils.Walk(mountPoint, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if strings.HasSuffix(path, ".dylib") {
relPath := strings.TrimPrefix(path, mountPoint)
fmt.Println("Found:", relPath)
}
return nil
})
if err != nil {
return fmt.Errorf("filesystem walk failed: %w", err)
}
// Cleanup: unmount when done
if err := utils.Unmount(mountPoint, true); err != nil {
return fmt.Errorf("unmount failed: %w", err)
}
return nil
}
func main() {
if err := analyzeDMG("System.dmg"); err != nil {
log.Fatal(err)
}
}
Type Detection Helpers
For applications that need to inspect images before mounting, use the magic number detectors:
import "github.com/blacktop/ipsw/internal/magic"
// Check if file is APFS
if isAPFS, _ := magic.IsAPFS(imagePath); isAPFS {
fmt.Println("APFS container detected")
}
// Check if file is HFS+
if isHFS, _ := magic.IsHFSPlus(imagePath); isHFS {
fmt.Println("HFS+ volume detected")
}
Key Source Files and Architecture
Understanding the codebase structure helps when extending ipsw or debugging mount issues.
| Path | Function |
|---|---|
internal/utils/macos.go#L651 |
MountDMG – Central dispatcher that routes to APFS or HFS+ handlers |
internal/magic/magic.go#L253 |
IsAPFS – Magic number detection for APFS containers |
internal/magic/magic.go#L272 |
IsHFSPlus – Magic number detection for HFS+ volumes |
internal/utils/macos.go#L564 |
mountWithAPFSFuse – APFS mounting via apfs-fuse binary |
internal/utils/macos.go#L578 |
mountWithHFSPlus – HFS+ mounting via native kernel driver |
cmd/ipsw/cmd/mount.go |
CLI implementation for ipsw mount subcommands |
pkg/dyld/extract.go |
dyld_shared_cache extraction from mounted SystemOS DMGs |
internal/search/search.go |
DMG scanning and filesystem walking utilities |
internal/diff/diff.go |
SystemOS DMG comparison logic |
api/server/routes/ipsw/ipsw.go |
HTTP API endpoints for remote DMG mounting |
Summary
- Automatic detection:
ipswidentifies APFS vs HFS+ via magic numbers ininternal/magic/magic.gobefore attempting to mount. - Flexible mounting: The
utils.MountDMGdispatcher atinternal/utils/macos.go#L651routes APFS images toapfs-fuseand HFS+ images to native kernel drivers. - CLI integration: Commands like
ipsw mount,ipsw extract, andipsw sb diffabstract the mounting lifecycle, automatically cleaning up resources after analysis. - Programmatic access: Go developers can import
github.com/blacktop/ipsw/internal/utilsto mount images, walk filesystems, and extract specific file types with full control over mount points and cleanup.
Frequently Asked Questions
What dependencies are required to mount APFS images with ipsw?
Mounting APFS containers requires the apfs-fuse binary to be installed and available in your system $PATH. ipsw does not bundle this dependency; it shells out to the external binary at internal/utils/macos.go#L564. HFS+ images do not require external tools on Linux systems with the native HFS+ kernel driver loaded.
Can ipsw mount encrypted DMG files?
Yes, ipsw supports mounting encrypted DMG files when the necessary keys are available. The mountWithAPFSFuse function handles container unlocking before mounting. For IPSW firmware packages, ipsw can automatically extract keys from the manifest for certain DMG types, though manual key provision may be required for custom encrypted images.
How does ipsw handle already-mounted images?
The utils.MountDMG function returns a boolean flag indicating whether the image was already mounted at the requested path. If already mounted, ipsw skips the mount operation and proceeds with analysis, preventing duplicate mount entries. During cleanup, the unmount logic checks this state to avoid unmounting images that were mounted by other processes before ipsw ran.
Is it possible to mount DMG images via the ipsw HTTP API?
Yes, the web server implementation in api/server/routes/ipsw/ipsw.go exposes HTTP endpoints that trigger DMG mounting operations remotely. This allows automated analysis pipelines to mount firmware images on a server instance, extract specific files via the API, and unmount resources programmatically without direct shell access to the host system.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →