About a month ago, I stumbled into the fascinating world of reverse engineering, and it felt like discovering a hidden treasure chest of possibilities! I had no idea that starting with something as straightforward as an app on a jailbroken device could unlock an entirely new realm of creativity and experimentation.
I decided to put my old iPhone 6 to good use and dove into this adventure. My first project was a simple app featuring a UITextField and a UIButton where the user guesses a code. If they get it right, they see a success popup; if not, they get a retry popup. It was a basic setup, but it was perfect for my exploration.
Through reverse engineering, I was eager to see how much I could tinker with this simple app. I ended up tweaking the pin logic and replaced the usual messages with a playful “Hello World” popup. It was amazing to see how even a small change could have such impact!
Step 1: Jailbreak Your iOS Device and Set Up SSH, SFTP
Alright, first things first: jailbreak your iPhone. I won’t get into the nitty-gritty of how to do this — there are tons of guides and videos out there. For my adventure, I used an iPhone running iOS 12 and the unc0ver jailbreak. Once that’s done, fire up Cydia and find openssh to install.
Step 2: Upload Your App and Unzip It
Now that your phone is all set up, it’s time to get your app on there. Use SFTP to sneak the app file into your iPhone’s /Applications directory. This file is a “.ipa” — think of it as a fancy, zipped-up gift. Unzip it right on your phone. You can download the source code and compile the ipa.
Step 3: Hook the App with Cycript
Time for the grand finale: hooking up your app with Cycript. SSH into your device, and make sure your “AnalysisDemoApp” is strutting its stuff in the foreground (no snoozing in the background, please!). Use the UIApp command to locate the app’s main character, a.k.a. the rootViewController.
Spoiler alert: the star’s name is ViewController.
Step 4: Get Your Debugging Tools Ready with Debugserver and LLDB
Now it’s time to bring in our trusty debugging sidekicks: debugserver and LLDB. First, you’ll need to install “debugserver” via SSH or Cydia. Think of this as setting up your debugging toolkit. Once that’s done, you’ll use LLDB to connect to your app’s process remotely. It’s like giving your app a little virtual check-up from afar.
Once you’re connected, run commands like `[[UIWindow keyWindow] recursiveDescription]` to peek at the app’s inner workings. This command will show you a hierarchy of elements, and if you spot an outer UIView, it’s probably a UIViewController in disguise. Using Cycript, we confirmed that the UIViewController is indeed named “ViewController.” Running the `nextResponder` command gave us the address of the VC, which turned out to be 0x100d08590. It’s like finding the secret location of the control room!
I ran another command, `po [0x100d08590 _methodDescription]`, which lists all the methods at a given address. To keep things tidy, I exported this list to a text file by giving session save output command. Scanning through the output, I spotted a method named `buttonTapped` — it looked like the one connected to the button action.
Examining also the app with Hopper it revealed that when `buttonTapped` is called, it runs some straightforward logic and then shows a popup.
The plan is to build a framework and use method swizzling to modify the `buttonTapped` method. This will let us inject our own code and replace the original functionality. For this example, the new behaviour will just pop up a cheerful “Hello World” message.
Here’s the final outcome: After compiling the framework and performing method swizzling on the `buttonTapped` method, I successfully integrated the modified framework into the existing IPA using Sideloadly.
As a result, the app now displays a “Hello World” popup instead of its original functionality. This experiment demonstrated how reverse engineering and code injection can be used to alter app behaviour, offering a clear example of the potential for app modification on iOS devices.