halis duraki/
- 0xduraki
See Decrypt IPA from AppStore notes for details, or use dumpdecrypt
.
Downloading IPA from the AppStore is possible on macOS as well, thanks to the majd/ipatool. The process of decrypting these binaries is explained under separate note - decrypt IPA from AppStore (macOS) but the results are not tested.
To run IPAs on Mac with M1 support (Apple Silicon), you can try PlayCover. Additionally, you may download XCode simulator using speedwagon
and use it in combination with simforge allowing you to run decrypted iOS apps on iOS Simulators. There is also simject which allows for iOS dynamic library injection (ie. tweak injection) in the iOS Simulators.
ipatool
on macOSThe ipatool
is an open-source utility developed by majd which allows users to download IPA files directly from the AppStore.
Important Errata
ipatool
via brew
won’t work. There is another ipatool
binary provided by XCode which might be confirmed using the command which ipatool
. Instead, it’s recommended to visit Releases section of the GitHub repository, and downloading latest release builds for the ipatool
.Building ipatool
from GitHub Repository
This is a proven way to use latest updates of the ipatool
, since the Releases version have long been outdated, although the new updates and commmits exists.
To build ipatool
, clone the repository first, build it, and then follow the next instructions. Ofcourse, make sure to have GoLang toolchain installed on your HostOS to be able to compile the codebase.
$ cd ~/utils/clone
$ git clone git@github.com:majd/ipatool.git
$ cd ipatool
$ go build -o ipatool-dl
# go: downloading github.com/juju/persistent-cookiejar v1.0.0
# go: downloading github.com/avast/retry-go v3.0.0+incompatible
# go: downloading github.com/99designs/keyring v1.2.1
$ file ipatool-dl
# ipatool-dl: Mach-O 64-bit executable arm64
Installing the ipatool
to $PATH
-registered directory
Lets move this ipatool
binary to any directory, preferably to that which is inside your $PATH
environment variable. On my macOS M1, I have ~/.config/bin/
directory configured and set in $PATH
so I will move the newly built ipatool-dl
to it:
$ cp ipatool-dl ~/.config/bin/ipatool-dl
$ chmod +x ~/.config/bin/ipatool-dl
Note that I’ve copied ipatool-dl
binary in one of my $PATH
directory - this is important since I already have XCode’s ipatool
in my executable paths. Using the chmod +x
we’ve set the binary flag as executable, making sure it can be executed.
Login to AppleID via ipatool
The ipatool
from majd requires an AppleID account, and we must sign-in using the ipatool auth login
command:
$ ipatool-dl auth login -e user@example.com
# 12:52PM INF enter password: <password>
# 12:52PM INF enter 2FA code: XXXXXX
# 12:52PM INF email= name=" " success=true
With that, we are logged in to AppStore and the ipatool
appends the authentication item in the Keychain Access app. Use the ipatool auth info
comamnd to show information about current account:
$ ipatool-dl auth info
# 3:01PM INF email=<user@example.com> name="<Full Name>" success=true
Using the ipatool
to Search in AppStore
If we try to use ipatool search
command which expects a search string argument, it should show list of apps that have been found in the AppStore for the given name:
$ ipatool-dl search "SMS Forwarder"
# 12:57PM INF apps=[{"bundleID":"tsubasa-technologies.Forward-OTP","id":6693285061,"name":"SMS Forwarder: Forward SMS","price":0,"version":"1.8.4"}] ... count=1
It’s also possible to combine the --format json
option with tools such is jq
, showing the list of apps more clearly, like so:;
$ ipatool-dl search "SMS Forwarder" --format json | jq # format output to JSON and pipe to 'jq'
# {
# "level": "info",
# "count": 5,
# "apps": [
# {
# "id": 6738728448,
# "bundleID": "com.blw.DemoIntents1",
# "name": "SMS Forwarder!",
# "version": "1.1",
# "price": 0
# },
# // ...
# ],
# "time": "2025-01-20T15:05:00+01:00"
# }
$ ipatool-dl search "SMS Forwarder" --format json | jq '.apps[].bundleID' # output only bundleID from the array
# "studio.panikka.ForwardSMS"
# ...
$ ipatool-dl search "SMS Forwarder" --format json | jq -r '.apps[].bundleID' # using '-r' to output without quotes
# studio.panikka.ForwardSMS
# ...
Downloading (encrypted) IPA via ipatool
from AppStore
There is a bug when downloading IPA
from the AppStore which doesn’t properly purchase the application license first, resulting in an error, even if the application is free to download. This happens if the IPA you are trying to download did not ‘purchase license’ first, and due to the bug in ipatool purchase
command, the flow is broken.
Lets take a look at the following example, which shows the Moonshot app. for iPhone in the AppStore.
Helpful Tip
If we try to use ipatool
to search and download this app. it will result in unexpected error, as shown below:
# First we need to search for the app. by it's name
$ ipatool-dl search "Moonshot" --format json | jq '.apps'
# [
# {
# "id": 6503993131,
# "bundleID": "money.moonshot.app",
# "name": "Moonshot",
# "version": "1.4.5",
# "price": 0
# },
# // ...
# ]
# Lets try to download the app.
$ ipatool-dl download -b "money.moonshot.app" --purchase
# downloading 0% | | ( 0/ 1 B)
# 3:30PM ERR error="failed to purchase item with param 'STDQ': failed to purchase app" success=false
As you can see, the purchase of the application license failed due to the bug in ipatool
. You may append --verbose
argument to the ipatool download
command which will spit more information on why it failed.
To workaround this bug, we must first initiate the purchase from the AppStore itself using the Get button, indicated by the #1 in screenshot below.
Click the Get button only once, which will then change itself to Install button.
Now click the Install button once it’s shown authenticate to AppStore via TouchID as requested, ie. when you receive the following modal window popup:
Once the application is installed on your macOS, move back to Terminal and execute the ipatool download
command again as shown in previous example:
$ ipatool-dl download -b money.moonshot.app --purchase
# 3:44PM INF output=money.moonshot.app_6503993131_1.4.5.ipa success=true
The IPA should now be downloaded correctly in current working directory. It’s also possible to pass an output directory argument using -o
which indicates where the *.ipa
should be downloaded to; and similarly, the -i
(AppStore - App ID) argument can be used instead of -b
(AppStore - App Bundle Identifier):
# This would download *.ipa to /tmp/ directory, using the AppID instead of BundleID
# Note that the downloaded IPA has filename "[ID].ipa" making it harder to identify.
$ ipatool-dl dowload -i 6503993131 -o /tmp/
# 4:43PM INF output=/tmp//6503993131.ipa success=true
Once the IPA has been downloaded, use a free tools such is AppCleaner to remove the installed application from the macOS. There is a CLI alternative to do the same called unistall-cli.sh which can be installed using:
$ wget -O$HOME/.config/bin/uninstall-app https://gist.githubusercontent.com/duraki/9dd16becf7676b352ca68eb84dcedfaa/raw/bbd54927adf5f00ee0c6feec7816520dec75b193/uninstall-app.sh
$ chmod +x ~/.config/bin/uninstall-app
# To use it, simply run
$ uninstall-app /Applications/AppName.app
fnd.io
duraki notes
* [Download IPA on MacOS](/download-ipa-on-macos)
Decrypt IPA from AppStore
Requires iproxy and frida-ios-dump. File will be generated in current directory with *.ipa extension. See download IPA on macOS note on how to download and prepare IPA if you don’t have a jailbroken iPhone device. It might be possible to downgrade apps from AppStore without jailbroken device using Charles Proxy.