static_dynamicCycript is a console based application that is a blend of Objective-C and JavaScript. Cycript is very useful for dynamic analysis of iOS applications.  What you can do with it is hook a running application on the phone and dynamically change parameters, rewrite objects and intercept communication within the application.  This can be done by injecting a static library or injecting as the app is running. Cycript does depend on MobileSubstrate so be sure to install that within Cydia. To get started with Cycript I’m going to walk through getting behind a password protected app. I’m not going to disclose the app as I don’t want to disclose any vulnerabilities. This is example should universally apply , there are ton of apps that state you can “securely” lock things in them just download one from the app store as I did.

1. Hook the application
Open the application on the phone and find the PID of the application you are going to hook.

ps -A |grep 
cycript -p

2. Find the Lock Screen Controller
The app should be sitting at the lock screen so we will want to find out the controller that is current at the time as this is the one we will want to manipulate.

cy# UIApp.keyWindow.rootViewController
@""
cy# LockScreen = UIApp.keyWindow.rootViewController
@""
cy# LockScreen.visibleViewController
[@"<PatternLockViewController: 0x1d88d4f0"]

As you can see by the last line we now know the name of the lock screen view controller is “PatternLockViewController”. This is the one we will want to look into. In the example above I created a variable named LockScreen to the current ViewController. This is just to make things easier in the future. You can alternatively just type the following to get the current ViewController.

cy# [UIApp.keyWindow.rootViewController.visibleViewController]
[@"<PatternLockViewController: 0x1d88d4f0"]

3. Analyze the Lock Screen Controller

This is the phase where we basically will just start looking for things that we can remove or somehow open the lock screen. With a little luck and common sense things will stick out worth altering.  Below are a few tricks I used to analyze this particular app.

One way to do this is to add a function in Cycript for printing all the methods of a class. This one below was taken from cycript tricks. You can just copy and paste it into the console and call it with “PatternLockViewController”. Reminder that “PatternLockViewController” is for this example, yours should be the one you discovered in step two.

cy# function printMethods(className) {
cy#    var count = new new Type("I");
cy#    var methods = class_copyMethodList(objc_getClass(className), count);
cy#    var methodsArray = [];
cy#    for(var i = 0; i < *count; i++) { cy>      var method = methods[i];
cy>      methodsArray.push({selector:method_getName(method), implementation:method_getImplementation(method)});
cy>    }
cy>    free(methods);
cy>    free(count);
cy>    return methodsArray;
cy> }
cy# printMethods(PatternLockViewController)
[{selector:@selector(moreButton),implementation:0x70aa1},{selector:@selector(setMoreButton:),implementation:0x70ac1},{selector:@selector(moreTapped:),implementation:0x6fd21},{selector:@selector(setupView),implementation:0x702fd},{selector:@selector(didFinishLockWithKey:),implementation:0x70739},{selector:@selector(lockerView),implementation:0x70b09},{selector:@selector(setupHeaderWithType:),implementation:0x6fda1},{selector:@selector(requestPassword),implementation:0x70a49},{selector:@selector(setRequestPassword:),implementation:0x70a59},{selector:@selector(drawPatternLockView),implementation:0x70a15},{selector:@selector(setDrawPatternLockView:),implementation:0x70a35},{selector:@selector(setLockerView:),implementation:0x70b29},{selector:@selector(tempPassword),implementation:0x70a69},{selector:@selector(dismissPatternLockViewController),implementation:0x7069d},{selector:@selector(setTempPassword:),implementation:0x70a79},{selector:@selector(setBackgroundView:),implementation:0x709cd},{selector:@selector(backgroundView),implementation:0x709ad},{selector:@selector(viewDidLoad),implementation:0x704cd},{selector:@selector(viewDidUnload),implementation:0x70609},{selector:@selector(setHeaderView:),implementation:0x70af5},{selector:@selector(headerView),implementation:0x70ad5},{selector:@selector(.cxx_destruct),implementation:0x70b3d},{selector:@selector(delegate),implementation:0x709e1},{selector:@selector(setDelegate:),implementation:0x70a01}]

