iOS App SideLoading
Sideloading refers to the process of installing an app on a device from sources other than the official app store. While the official app store is the primary source for downloading and updating apps on an iOS device, sideloading can be a useful option for installing apps that aren't available on the app store or for testing and debugging apps during the development process. In this blog post, we will explore the various methods for sideloading applications on iOS and discuss the pros and cons of using this approach.
Note that for sideloading, iOS and iPadOS are equivalent. The minimum version required is iOS 14. We will be using SideStore, “an iOS application that allows you to sideload apps onto your iOS device with just your Apple ID”.
Pairing (and binary patching)
A pairing file must be supplied to SideStore to work correctly. It can be obtained using the jitterbugpair
executable from
I had one of the required libraries (libplist.so.3
) installed under a different name (/usr/lib/libplist-2.0.so.4
) which caused the error
./jitterbugpair: error while loading shared libraries: libplist.so.3: cannot open shared object file: No such file or directory
Indeed, checking with ldd
, the library libplist.so.3
is not found:
$ ldd ./jitterbugpair
linux-vdso.so.1 (0x00007fffb9cda000)
libplist.so.3 => not found
libp11-kit.so.0 => /usr/lib/libp11-kit.so.0 (0x00007f8c06600000)
libpthread.so.0 => /usr/lib/libpthread.so.0 (0x00007f8c065fb000)
libc.so.6 => /usr/lib/libc.so.6 (0x00007f8c06019000)
libffi.so.8 => /usr/lib/libffi.so.8 (0x00007f8c065f0000)
libdl.so.2 => /usr/lib/libdl.so.2 (0x00007f8c065e9000)
/lib64/ld-linux-x86-64.so.2 => /usr/lib64/ld-linux-x86-64.so.2 (0x00007f8c06767000)
While this can be fixed by compiling ldd
from scratch or by renaming my library file, I just patched the executable with patchelf
to statically link my own version of the library:
patchelf --replace-needed libplist.so.3 /usr/lib/libplist-2.0.so.4 ./jitterbugpair
Checking again with ldd
, it now shows /usr/lib/libplist-2.0.so.4 (0x00007f5d5d35c000)
instead of libplist.so.3 => not found
.
Now connect the device to PC and, after trusting it in iOS, run jitterbugpair
which should generate the pairing file:
$ ./jitterbugpair
SUCCESS: wrote to 00001234-XXXXXXXXXXXXXXXX.mobiledevicepairing
Copy to the device.
SideStore
17.0.3
. The following method works instead.Install SideStore on the device via AltStore (for MacOs or Windows) or AltServer (for Linux) from the PC by directly sideloading the SideStore.ipa
file available on the GitHub repo. Download also SideStore.conf
, it's needed later.
When using AltStore to install SideStore, a (developer) Apple Account is needed. It doesn't have to be the same one that is logged in on the device. For example, to avoid conflicts I use two different Apple accounts for the iPad and the iPhone.
Optionally you can change the default Anisette server. It's an advanced option and it's not needed in most of the cases. I used to host my own server but now I use the default one. Once installed, set up your anisette server as described here (to directly run the docker container look here). Then change the Anisette URL
option (in the device settings) of SideStore to your own URL. You can use public servers but the risk of account banning and constant malfunction is not worth it. Some public servers are https://armconverter.com/anisette/irGb3Quww8zrhgqnzmrx
or https://anisette.jawshoeadan.me/
.
SideStore uses a specially designed VPN in order to trick iOS into installing self-signed apps: install WireGuard from AppStore, import the SideStore's VPN configuration preciously downloaded (SideStore.conf
) and activate it.
When opening SideStore for the first time, the app will ask for the pairing file. Select the file previously obtained with jitterbugpair
. Go back to SideStore and login with the Apple Account you previously used to install SideStore. When connected to the VPN, SideStore will periodically "refresh" your apps in the background to keep their normal 7-day development period from expiring.
MacDirtyCow
With a recent exploit, called MacDirtyCow (MDC), it's possible to remove the 3-app limit. MacDirtyCow requires iOS 14.0-16.1.2 (excluding 15.7.2). You are still limited to 10 App IDs at a time (a single app can have multiple App IDs, but it's usually one or two). Also note that App IDs are not instantly removed when you uninstall (or deactivate) a sideloaded app, but they automatically expire after 7 days. So if you are tying out several apps in a short time you may hit the 10 App IDs limit and have to wait that some of them expire. At the time of writing a custom SideStore build that implement the exploit is required. This build includes also an update of the Anisette protocol to V3, so a custom Anisette URL
option is required: http://ani.sidestore.io:6969/
. To execute the exploit (required each boot) follow this guide, but in short sideload this app, open it and click go.
Once the exploit has been run, you should be able to sideload more than 3 app via SideStore (at this point, two spots are required by SideStore itself and the MDC exploit, but since Cowbunga contains the exploit runner you can replace the previously installed app with it and enjoy the additional features of Cowbunga).
TrollStore
TrollStore is a tool which uses a codesign bypass as well as another exploit in order to permanently sign any app with any entitlements which are necessary for the apps functioning. This means that an unlimited number of unsigned apps can be installed and do not need to be refreshed. Check the link above to see the supported iOS/iPadOS version. In my case, to install it on my arm64e
iPad running iPadOS 15.6
I used the TrollHelperOTA method.
Some apps have version that are specific to TrollStore (e.g. UTM with the specific version UTM-HV).
Profit
To sideload an app head over SideStore's "My Apps" tab, click on the "+" on the top left and select the .ipa
file. Remember that for non developer account (if not using TrollStore), a maximum of 3 signed apps can be installed at the same time, including SideStore. Below you can find some interesting application.
Errors
Possible errors that I encountered and how I resolved them.
If SideStore can't connect to the VPN, turn off the VPN in WireGuard and close both apps. Then, in this order, start SideStore, start WireGuard and enable the VPN. After a short time in the peer section of WireGuard you should see the time of the Latest Handshake.
Recreate the pairing file:
Resources
Additional sites and tools that may be useful.