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.503
bash# cycript -p SpringBoard
cy#
cy# [UIApp description]
@"<SpringBoard: 0x10ed05e40>"
cy# [x+1 for (x of @[1,2,3])]
[@2,@3,@4]
cy# choose(CALayer)[0]
#"<CALayer: 0x115807910>"
cy# @[0,1] instanceof Array
true
cy# var a = malloc(128)
0x1147c9d00
cy# ({m: 4, b: 5}).<TAB><TAB>
b m
cy# [&](int a)->int{return a}
0x111001000
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")
0x7fff8d71b58c
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)
0x7fff8d71b58c
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");
0x7fff72c14280
cy# log
[["/var/passwd-fake","r",0x7fff72c14280]]
To learn more, we recommend:



