Dev:Cycript Tricks

Printing Ivars
Often just typing *varName works: Sometimes it does not... then you can do:

You may use this function to get as much ivar values as possible: To use:

Printing Methods
Function to get the methods:

Usage: You can also just look at the message property of the isa, e.g. to get rootViewControllers methods: UIApp.keyWindow.rootViewController.isa.messages

Get methods matching particular RegExp
Usage:

Getting Objective-C Objects from Addresses
Use new Instance(0xdeadbabe).

Replacing existing Objective-C methods
You can simulate MSHookMessage by replacing contents in the messages array, e.g. Note the func.call(self) construct. This binds the self in the original function to the user-specified one. If more than one variable is needed, use func.call(self, arg1, arg2, arg3, ...). Note that the subsequent arguments will not be automatically mapped to the corresponding Objective-C types, so instead of "foo" you will need to use [NSString stringWithString:"foo"].

Getting class methods
class.messages only contains instance methods. To hook class methods, you need to get to its metaclass. A simple way would be

Include other Cycript files
As of 0.9.274-1, there isn't a native file import feature. If cycript will be hooked into another process, since the data will be retained there, you can first load the other .cy file with this:

If cycript is launched standalone, inclusion can still be faked with a combination of cycript compiler and Javascript's eval</tt> function:

Using NSLog
Type in the console: NSLog_ = dlsym(RTLD_DEFAULT, "NSLog") NSLog = function { var types = 'v', args = [], count = arguments.length; for (var i = 0; i != count; ++i) { types += '@'; args.push(arguments[i]); } new Functor(NSLog_, types).apply(null, args); }

And then you can use NSLog as usual: cy# NSLog_ = dlsym(RTLD_DEFAULT, "NSLog") 0x31451329 cy# NSLog = function { var types = 'v', args = [], count = arguments.length; for (var i = 0; i != count; ++i) { types += '@'; args.push(arguments[i]); } new Functor(NSLog_, types).apply(null, args); } {} cy# NSLog("w ivars: %@", tryPrintIvars(w))

If you are attached to a process, the output is going to be in the syslog: Nov 17 20:26:01 iPhone3GS Foobar[551]: w ivars: {\n   contentView = <UIView: 0x233ea0; ....}

Writing Cycript output to file
Cycript output is an NSString, so it is possible to call writeToFile and save it somewhere. Example:

You can use this, for example, to get a dump of SpringBoard's view tree.