# How to Use the ipsw diff Command to Compare Firmware Versions Effectively

> Learn to effectively compare firmware versions using the ipsw diff command. Mount DMGs and diff Mach-O binaries byte-by-byte with the --fw flag for detailed insights.

- Repository: [blacktop/ipsw](https://github.com/blacktop/ipsw)
- Tags: how-to-guide
- Published: 2026-02-26

---

**The `ipsw diff` command generates detailed byte-level comparisons between two IPSW files by mounting their SystemOS DMGs and running Git-style diffs on Mach-O binaries using the `--fw` flag.**

The `ipsw diff` command in the **blacktop/ipsw** toolkit is the definitive way to analyze changes between iOS, iPadOS, or macOS firmware versions. Whether you are a security researcher tracking kernel patches or a developer auditing framework changes, this command provides granular visibility into firmware modifications by analyzing the actual Mach-O binaries extracted from IPSW archives.

## How the ipsw diff Command Works

The command operates through a three-stage pipeline defined in [`internal/diff/diff.go`](https://github.com/blacktop/ipsw/blob/main/internal/diff/diff.go). Understanding this flow helps you interpret the output and optimize performance for large firmware files.

### Metadata Extraction

First, the command parses each IPSW's `BuildManifest` to extract version strings, build numbers, and board configurations. This logic resides in the `(*Diff).getInfo` method (lines 30-33 of [`internal/diff/diff.go`](https://github.com/blacktop/ipsw/blob/main/internal/diff/diff.go)), which populates the diff context before any binary analysis begins.

### SystemOS DMG Mounting

Next, the command extracts and mounts the SystemOS DMG from each IPSW. If the DMG is AEA-encrypted, it is decrypted automatically. The mounting logic is handled by `mountDMG` and `mountSystemOsDMGs` (lines 25-38 of [`internal/diff/diff.go`](https://github.com/blacktop/ipsw/blob/main/internal/diff/diff.go)), which prepare the filesystem for analysis.

### Firmware Parsing and Comparison

Finally, the command invokes component-specific differs. For firmware analysis, `parseFirmwares` (lines 11112-11124 of [`internal/diff/diff.go`](https://github.com/blacktop/ipsw/blob/main/internal/diff/diff.go)) calls `mcmd.DiffFirmwares` from [`pkg/macho/diff.go`](https://github.com/blacktop/ipsw/blob/main/pkg/macho/diff.go). This performs a Git-style diff on every Mach-O binary—including the kernel, kexts, and dyld shared caches—highlighting exact byte-level changes in sections you specify.

## Essential Flags for Firmware Comparison

The command-line interface, defined in [`cmd/ipsw/cmd/diff.go`](https://github.com/blacktop/ipsw/blob/main/cmd/ipsw/cmd/diff.go) (lines 35-50), provides several flags to control the firmware comparison behavior:

- **`--fw`** – Enables firmware diffing mode, which analyzes kernelcaches, kexts, and dyld shared caches.
- **`--allow-list`** – Restricts analysis to specific Mach-O sections (e.g., `__TEXT.__text`) to reduce noise.
- **`--block-list`** – Excludes specific sections from the diff (e.g., `__TEXT.__info_plist`).
- **`--markdown`, `--json`, `--html`** – Specifies the output format; Markdown is recommended for human-readable reports.
- **`--output`** (`-o`) – Sets the destination directory for generated reports.
- **`--low-memory`** – Forces the diff engine to use temporary files instead of RAM, essential for comparing large IPSWs on resource-constrained systems.

## Step-by-Step Workflow for Comparing Firmware Versions

Follow this workflow to generate actionable intelligence from firmware updates:

1. **Acquire the IPSW files** for both versions you want to compare (e.g., `iPhone14,2_15.6_20G5023e_Restore.ipsw` and `iPhone14,2_15.7_20H19_Restore.ipsw`).

2. **Run the basic firmware diff** with Markdown output:

   ```bash
   ipsw diff iPhone14,2_15.6_20G5023e_Restore.ipsw \
             iPhone14,2_15.7_20H19_Restore.ipsw \
             --fw --markdown -o ./fw-diff
   ```

   This mounts the SystemOS DMGs from both IPSWs and produces a Git-style diff of all Mach-O binaries in `./fw-diff/`.

3. **Filter for specific sections** to focus on executable code changes only:

   ```bash
   ipsw diff old.ipsw new.ipsw --fw \
       --allow-list __TEXT.__text \
       --markdown -o ./kernel-text-diff
   ```

4. **Handle large firmware files** on systems with limited RAM:

   ```bash
   ipsw diff old.ipsw new.ipsw --fw --low-memory --markdown -o ./lowmem-report
   ```

5. **Inspect the generated Markdown report**. The output uses standard `+`/`-` markers to highlight added or removed symbols, modified function prologues, and altered section contents across the kernel and kexts.

## Summary

- The `ipsw diff` command provides **byte-level firmware comparison** by analyzing Mach-O binaries extracted from IPSW SystemOS DMGs.
- The process involves **three stages**: metadata extraction (`(*Diff).getInfo`), DMG mounting (`mountSystemOsDMGs`), and component parsing (`parseFirmwares` using `mcmd.DiffFirmwares`).
- Use the **`--fw`** flag to enable firmware mode, and filter output with **`--allow-list`** or **`--block-list`** to focus on specific Mach-O sections.
- Generate human-readable reports with **`--markdown`**, **`--json`**, or **`--html`**, and use **`--low-memory`** for large IPSWs on constrained hardware.

## Frequently Asked Questions

### What file formats does ipsw diff support for output?

The command supports four output formats: **binary** (default `.idiff` file using gob encoding for programmatic reuse), **Markdown** (`--markdown`), **JSON** (`--json`), and **HTML** (`--html`). Markdown is recommended for security research reports because it renders Git-style diffs with `+` and `-` markers in any text editor or GitHub/GitLab interface.

### How does ipsw diff handle encrypted or AEA-formatted DMGs?

The `ipsw diff` command automatically detects and decrypts AEA-encrypted DMGs during the mounting phase. The logic in `mountDMG` and `mountSystemOsDMGs` (defined in [`internal/diff/diff.go`](https://github.com/blacktop/ipsw/blob/main/internal/diff/diff.go)) extracts the SystemOS DMG from each IPSW, decrypts it if necessary, and mounts it to a temporary location before the Mach-O diff engine begins analysis.

### Can I compare specific Mach-O sections instead of entire binaries?

Yes. Use the **`--allow-list`** flag to restrict the diff to specific sections (e.g., `--allow-list __TEXT.__text` to compare only executable code), or use **`--block-list`** to exclude noisy sections like `__TEXT.__info_plist`. These filters are passed to `mcmd.DiffFirmwares` in [`pkg/macho/diff.go`](https://github.com/blacktop/ipsw/blob/main/pkg/macho/diff.go), which performs the section-level comparison on the extracted firmware binaries.

### What should I do if the diff fails due to memory constraints?

For large IPSW files (such as modern iOS restore images exceeding 8 GB), add the **`--low-memory`** flag. This forces the diff engine in [`internal/diff/diff.go`](https://github.com/blacktop/ipsw/blob/main/internal/diff/diff.go) to use temporary files on disk instead of loading entire Mach-O binaries into RAM. While this increases runtime slightly, it prevents out-of-memory errors on systems with limited physical RAM or when comparing multiple large firmware versions simultaneously.