Reverse Engineering iOS Apps - iOS 11 Edition (Part 1)
Even though there are already many, many blog posts, tutorials and even youtube videos about "reverse engineering iOS apps", every time Apple releases a new iOS version the "game" changes; researchers have to find a new way to jailbreak the new released version of iOS and we have to update our tools to work with the new jailbroken environment. This is especially true for the latest iOS 11 jailbreak, both LiberiOS and Electra jailbreaks, which are based on Ian Beer's async_wake exploit, have very different techniques than the previous jailbreaks and most (all?) of the existing tools are broken on these jailbreaks.
I'm going to focus on LiberiOS for this post since that's the only jailbreak I've tested. But also because I'm a huge fan of Jonathan Levin's work and his contributions to the community. The LiberiOS jailbreak is what's called a KPP-less jailbreak (KPP stands for Kernel Patch Protection). It basically means there are no modifications to the kernel areas that KPP guards, and most of the jailbreak tools (like Clutch, dumpdecrypted) and all of the tweaks that depend on Cydia Substrate haven't been updated to work with this approach.
This post ended up being a bit too long, so I decided to split it in two parts:
- Part 1: Will help you setup your device and decrypt iOS apps
- Part 2: Will help you dump the app's classes, disassemble its instructions and manipulate the runtime to change the app's behaviour
Syllabus
Part 1
- Jailbreak your device (external link)
- Setup
iTunnel - Setup
bfinject - Decrypt Starbucks iOS app using
bfinject decrypt
Part 2
- Dump Starbucks app's Classes using
class-dump - Disassemble the Starbucks app using
Hopper - Runtime manipulation using
bfinject cycript
Jailbreak your device (external link)
To begin RE'ing iOS apps you need a jailbroken device. In this post I'm assuming you are on iOS 11 so let's start with jailbreaking your device. I like the iClarified tutorials and they have a great one for jailbreaking your iPhone/iPod/iPad (iDevice) on iOS 11-11.1.2:
- Follow iClarified's tutorial to jailbreak your iDevice using LiberiOS here.
Now that your iDevice is jailbroken we can start reverse engineering iOS Apps!
Setup iTunnel
Even though LiberiOS' version of Dropbear SSH has wifi connectivity enabled, I find USB faster and more reliable. To SSH into your device via USB using your lighting cable you'll need to setup iTunnel (or a similar tool).
- Download the latest version of
iTunnelfrom here - Extract the contents of the .zip file
- Copy the
itnlbinary to/usr/local/bin - Copy the
libmd.dyliblibrary to/usr/local/lib
You can also leave both files in a folder and execute theitnlcommand with the./prefix.
Setup bfinject
As I said before, many of the existing tools don't work as in previous jailbreaks, but thanks to Bishop Fox we can now use Clutch in LiberiOS by doing the following:
- Create a folder called
bfinjectin your desktop - Download the latest .tar file in the
bfinjectfolder - Run
itnlto forward the ssh traffic to a different port,--lportis the local port and--iportis the iDevice port:
> itnl --lport 2222 --iport 22
- In a different terminal session SSH into the iDevice:
> ssh -p 2222 root@localhost
- Enter the root password, the default password is
alpine(though you should change it)

