multipart-message nevyn bengtsson's blog

featured articles 🦄, about, archive, tags

Writing your own jailbreak tweak

This article is my raw presentation script from CocoaHeads Stockholm 2014-02. It’s written as if I was talking to an audience, not as a blog article, so it might be a bit weird to read.

Hi! I’m nevyn from Lookback. Whenever Marthin sends panicked emails looking for presenters for next Cocoaheads, I look back through the things I’ve encountered recently looking for something interesting. In other words, I am far from an expert on the upcoming subject, but I find it absolutely fascinating. And the topic is: Jailbreak development. I’m going to try to sneak in a product announcement in here somewhere, so don’t zone out!

What does that even mean? Let’s break it down. Jailbreaking has two parts: There’s a jail, and there’s breaking it. The jail is all the security infrastructure of iOS: a virtual room in which your apps run, and very little bad can happen. This infrastructure includes sandboxing, code signing, NX, ASLR, and so on: a seriously impressive layer-cake of security. All of these pieces work together to make sure that only trusted code can be run on your device—only apps signed by Apple or by you as a developer for your own device—and even if that code is compromised, there is a very limited range of possible consequences; for example, even if you happen to have a buffer overrun vulnerability in your app, a hacker can’t use that bug to install malicious code (like a virus) on your phone.

I could go into details of how all this works, but to allow us to move on, instead I deeply recommend Charlie Miller et al’s iOS Hacker’s Handbook. It’s an excellent guide to both basic security, how to write secure iOS applications, the security infrastructure of both FreeBSD, Mac OS X, and iOS, and how all of those have previously been broken.

That gets us on to the “breaking” in “jailbreaking”. What does “breaking” mean in this context, anyway? Jailbreaking means finding operating system bugs that allow you to expose vulnerabilities by writing exploits to disable every single one of the defenses put in place.

For example, the iOS 7 jailbreak “evasi0n” works like this:

  1. The WWDC 2012 app has code signing that allows it to run anywhere forever. However, it’s still just a normal app within a sandbox, so it can’t make changes to the operating system.
  2. A bug in the way the app installer handles symbolic links allows us to run iOS’s file server instead (used to make backups, normally).
  3. A bug in the dynamic linker allows a flag to completely disable the sandbox. However, we’re still running as the user, not as root, so we can only modify the user’s apps and documents, not the operating system.
  4. A bug in the way the file server handles symbolic links gives us raw access to the harddrive.
  5. And at this point, we can write whatever we want to the disk. The sandbox is completely disabled, allowing us to run any software we want.

This should be scary. This means that on a jailbroken device, a mail attachment could contain a virus, and all the gatekeepers would be asleep: the virus could execute, and it could infect your phone and spread it to all your contacts. Just like on a normal computer.

…

and that’s sort of the point. You own your iPhone. It’s a computer, just like any other. You shouldn’t have to pay Apple *additional* money just to be able to install whatever software you want on it.

And I really mean *whatever* software. On a Mac you can also whatever you want, but there never really sprung up a big community of modders. There was CandyBar, Audio Hijack and a few others.

But on iOS, every jailbreak comes with Cydia, and a whole lot of infrastructure written by Saurik and other awesome hackers. Every piece of the system has a category of modifications on his store. Saurik likes calling “remixing software”, which I think is a great term.

How would one get started with jailbreak development, with remixing software?

Large parts of the jailbreak community is based on the idea that you shouldn’t need a Mac to do development, so they’re based on Makefiles and other traditional Unix development tools. Me, I prefer my GUIs. If you’re like me, you’ll appreciate iOS Open Dev, which is an Xcode plugin package with awesome templates to help you get started. One might think it’s just a bunch of unmaintained scripts (as is often the case with obscure dev communities), but I’ve found it to be very well put together.

After installation, iosopendev might not work right off the bat. If it doesn’t, you might to tell it to use the latest iOS SDK:

iod-setup sdk -d /Applications/Xcode.app/Contents/Developer -sdk iphoneos

