How to Decrypt and Analyze IMG3 and IMG4 Firmware Formats with ipsw

You can decrypt and analyze Apple IMG3 and IMG4 firmware files using the ipsw toolkit's Go packages (pkg/img3, pkg/img4) for programmatic access or the ipsw CLI for command-line workflows that support automatic key lookup from public databases.

The ipsw toolkit provides comprehensive support for parsing and decrypting Apple's proprietary firmware containers. Whether you are analyzing legacy IMG3 binary tag-based formats or modern ASN.1-based IMG4 wrappers, ipsw offers both low-level Go APIs and high-level CLI commands to extract and decrypt firmware components.

Understanding IMG3 and IMG4 Firmware Formats

Apple firmware files use two primary container formats. IMG3 is a binary tag-based structure used in older iOS devices, while IMG4 is a newer ASN.1-encoded wrapper that contains optional Payload, Manifest, and RestoreInfo components. Both formats support encryption via KBAG (keybag) tags that store the AES IV and key required for decryption.

Parsing IMG3 Files with pkg/img3

The pkg/img3 package in ipsw provides a complete parser for IMG3 containers. The implementation in pkg/img3/img3.go defines the binary structures and parsing logic.

The Header structure starts with a 4-byte magic (Img3) followed by size fields and an identifier:

// pkg/img3/img3.go#L23-L34
type Header struct {
    Magic  [4]byte
    Size   uint32
    ID     uint32
    // ...
}

Tags are repeated blocks containing a header, data, and padding. Common tags include TYPE, DATA, and KBAG:

// pkg/img3/img3.go#L36-L44
type Tag struct {
    Header TagHeader
    Data   []byte
    Pad    []byte
}

To parse an IMG3 file programmatically, use the ParseImg3 function:

import "github.com/blacktop/ipsw/pkg/img3"

data, err := os.ReadFile("firmware.img3")
if err != nil {
    log.Fatal(err)
}

img, err := img3.ParseImg3(data)
if err != nil {
    log.Fatal(err)
}

Decrypting IMG3 Firmware Components

Decryption in ipsw follows a two-step process: first decrypting the KBAG to obtain the AES key and IV, then decrypting the actual DATA tag using AES-CBC.

The DecryptKBag function in pkg/img3/img3.go handles KBAG decryption using a supplied GID key:

// pkg/img3/img3.go#L232-L259
func DecryptKBag(kbagData []byte, gidKey []byte) ([]byte, error) {
    // Decrypts KBAG payload to reveal IV and AES key
}

For the complete workflow, use DecryptWithGIDKey which combines KBAG extraction and data decryption:

decrypted, err := img3.DecryptWithGIDKey(data, gidKey)
if err != nil {
    log.Fatal(err)
}

Alternatively, if you already have the raw IV and key (not the GID key), use DecryptData directly:

// pkg/img3/img3.go#L266-L291
func DecryptData(data []byte, iv []byte, key []byte) ([]byte, error) {
    // AES-CBC decryption
}

Parsing and Decrypting IMG4 Files

The IMG4 format uses ASN.1 encoding and is handled by pkg/img4. The top-level structure in pkg/img4/img4.go consists of optional Payload, Manifest, and RestoreInfo components:

// pkg/img4/img4.go#L52-L65
type Image struct {
    Payload      *Payload
    Manifest     *Manifest
    RestoreInfo  *RestoreInfo
}

Parse an IMG4 file using the Parse function:

import "github.com/blacktop/ipsw/pkg/img4"

data, err := os.ReadFile("firmware.img4")
if err != nil {
    log.Fatal(err)
}

img4Image, err := img4.Parse(data)
if err != nil {
    log.Fatal(err)
}

The IM4P (IMG4 Payload) component contains the actual firmware binary and may include its own KBAG for encryption. Access the payload via img4Image.Payload and check payload.Encrypted to determine if decryption is required.

Decrypting IMG4 IM4P Payloads

Decryption of IMG4 payloads is implemented in pkg/img4/payload.go. The DecryptPayload function performs AES-CBC decryption when provided with the correct IV and key:

// pkg/img4/payload.go#L756-L768
func DecryptPayload(inputPath string, outputPath string, iv []byte, key []byte) error {
    // Reads IM4P, decrypts with AES-CBC, writes output
}

For in-memory decryption of payload bytes, use DecryptPayloadBytes:

decryptedData, err := img4.DecryptPayloadBytes(payload.Data, iv, key)
if err != nil {
    log.Fatal(err)
}

