Cycript allows developers to explore and modify running applications on either iOS or Mac OS X using a hybrid of Objective-C++ and JavaScript syntax through an interactive console that features syntax highlighting and tab completion.

current version: 0.9.501

Download ZIP   Read Manual

Inject Into Processes

bash# cycript -p SpringBoard

Objective-C Messages

cy# [UIApp description]
@"<SpringBoard: 0x10ed05e40>"

JavaScript Extensions

cy# [x+1 for (x of @[1,2,3])]

Effortless Exploration

cy# choose(CALayer)[0]
#"<CALayer: 0x115807910>"

Bridged Object Model

cy# @[0,1] instanceof Array

Foreign Function Calls

cy# var a = malloc(128)

Magical Tab-Complete

cy# ({m: 4, b: 5}).<TAB><TAB>
b m

C++11 Lambda Syntax

cy# [&](int a)->int{return a}


Say we have a program that opens /etc/passwd to check our password. We would prefer that it uses /var/passwd-fake. First, we need the address of fopen.

cy# fopen = dlsym(RTLD_DEFAULT, "fopen")

We can't work with this function without a type signature, though, so let's cast it to a Functor. With @encode we can use high-level C typedef syntax.

cy# fopen = @encode(void *(char *, char *))(fopen)

Next, let's @import Substrate, so we can use MS.hookFunction to modify fopen: we will swap in our fake passwd file, as well as log all the arguments.

cy# @import com.saurik.substrate.MS
cy# var oldf = {}
cy# var log = []
cy# MS.hookFunction(fopen, function(path, mode) {
cy>     if (path == "/etc/passwd")
cy>         path = "/var/passwd-fake";
cy>     var file = (*oldf)(path, mode);
cy>     log.push([path, mode, file]);
cy>     return file;
cy> }, oldf)

In addition to our nefarious modification, this let's us see all of the calls to fopen, as well as track what the returned FILE * values were. Let's try it out.

cy# fopen("/etc/passwd", "r");
cy# log

Featured Video cycript @ 360|iDev

More Information

To learn more, we recommend:

As seen at...