decrypted Turns Apple’s Own Debugging Tools Into a FairPlay Decryption Pipeline

A Swift UI, a Python engine, and a vulnerable `gcore` entitlement combine to dump decrypted iOS app memory, patch the Mach-O, and make the runtime state permanent.

9 min read • View on GitHub • More from 34306

A MacBook-like laptop sits under a stark white field while a live app window and a sealed file icon are connected by a thin siphon of black ink. The image explains that the tool does not crack FairPlay on disk, it captures the decrypted state while the app is running.
The twist is not brute force. It is capturing the moment an encrypted app becomes readable in memory.
Key Takeaways

The sharp part of decrypted is not that it can strip protection off an iOS app. It is that it does so by standing on a trusted macOS debugging path and waiting for the decrypted state to appear in memory. That shifts the problem from cracking a file to freezing a running process.

The trusted tool is the twist

This is a living-off-the-land exploit in the most literal sense. A system utility that should help developers inspect crashes becomes the mechanism that drains decrypted pages out of a protected app. The binary on disk stays protected until execution starts, which is exactly why runtime capture is the leverage point.

Project typeTarget surfaceMethodOutputTradeoff
decryptedApple Silicon Mac running iOS appsDump live memory with a trusted debug utility, then patch Mach-O metadataA usable decrypted binaryNarrow, sharp, and tied to one exploit window
Classic jailbreak decryptorsA jailbroken iPhoneUse device-side access to pull protected app codeA decrypted IPA or app binaryDepends on a compromised phone
Broad awesome listsReverse-engineering ecosystemCurate links across many tools and topicsA reading list, not a pipelineUseful for breadth, weak on leverage

Apple Silicon moved the target

Apple Silicon changed where the interesting moment happens. With Designed for iPhone and iPad apps running on Mac, the desktop becomes the place where mobile code is actually executing. That matters because the old jailbreak workflow depended on the device itself, while this one turns a Mac into the collection point.

The scene contrasts a cramped jailbroken phone with cables and stress on one side, and a Mac with a calm running app on the other. It explains how the battlefield moved from a compromised handset to a desktop environment where the app still runs under Apple’s own tooling.
The venue changed. The desktop can now host the moment of decryption.

Scan, launch, dump, patch

The pipeline is simple to read and hard to execute cleanly. First the tool scans /Applications for bundles that look like iOS wrappers. Then it checks whether the binary is still encrypted, launches the app, maps its memory, and snapshots the process with gcore. The last step is the most important one: rebuild the Mach-O so the dumped runtime state becomes a durable file.

The key insight is that the tool does not decrypt in the abstract. It harvests a decrypted runtime, then rewrites the file so the result survives after the process exits.

The code paths mirror that sequence. Discovery lives in the scanner, execution lives in the runtime helper, and reconstruction lives in the binary patcher. That separation is what makes the repo feel more like a production pipeline than a one-off script.

decrypted/
  ContentView.swift   -> SwiftUI app browser and progress view
  decryptedApp.swift  -> entry point
  app_scanner.py      -> find .app bundles and iOS wrappers
  decrypt_fairplay.py -> launch, dump, and patch the binary
  setup.py            -> environment and entitlement checks

Swift for the shell, Python for the surgery

The split is practical, not accidental. SwiftUI gives the project a native macOS front end for browsing apps and showing status, while Python does the brittle work where libraries matter more than polish. That is where LIEF and radare2 fit: they are better suited to memory maps, load commands, and Mach-O surgery than a thin UI layer would be.

A workbench is split into two distinct halves, one orderly and Mac-like, the other filled with scripts, pipes, and binary fragments. The image explains the division of labor between a native SwiftUI wrapper and Python-based binary tooling.
The repo keeps the interface clean by pushing the messy part into Python.

The Mach-O patch makes the output durable

The dump is only half the story. A core file is evidence, but it is not yet a reusable binary. The patcher rewrites the Mach-O load commands, flips the encryption state, and swaps the runtime pages back into a file that behaves like the decrypted app the user actually ran. That is the difference between a forensic snapshot and a practical artifact.

A magnified binary slab sits under a loupe while a lock notch is being replaced by an open notch. It explains that the crucial transformation happens at the Mach-O header, where encryption metadata is rewritten so the dumped code can be used again.
The real payoff sits at the file format level, where a runtime snapshot becomes a stable binary.

Specialization beats breadth when leverage matters

Broad reverse-engineering lists are useful, but they are catalogs. decrypted is opinionated. It assumes you want one thing only: FairPlay out of a running app on a Mac that can host the target. That makes it smaller than a general reference repo and more interesting as a technical artifact, because it compresses a whole attack chain into a narrow tool.

That narrowness also explains why the project feels sharp rather than generic. A broad list gives you options. This repo gives you a path, and the path depends on a specific entitlement failure, a specific OS window, and a specific relationship between disk encryption and runtime memory.

This kind of tool ages fast

The README signal matters here. The project is still under development, which fits the shape of the technique itself. Tools like this are most revealing when they sit on top of a fragile assumption in the platform, because that is where the boundary between protection and exposure is easiest to see.

That is why the repo reads as more than a utility. It is a case study in trust misplaced at the system level. Apple’s own tooling is doing the work, the decrypted state already exists, and the only question is whether you can catch it before the process closes.