Restarting Xcode and making a new project now gives a ton of new options. They’re all based on the idea that you want to put code into other people’s apps. Some interesting ones are:

  • Action Menu Plugin. Always wanted to be able to select text and have an option to make it sparkle? Well, why don’t you build it!
  • Tweak. A tweak is a plugin that is loaded into apps that aren’t supposed to have plugins. You can make a tweak that loads into every single app, or just into Springboard, which is the app that launches apps and does all the other iOS-y stuff. This is the most interesting one, so I’ll get into more detail on it later.
  • Activator Listener. A crazy infrastructure which lets you bind any action to any handler. For example, if you make, I dunno, a tweak that lets you record the screen of any app, you might want to add an Activator to it so that the end user can choose which action should start the recording. And it could be ANY action. This is just a small sample. When locking the phone. When triple-tapping the lock button. When inverse five-finger swiping the screen. When dragging in with two fingers from top-right of the screen. You get the point.
  • Library. Hey look, you can actually make dynamic libraries on iOS!
  • Tool. And command line tools! It’s as if this is some kind of UNIX operating system!
  • You can make your own Notification Center widget, just like Weather and Stocks.
  • Toggles. Before Control Center in iOS 7, jailbreakers enjoyed the same features (and many more) using SBSettings toggles. You can make your own.
  • XPC Service! Now this is even starting to look like Mac OS X! How odd.

Ok, so before we jump into live coding, I’d like a volunteer app. If you have an app on the AppStore and want to be horrified, yell the app name out loud!

While that’s downloading, let’s make a tweak. Primarily, a tweak is a uniform way of injecting code into apps using a library called Cydia Substrate. It will let you specify which apps you want to inject in, for example by checking for the existence of a class. This filter here will inject into any app that has the hypothetical class SpotifyViewController in it. You can also say “only inject into SpringBoard”, or “into any UIKit app”, or something else.

Once inside the target app, what can you do?

Well, a tweak is also method swizzling made into an art form. To make it really, really easy to swizzle stuff. two optional frameworks have emerged.

Logos is the oldest one, and it is a bit crazy. It’s a custom preprocessor on top of Objective-C with the extension “.x”. You tell it which class you want to swizzle, implement your replacement, and then you can optionally call the original implementation with %orig. It has support for many other things, but I think I’ll leave it at that.

The alternative is CaptainHook, which uses C++ template classes and macros to accomplish the same thing. It’s not less crazy. Here we are logging every call to [NSString writeToFile:], and then calling the original implementation.

So let’s write a very simple tweak. It’ll create a class called “ListClasses” when the app starts, using +load. We’ll wait for the app to finish launching properly before we do anything. At that point, we’ll add a button to the window after a second, to let the UI settle. It’s going to present a custom view controller on top of the app.

This’ll be a table view controller. We will list ALL classes available to the app, and get their names. Then we’ll just list those in a table view. Build and run, aaand… Let’s have a look inside the audience app.

So, these are real class names, and I could instantiate any one of them if I wanted, and call any method I wanted on them.

Class names aren’t quite enough to know what to swizzle though: we want method names, and preferrably, even headers. Luckilly, or unfortunately if you want to keep secrets, Objective-C is very verbose in what kind of information is available at runtime, since it’s such a dynamic language. There’s a tool called class-dump that will take an app or a library, and output headers, much like this. However, all app-store apps are encrypted and aren’t easily class-dumped. First, they must be cracked using a tool using “Clutch”. This is also the same way that apps are pirated, so please don’t do that :(

Let’s do a classdump of the audience app. I will SSH into my phone, as if it was a regular UNIX computer o_O

This is a good time to mention that development on device is going to be very painful if you don’t enable SSH. SSH lets you get a command line shell right into your phone. However, you should change the password immediately after installation, since all iPhones have the same default password: alpine. You’ll also want to add a ssh key to your phone, so that iosopendev can install tweaks onto your phone directly from Xcode. If you add your phone’s IP address to your .bash_profile file, you can press command-shift-I to install tweaks.

You will probably also want the tool deviceconsole, which is like Xcode organizer’s console log, except as a terminal app which means it’s searchable, fast, and just generally awesome in every way that Xcode isn’t.

There’s so much more to talk about. How to publish your creation, how to debug, how to write activators, and much more. However, my time is up so talk to me afterwards if you want to know more.

I’d like to finish off with the tool I built that made me learn all this. You probably saw my previous presentation on Lookback, so now I’d like to show you Lookback Anywhere. Lookback Anywhere is very simple: I’ve taken the Lookback SDK, linked it into a tweak, and added two activator actions. That means Lookback is loaded into every app on your phone, and you can record them without having to install the SDK. The same concept could be applied to any developer tool: Reveal, PonyDebugger, Spark Inspector and others could be installed into any app very easily.

So I’d like to show you here how I can record in this audience app… And voila, it’s uploaded to lookback.io.

Lookback Anywhere is not ready for release, but you can install a beta on your phone by adding a custom source in Cydia.

Tagged ios, iphonedev, iosdev, flattr, faves