Dev:Cycript Tricks

Objective-C objects using choose
The function choose, introduced in version 0.9.502[citation needed] and documented here, allows us to get an array of existing objects of a certain class.

Objective-C objects from addresses
Use new Instance(0xdeadbabe).

Javascript variables
Requires testing.

Getting 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:

Getting 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 class methods
class.messages only contains instance methods. To hook class methods, you need to get to its metaclass. A simple way would be

''Note: this no longer works on 0.9.592. For a similar effect, use the below method''

Alternatively, set the optional second parameter in printMethods to true, e.g. printMethods("NSRunLoop", true)

Replacing existing Objective-C methods
You can simulate MSHookMessage by replacing contents in the messages array, e.g.

Note the func.call(this)</tt> construct. This binds the this</tt> in the original function to the user-specified one. If more than one variable is needed, use function(arg1, arg2, arg3, ...) {...func.call(self, arg1, arg2, arg3, ...);}</tt>, e.g.

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"]</tt>.

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:

As of version 0.9.502[citation needed], there is. See @import's documentation.

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; ....}

Using CGGeometry functions
In order to use functions from the CGGeometry class, you must type this in the cycript prompt:

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.

Cycript scripts
Custom shell function that loads a cycript file: cyc { cycript -p $1 /var/root/common.cy > /dev/null; cycript -p $1; }

Usage: cyc ProcessName

Add this to /etc/profile.d/cycript.sh to make it available in all sessions.

"Warning: If you run this command multiple times against a process, the scripts will be loaded into the script multiple times. This could potentially have unexpected consequences depending on the scripts you are loading. It is not a proper way of doing this and saurik recommends against it."

Weak Classdump (Cycript based class-dump)
Link: https://github.com/limneos/weak_classdump

Usage:

Utils
Link: https://github.com/Tyilo/cycript-utils