If you need to decrypt a complete IMG4 file programmatically, combine parsing with payload decryption:

// Open and parse
payload, err := img4.OpenPayload("kernelcache.im4p")
if err != nil {
    log.Fatal(err)
}

// Decrypt if necessary
if payload.Encrypted {
    decrypted, err := img4.DecryptPayloadBytes(payload.Data, iv, key)
    if err != nil {
        log.Fatal(err)
    }
    os.WriteFile("kernelcache.decrypted", decrypted, 0644)
}

Using the ipsw CLI for Firmware Analysis

The ipsw command-line tool provides convenient access to all parsing and decryption functionality without writing Go code.

Analyzing IMG3 Files

Inspect IMG3 metadata:

ipsw img3 info firmware.img3

Extract and decrypt with raw keys:


# Using concatenated IV+key

ipsw img3 extract firmware.img3 \
    --iv-key 112233445566778899aabbccddeeff0000112233445566778899aabbccddeeff

# Using separate IV and key

ipsw img3 extract firmware.img3 \
    --iv 112233445566778899aabbccddeeff00 \
    --key 00112233445566778899aabbccddeeff

Auto-lookup keys from theapplewiki.com:

ipsw img3 extract firmware.img3 \
    --lookup \
    --lookup-device iPhone14,2 \
    --lookup-build 20H71

Analyzing IMG4 Files

Get human-readable IMG4 information:

ipsw img4 info firmware.img4

Output as JSON for programmatic processing:

ipsw img4 info firmware.img4 --json

Extract and decrypt IM4P payloads:


# With explicit keys

ipsw img4 im4p extract kernelcache.im4p \
    --iv 112233445566778899aabbccddeeff00 \
    --key 00112233445566778899aabbccddeeff \
    --output kernelcache.bin

# With automatic key lookup

ipsw img4 im4p extract kernelcache.im4p \
    --lookup --lookup-device iPhone14,2 --lookup-build 20H71

Summary

  • IMG3 files use a binary tag-based structure with KBAG tags containing encrypted AES keys, while IMG4 files use ASN.1 encoding with separate Payload, Manifest, and RestoreInfo components.
  • The pkg/img3 package provides ParseImg3, DecryptKBag, and DecryptWithGIDKey for parsing and decrypting IMG3 firmware in Go.
  • The pkg/img4 package offers Parse, OpenPayload, and DecryptPayload for handling IMG4 containers and IM4P payload decryption.
  • The ipsw CLI exposes these capabilities through ipsw img3 extract, ipsw img4 info, and ipsw img4 im4p extract, with support for automatic key lookup via --lookup flags.

Frequently Asked Questions

What is the difference between IMG3 and IMG4 firmware formats?

IMG3 is Apple's older binary tag-based format used in earlier iOS devices, consisting of a header followed by sequential tags like TYPE, DATA, and KBAG. IMG4 is the modern replacement using ASN.1 encoding that wraps firmware components in a structured container with separate Payload (IM4P), Manifest, and RestoreInfo sections. Both formats support encryption via KBAG tags, but IMG4 provides more flexible metadata and is used in all modern Apple devices.

How does ipsw handle firmware decryption without manual keys?

The ipsw CLI supports automatic key lookup through the --lookup flag, which queries the public theapplewiki.com database for IV and key pairs based on your specified device identifier and iOS build number. When you run commands like ipsw img3 extract --lookup or ipsw img4 im4p extract --lookup, the tool automatically retrieves the appropriate decryption keys and applies them using the underlying DecryptWithGIDKey or DecryptPayload functions.

Can I use ipsw as a library in my own Go applications?

Yes, ipsw is designed as a modular Go toolkit that you can import into your own projects. The pkg/img3 and pkg/img4 packages provide programmatic access to parsing and decryption functions like ParseImg3, DecryptData, Parse, and DecryptPayloadBytes. You can use these to build custom firmware analysis pipelines, automated decryption services, or specialized security research tools without relying on the CLI interface.

What encryption methods does ipsw support for firmware decryption?

ipsw implements AES-CBC decryption for both IMG3 and IMG4 formats. For IMG3 files, it handles KBAG decryption using either GID keys (device-specific group keys) or raw user-supplied keys via functions like DecryptKBag and DecryptWithGIDKey. For IMG4/IM4P payloads, decryption is handled by DecryptPayload and DecryptPayloadBytes, which apply AES-CBC using the IV and key extracted from the KBAG or provided manually.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →