Injecting code in a process with Cycript
In this article, I’m going to show you how to inject code in running process on an iOS device using Cycript. In this example, I injected code into viewWillAppear:
function, so that every time a view controller receives viewWillAppear: message, it displays an alert view with its name and address. Although I used Music app as an example, this just works for any application available in the App Store.
For this entire article I used a jailbroken iPhone 5 with iOS 8.1 and a MacBookPro with macOS 10.11.6.
Cycript is a tool developed by Jay Freeman (saurik), who also created Cydia, which allows developers to explore and modify running application. Cycript allows you to perform “Method Swizzling” on a running process, which mean you can inject your code in a running process. (How cool is that?)
SSH into iPhone #
If you haven’t, download “OpenSSH” by Jay Freeman (saurik) from Cydia.
First, connect a Mac and a jailbroken iPhone in a same Wi-Fi network.
Type following in the Terminal app (Mac). You can find iPhone’s IP address from Settings > Wi-Fi > (i) next to the currently connected network name.
ssh root@<ip_address>
Type “yes” to following message:
The authenticity of host 'xx.x.x.x (xx.x.x.x)' can't be established.
RSA key fingerprint is SHA256:xxxxx.
Are you sure you want to continue connecting (yes/no)?
Type “alpine” for the password if you haven’t changed.
As noted in the OpenSSH description, you want to change the password as soon as possible.
root@xx.x.x.x's password:
If you see following, you are logged in.
iPhone:~ root#
Install Cycript #
You can download Cycript from Cydia, or you can also download Cycript SDK from http://www.cycript.org/ and manually install it.
Inject Cycript to a process #
In this example, I’m going use pre-installed Music app.
Launch Music app and type following.
iPhone:~ root# cycript -p Music
Alternatively, you can also use the process ID of the target application.
iPhone:~ root# ps aux | grep Music
You will see a list of processes with name contains Music. Find one similar to following.
mobile 9799 0.0 3.7 641992 38248 ?? Ss 9:43PM 0:05.82 /Applications/Music.app/Music
Use following command to inject Cycript to the Music app process. Use the process ID shown in your console.
iPhone:~ root# cycript -p 9799
If you see following, you successfully injected Cycript into the Music app
cy#
Inject code in viewWillAppear: #
First, save original implementation of viewWillAppear:
orgViewWillAppear = UIViewController.prototype['viewWillAppear:']`
Define a new implementation for viewWillAppear:
and assign it.
Following new implementation for viewWillAppear:
displays an alert with the name and address of the viewController, then call the original implementation of viewWillAppear:
UIViewController.prototype['viewWillAppear:'] = function(arg1) {
var className = [NSString stringWithFormat:@"%s(%p)", object_getClassName(this), this];
var alertVC = [UIAlertController alertControllerWithTitle:@"viewWillAppear Hook" message:className preferredStyle:1];
[alertVC addAction:[UIAlertAction actionWithTitle:@"Close" style:1 handler:nil]];
[[[[UIApplication sharedApplication] keyWindow] rootViewController] presentViewController:alertVC animated:YES completion:nil];
// Call original viewWillAppear: function
orgViewWillAppear.call(this, arg1);
}
Result #
Now you know that the custom view controller that shows an album artwork and a list of songs is named “MPHCZAlbumTableViewController” and its address is “0x17dd9cc0”
Conclusion #
I think this is pretty cool, yet crazy thing that all iOS developers should be at least aware of because you want to protect your app from being hacked.
Let’s say your app has “premium” feature that unlocks some of app’s functionality.
It is easy for crackers to counterfeit themselves as a “premium” user if the app uses -(BOOL)isPremium
function to figure out if the user is a premium user. (Override -(BOOL)isPremium
to always return YES)
In fact, users does not need to be a “cracker” for this specific example.
An app call “Flex”, which is available in Cydia, let users override specific function’s return value without writing any code.
Additional Links #
Cycript manual
Know more about Cycript
Cycript Tricks
There are much more you can do with cycript than swizzling method implementation.