blacktop/ipsw: a Go CLI for pulling apart Apple firmware
iOS/macOS Research Swiss Army Knife
At a glance
- What is it?
- The ipsw command line tool downloads, extracts and inspects IPSW and OTA images, Mach-O binaries and the dyld shared cache. It is aimed at security researchers and jailbreak developers, and it assumes you already know what you are looking for.
- Who is it for?
- Adopt ipsw if you already work with Apple firmware and want one Go binary that covers download, extraction, Mach-O parsing, dyld cache analysis and device interaction, with a documented Homebrew, Snap or Scoop install path. Do not adopt it if you need a supported, versioned library API or a GUI: the release line is v3.1.x with frequent patch bumps, the sandbox package is closed source, and the README documents no rollback procedure.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 1 day ago.
- What is it written in?
- Mainly Go, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What blacktop/ipsw is for, and who it is not for
Apple ships firmware as IPSW and OTA archives that bundle a kernelcache, a dyld shared cache, iBoot, SEP firmware and hundreds of Mach-O binaries. Reading any of that normally means assembling a chain of separate tools. blacktop/ipsw collapses that chain into a single Go binary. The README describes it as a "comprehensive command-line research framework for iOS and macOS" and lists its audience explicitly: security researchers, reverse engineers, jailbreak developers and iOS enthusiasts.
The scope is wide on purpose. The same executable downloads firmware from Apple, AppleDB, the Developer Portal, RSS feeds, GitHub, iTunes and Wikipedia; extracts and diffs images; parses Mach-O and disassembles ARM; walks the dyld shared cache; parses IMG4, iBoot and SEP; talks to a connected device over AFC, backup and syslog; and drives the App Store Connect API. If you only need to unpack one IPSW, most of that surface is irrelevant to you. If you spend your week moving between those tasks, the single entry point is the point.
The repository is not archived and the last push was on 2026-09-22, so the codebase is moving. That cuts both ways: recent releases are frequent (v3.1.723 on 2026-09-19, v3.1.722 on 2026-09-17), and a prerelease tag appeared on 2026-09-22. Frequent patch releases on a v3.1.x line mean you should pin a version rather than track latest.
How the CLI, the daemon and the package tree fit together
The README states that ipsw consists of two main components: the ipsw CLI, which carries the analysis capabilities, and ipswd, a REST API daemon for remote operations and automation. The repository layout matches that split: cmd/ holds the command entry points, pkg/ holds the reusable packages, api/ holds the daemon surface, and internal/ holds code not meant for import. A Dockerfile builds the CLI, and a separate Dockerfile.daemon builds the daemon.
The dependency list in go.mod is the clearest statement of how the analysis actually works. Mach-O parsing comes from github.com/blacktop/go-macho, DWARF from go-dwarf, APFS from go-apfs, compression from lzfse-cgo and lzss, ARM64 disassembly from arm64-cgo, and Frida integration from frida-go. The tool is largely a command surface over a set of Blacktop-maintained Go libraries, which is why cgo is enabled in the Docker build (CGO_ENABLED=1) and why the image also compiles apfs-fuse from source and sets LD_LIBRARY_PATH. That is a real constraint: the Docker image is not a minimal static binary, it carries FUSE and a C toolchain's output.
Configuration follows the usual pattern. The README says ipsw supports YAML configuration files and environment variables, with ~/.config/ipsw/config.yaml as the location and config.example.yml in the repository as the starting point. Storage defaults to SQLite and can be switched to PostgreSQL.
Installing ipsw and running a first download
The README gives a platform-specific install for each of the three desktop systems. On macOS there are two Homebrew routes, one of which the README notes "includes extras":
brew install blacktop/tap/ipswbrew install ipswLinux users install through Snap, and Windows users add a Scoop bucket first:
sudo snap install ipswscoop bucket add blacktop https://github.com/blacktop/scoop-bucket.git
scoop install blacktop/ipswOnce the binary is on your PATH, the README's first example fetches the newest firmware for a specific device model. The device string is the Apple model identifier, not the marketing name:
ipsw download ipsw --device iPhone16,1 --latestExpect a large file and a progress display; the README shows no resume flag, so treat an interrupted download as a restart. From there the two operations most people reach for next are extraction and comparison. The README's extract example pulls the kernelcache out of a named IPSW, and the diff example compares two builds side by side:
ipsw extract --kernel iPhone16,1_18.2_22C150_Restore.ipsw
ipsw diff iPhone16,1_18.1_22B83_Restore.ipsw iPhone16,1_18.2_22C150_Restore.ipswThe output of the diff is a per-component comparison rather than a single checksum, which is what makes it useful for tracking what changed between two OS builds. If you would rather run the CLI in a container, the repository ships a Dockerfile whose entrypoint is /bin/ipsw and whose default command is --help.
dyld shared cache and Mach-O analysis in practice
The dyld shared cache is where the interesting private frameworks live, and it is the part of the toolkit with the most subcommands. The README documents three: info for the cache structure, extract for pulling out a single dylib, and objc class for inspecting a class. The extract example names Foundation, and the class example names NSString:
ipsw dyld info /path/to/dyld_shared_cache_arm64
ipsw dyld extract /path/to/dyld_shared_cache --dylib Foundation
ipsw dyld objc class /path/to/dyld_shared_cache --class NSStringThe README labels Swift class dumping and analysis as experimental, while ObjC class dumps and protocol parsing are listed without that caveat. Take the distinction seriously: if your work depends on Swift metadata, you are on the less settled path.
Mach-O handling is the other half. The README shows info, disass and search, with search taking a --string argument. Disassembly targets ARM v9-a and can be routed through an AI decompiler that the README says integrates with Claude, OpenAI, Gemini, Ollama and OpenRouter. The documented invocation passes --entry and --dec with a model name, and the README's own transcript shows the tool loading a symbol cache and printing Objective-C output. That is a documented example, not a guarantee about output quality, and it means your binary content leaves your machine when you use a hosted model. For firmware work under NDA or in an air-gapped lab, that is a disqualifying default unless you point it at a local Ollama instance.
Where ipsw stops being the right tool
The Makefile is unusually candid about one boundary. Several targets (snapshot, dry_release, release, release-minor, docs) are gated behind a _require-sandbox check that fails with the message that pkg/sandbox/ is closed-source and not present in public clones. Public users are told to use make build or go build ./cmd/ipsw instead. So the release pipeline the maintainer uses is not reproducible from the public repository, and anyone hoping to fork and cut their own signed release inherits that gap.
The second boundary is platform. The Dockerfile is based on Ubuntu and builds apfs-fuse from source, so the container path is Linux-only and comparatively heavy. Device interaction through ipsw idev, backup, syslog and developer image mounting assumes a physically attached device and the relevant host services; that is not something a container on a build server gives you for free.
The third is the release cadence. With patch releases landing every couple of days on a v3.1.x line, and a prerelease tag on 2026-09-22, the CLI surface is a moving target. The README does not document a rollback procedure or a stability policy for the subcommands, so if you script against ipsw, pin an exact version and read the release notes before bumping. Finally, this is a research tool: nothing in the README promises support windows or backwards compatibility for output formats.
How ipsw differs from LiEF and similar parsers
The closest comparison is LiEF, the binary parsing library used widely for Mach-O, ELF and PE work. The difference is in shape rather than in parsing ability. LiEF is a library with bindings for Python, C++ and Rust, and you write code to walk a binary; ipsw is a CLI whose subcommands already encode the workflows, and its Go packages are importable but documented as an application, not as a stable API. If you need to embed Mach-O parsing in a Python pipeline, LiEF is the shorter path. If you need to answer "what changed in the kernelcache between these two builds" from a shell, ipsw already has the subcommand.
A second difference is scope. LiEF parses formats; it does not download firmware, mount APFS images, decrypt AEA archives, dump a dyld shared cache, or talk to a device over AFC. ipsw does all of those, which is why its dependency graph includes go-apfs, lzfse-cgo, frida-go and the App Store Connect client. That breadth is also the cost: cgo, FUSE and a large dependency tree make it harder to cross-compile than a pure parser.
For pure dyld cache work, dedicated dumpers exist and are often the community default for ObjC class extraction. ipsw's advantage there is that the same binary also parses the kernelcache and IMG4 files, so you are not stitching three tools together for one investigation.
Licence, maintenance and what an upgrade costs you
ipsw is MIT licensed, and the LICENSE file sits at the repository root. MIT is permissive: you can use, modify and redistribute the code, including in closed products, provided the copyright notice and permission notice are preserved. That applies to the ipsw code itself. It does not automatically cover the third-party components compiled into the binary, and the Dockerfile pulls apfs-fuse from its own upstream repository and builds it from source, so that component carries whatever terms its own project uses. Check the licences of the bundled dependencies before shipping a redistributed binary; this is a description of what the repository contains, not legal advice.
On maintenance, the observable facts are these: the repository is not archived, the last push was on 2026-09-22, and releases v3.1.722 and v3.1.723 landed on 2026-09-17 and 2026-09-19, with a prerelease tagged on 2026-09-22. That is a fast cadence, and it is the main upgrade cost. Every bump on a v3.1.x line can change subcommand behaviour, and the README documents no deprecation policy or migration guide. The practical approach is to pin the version you install (for Homebrew, an exact formula version rather than the tap head), keep the IPSW files you extracted against, and re-run your diff after upgrading if output formats matter to downstream tooling. The Makefile's closed-source sandbox package also means you cannot reproduce the maintainer's release artifacts from a public clone, so treat official releases as the only supported binaries.
Editorial conclusion
Adopt ipsw if you already work with Apple firmware and want one Go binary that covers download, extraction, Mach-O parsing, dyld cache analysis and device interaction, with a documented Homebrew, Snap or Scoop install path. Do not adopt it if you need a supported, versioned library API or a GUI: the release line is v3.1.x with frequent patch bumps, the sandbox package is closed source, and the README documents no rollback procedure. Before you commit, run ipsw download ipsw --device iPhone16,1 --latest once and confirm the resulting file matches the build you expected, then check whether ipswd is the component you actually need.
Frequently asked questions
What does IPSW stand for in blacktop/ipsw?
The project name comes from the IPSW firmware file format that Apple ships for iOS devices, which is the primary input the tool downloads and analyzes. The README describes ipsw as a command-line research framework for iOS and macOS rather than an expansion of the acronym.
How can I open an IPSW file with ipsw?
The README's quick start shows ipsw extract with a component flag, for example ipsw extract --kernel followed by the IPSW filename, which pulls the kernelcache out of the image. The same tool also offers diff and metadata analysis over the extracted contents.
Is blacktop/ipsw trustworthy to run on my machine?
The README contains no security audit or trust assessment, so that question cannot be answered from the project's own documentation. What is documented is an MIT licence, a SECURITY.md file at the repository root, and installs distributed through Homebrew, Snap and Scoop.
How do I download an IPSW with blacktop/ipsw?
Run ipsw download ipsw with a device identifier and the --latest flag, as in ipsw download ipsw --device iPhone16,1 --latest. The README lists Apple, AppleDB, the Developer Portal, RSS feeds, GitHub, iTunes and Wikipedia as download sources.
Does blacktop/ipsw work on Windows and Linux?
Yes. The README gives a Snap install for Linux and a Scoop bucket install for Windows, alongside two Homebrew options for macOS. The provided Dockerfile builds a Linux image with apfs-fuse compiled from source.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/blacktop-ipsw)