- To enable the
binpackadd the binaries directories toPATH:
# export PATH=$PATH:/jb/usr/bin:/jb/bin:/jb/sbin:/jb/usr/sbin:/jb/usr/local/bin:/sbin:/usr/sbin:/usr/local/bin:
- Create a
bfinjectfolder in/jband change directory to it:
# mkdir /jb/bfinject && cd /jb/bfinject
- In a different terminal session, copy the .tar file to the device:
> scp -P 2222 bfinject.tar root@localhost:/jb/bfinject
Update: if you get the bash: scp: command not found error, you'll need to execute /jb/makeMeAtHome.sh before being able to use scp. (Thanks @jackmccr for the heads up):
# cd /jb
# ./makeMeAtHome.sh
- Enter the root password and wait for the file to be transfered
- Extract the .tar file contents:
# tar xvf bfinject.tar
- Add the
/jb/bfinjectpath toPATH:
# export PATH=$PATH:/jb/bfinject:
- Optional: you can move or copy the
.dyliblibraries to/usr/local/libto be able to runbfinjectfrom any directory
From now on you can add/jb/bfinjectto the list of binpack paths. For more information aboutbfinjectvisit their GitHub repo.
tl;dr of why we need to decrypt apps first
The app binary of an app downloaded from the App Store is encrypted using Apple's FairPlay DRM to protect the dev's intellectual property and avoid tampering.
Decrypt Starbucks iOS app using bfinject decrypt
- Download the Starbucks app from the App Store
- Run
itnlto forward the ssh traffic to a different port (if you haven't already done so):
> itnl --lport 2222 --iport 22
- In a different terminal session SSH into the iDevice (if you haven't already done so):
> ssh -p 2222 root@localhost
- Enter the root password
- Change directories to
/private/var/containers/Bundle/Application, this is the directory where iOS stores all the apps downloaded from the App Store:
# cd /private/var/containers/Bundle/Application
- Here you'll see a list of UUID folders, iOS generates a random UUID every time you download an app. If you have many applications installed, a quick hack to know which one is the last installed one is to sort the files by date:
# ls -lat

- Change directories to the very first UUID folder, in this case it should be the Starbucks app. You will see something like this:

- Take a note of the name of the
.appbundle, in this case is justStarbucks.appbut other apps might have different names. This name is important becausebfinject decrypttakes it as a parameter and will search for a bundle named exactly as your parameter
Side note
If you change directories to the Starbucks.app, here you'll see all the files included with the Starbucks app bundle. As you can see not a single file is encrypted. When Apple says they encrypt the app, they mean the actual binary not the assets and extra files. (Tip: sometimes you might get lucky and find some server configuration files or secret keys because some devs might not realize we can extract these files). Don't worry about transferring these files to your machine, you'll have access to them once we decrypt the app.
- On your iDevice, open the Starbucks app
- On your terminal type:
# bash bfinject -P Starbucks -L decrypt
If you didn't move/copy the .dylib libraries to /usr/local/lib you will need to change directories to /jb/bfinject and execute the command from there.
- On your device you should see a pop up dialog like the following:

- Optional: Tap on
YESand follow the instructions if you want to transfer the decrypted app usingNetCat - I prefer using
scpto transfer the decrypted app. The decrypted app will be stored in the/Documentsfolder of the original app. The directory for theDatasection of the iOS apps is/private/var/mobile/Containers/Data/Application/. Change directories to theDatasection:
# cd /var/mobile/Containers/Data/Application/
- Again, you'll see a list of UUID folders, you can sort by date again to get the latest modified folder, change directories to that UUID and then to the
Documentsfolder, you should see adecrypted-app.ipafile:

- In a different terminal session transfer the
decrypted-app.ipafile to your machine:
> scp -P 2222 root@localhost:/var/mobile/Containers/Data/Application/{UUID}/Documents/decrypted-app.ipa decrypted-app.ipa
Update: if you get the bash: scp: command not found error, you'll need to execute /jb/makeMeAtHome.sh before being able to use scp. (Thanks @jackmccr for the heads up):
# cd /jb
# ./makeMeAtHome.sh
- Optional: I don't like having files laying around, after transferring the
decrypted-app.ipato my machine, I usually delete it from the device:
# rm /var/mobile/Containers/Data/Application/{UUID}/Documents/decrypted-app.ipa
- On your machine, rename and change the file's extension to
Starbucks.zip:
> mv decrypted-app.ipa Starbucks.zip
- Extract the .zip contents:
> unzip -a Starbucks.zip
- You should get a folder named
Payloadand inside a bundle calledStarbucks.app, right-click on theStarbucks.appbundle and selectShow Package Contents, now you should see all the files contained in the Starbucks bundle, including the decrypted version of theStarbucksbinary, yay!
I know this is a lot of information and instructions, that's why I divided this post in two parts. Try repeat these steps with a few different apps to get familiar with the flow and the tools and next we'll get a sense of how to disassemble and dump the decrypted app's classes.
Note: The reason why I chose the Starbucks app is because they have a bug bounty program on HackerOne and their iOS app is in scope of that program, so if by following this tutorial you manage to find a vulnerability you get to report it to them.