While the dump doesn’t display that well in this format below are some interesting methods.

selector:@selector(requestPassword),implementation:0x70a49
selector:@selector(setRequestPassword:),implementation:0x70a59
selector:@selector(tempPassword),implementation:0x70a69
selector:@selector(dismissPatternLockViewController),implementation:0x7069d

Another thing to do is dump the messages to ensure you are getting all delegates.

cy# PatternLockViewController.messages
{moreButton:0x70aa1,"setMoreButton:":0x70ac1,"moreTapped:":0x6fd21,setupView:0x702fd,"didFinishLockWithKey:":0x70739,lockerView:0x70b09,"setupHeaderWithType:":0x6fda1,requestPassword:0x70a49,"setRequestPassword:":0x70a59,drawPatternLockView:0x70a15,"setDrawPatternLockView:":0x70a35,"setLockerView:":0x70b29,tempPassword:0x70a69,dismissPatternLockViewController:0x7069d,"setTempPassword:":0x70a79,"setBackgroundView:":0x709cd,backgroundView:0x709ad,viewDidLoad:0x704cd,viewDidUnload:0x70609,"setHeaderView:":0x70af5,headerView:0x70ad5,".cxx_destruct":0x70b3d,delegate:0x709e1,"setDelegate:":0x70a01,mf_dataForUICustomization:0x3358d741,mf_keyPathsMapForUICustomization:0x3358d73d,"mf_setDataForUI"

Some interesting messages to take a look at are.

dismissPatternLockViewController:0x7069d
setRequestPassword:0x70a59

Another valuable resource is class-dump-z information. This is the class headers dump that I have done on the application. The example below is an area in the class dump that stood out to me from the data I saw above. I found this just by looking for “PatternLockViewController” and “requestPassword”. All of which was obtained from the previous actions. If you are unaware of how to get class-dump-z information there are tons of guides on the internet.

__attribute__((visibility("hidden")))
@interface PatternLockViewController : UIViewController  {
	UIImageView* _backgroundView;
	id _delegate;
	DrawPatternLockView* _drawPatternLockView;
	BOOL _requestPassword;
	NSString* _tempPassword;
	UIButton* _moreButton;
	UIImageView* _headerView;
	UIImageView* _lockerView;
}
@property(assign, nonatomic) __weak UIImageView* lockerView;
@property(assign, nonatomic) __weak UIImageView* headerView;
@property(assign, nonatomic) __weak UIButton* moreButton;
@property(retain, nonatomic) NSString* tempPassword;
@property(assign, nonatomic) __weak UIImageView* backgroundView;
@property(assign, nonatomic) BOOL requestPassword;
@property(assign, nonatomic) __weak id delegate;
@property(assign, nonatomic) __weak DrawPatternLockView* drawPatternLockView;
-(void).cxx_destruct;
-(void)didFinishLockWithKey:(id)key;
-(void)dismissPatternLockViewController;
-(void)viewDidUnload;
-(void)viewDidLoad;
-(void)setupView;
-(void)setupHeaderWithType:(int)type;
-(void)moreTapped:(id)tapped;
@end

 

4. Inject the application.

With all the information we gathered above there is a couple of things we can do here and probably more. Below are just two methods that get us access to the application. One is setting a variable and the other is setting your View Controller.

Setting Variable:

We will want to set the “BOOL _requestPassword” variable. Being a BOOLEAN we can easily change this variable to true in cycript like below. Notice calling the controller with the variable requestPassword and returning true.

cy# PatternLockViewController.messages['requestPassword'] = function() {return true;}
function () {return true;}

In this particular example it called for me to set the master password again. I was then able to set a new password and get into the “secure” container.

Set View Controller:

Secondly we can just call “dismissPatternLockViewController” as the visible controller. This will not change the master password like above but instead just get rid of the password screen thus allowing access to all the data.

cy# [UIApp.keyWindow.rootViewController.visibleViewController dismissPatternLockViewController]

Hopefully this was a decent enough primer to get you started with Cycript. If anyone else has some standard things they do in cyript I would love to hear them.

References: