ios逆向工具--cycript

不知道cycript之前,要验证class-dump出来的方法,都是傻傻地写个tweak,hook这个方法,然后安装运行验证。自从了解到了cycript之后,才发现之前的做法是“缺南摸了个北”,浪费了好多本就不太值钱的时间,fuck!

安装: 在cydia中直接搜索安装上cycript插件,即可愉快地使用。

使用:

1、注入到指定进程,如注入到桌面进程SpringBoard,并在桌面上显示一个对话框:

adongMacBook-Pro:~ chenzhidong$ ssh [email protected]

[email protected]'s password:

Iphone192:~ root# cycript -p SpringBoard

cy# alertView=[[UIAlertView alloc]initWithTitle:@'iOSRE' message:@'hello huanglng' delegate:nil cancelButtonTitle:@'OK' otherButtonTitles:nil]

#'>'

cy# [alertView show]

cy# [alertView release]

先ssh到ios上,然后cycript注入到SpringBoard进程;接下来创建一个UIAlertView对象,然后调用show方法,就可以在桌面上显示一个对话框了:

ios逆向工具--cycriptX

ps.cycript里经常使用#+对象的地址来操作,如上面的代码不用alertView对象,而用#加上其地址:

cy# [#0x14822f0c0 show]

效果是一样的,以上只是个简单的举例,是不是比去xcode或theos中写段代码,然后编译安装,来的轻快许多!

2、逆向中经常要用到的一些用法

1)、recursiveDescription

[[UIApp key Window]recursiveDescription]查看当前app的UI层次结构,如查看计算器app的层次结构:

ios逆向工具--cycript

可以看到,keyWindow的每个subview及二级subView的description会被完整展示在<...>里,包括每个view对象的内存地址,以及它的坐标、尺寸等基本信息。其中,|缩进的多少体现了视图之前的关系,同一缩进量的视图是平级的;缩进少的视图是缩进多的视图的superview。通过'#'操作符,加上view的内存地址就可以拿到该window上的任意view。

P.S:

其中?expand主要是为了显示的内容能自动换行,早期的版本,这样写,系统会返回一句expand==true表示开启expand功能成功了:

ios逆向工具--cycript 如果没有此返回,则可能您装的是更高的cycript版本,此时要自动换行显示,则需要在末尾增加.toString()。

另外,如果执行recursiveDescription语句后发现显示的UI结构不完整,则有可能说明当前版本的cycript与ios版本不匹配,您可以在cydia中对cycript进行降级,我碰到此情况的时候,降级到0.9.505版后,功能显示正常。

UIApp是[UIApplication sharedApplication]的简写,两者等价。

当然也可以通过UIApplication和UIView的其他方法,获取我们感兴趣的其他view,如:

cy# [UIApp windows]

@[#'; layer = >',#'>']

上面的代码,可以拿到这个App的所有window;

cy# [#0x124eb8370 superview]

#'>'

cy# [#0x124eb8370 subviews]

@[#'>',#'>',#'

上面的代码可以拿到superview和subviews。综合利用以上几个函数,就可以拿到UI上的任意view。

cy# [#0x124eb8370 setHidden:YES]

cy# [#0x124eb8370 setHidden:NO]

通过setHidden控制view的显示和隐藏,这样我们就通知哪个view对应UI上的哪个部件。

以上代码还可以这样写:

cy# #0x124deb550.Hidden=YES

true

cy# #0x124deb550.Hidden=NO

false

2)、[UIResponder nextResponder]:

与recursiveDescription同等地位的公开函数,从view获取到对应的Controller;

ps:按照MVC的设计标准,M代表model,即数据源,是未知的;V代表view,即视图,是已知的;C代表controller,是未知的。M和V之间没有直接联系,而C即可以访问M又可以访问V,是三者的交流中枢。nextResponder可以通过已知的V,获取C,通过C就可以访问M,从而找到最终的数据源。

对一个V调用nextResponder要么返回它对应的C,要么返回它的superview。因为MVC三者缺一不可,所以C是一定存在的,也就是说一定有一个V的nextResponder是C;又因为recursiveDescription可以拿到所有的V,所以从已知的V获取C是可行的,从而就可进一步访问M了。

cy# [#0x124deb550 nextResponder]

#'>'

cy# [#0x124eb8370 nextResponder]

#'>'

cy# [#0x124eb80b0 nextResponder]

#''

上面代码,从计算器的按键View,一步步获取到了对应的controller为keypadViewController

3)找到按钮的响应函数

按钮的UI函数,就是点击它之后的响应函数。给UIView对象加上响应函数,一般是通过[UIControl addTarget:action:forControlEvents:]实现的;而UIControl提供了一个actionsForTarget:forControlEvent:方法,来获得这个UIControl的响应函数。基于这个条件,就可以通过这种方式找到它的响应函数。

cy# [#0x14f8cd2a0 allTargets]

[NSSet setWithArray:@[#'']]]

cy# [#0x14f8cd2a0 allControlEvents]

8192

cy# [#0x14f8cd2a0 actionsForTarget:#0x14f8cfd90 forControlEvent:8192]

@['_sendAction:withEvent:']

cy#

p.s. 也有最后一句返回为null的情况,说明此按钮不是添加的点击响应方法,而是通过touch事件来处理的点击事件。一般可以在头文件中找到相关的操作;

4) rootViewController

在一些视频类app中

var rootController=[UIApp keyWindow].rootViewController

//取得根目录viewController

rootController.selectedViewController.visibleViewController

//取得当前所打开显示的页面viewController

ios逆向工具--cycript

5)choose查找对象的内存地址。

如果知道了类名,及知道一个类对象存在于当前进程中,却不知道它的内存地址,此时可以试用choose命令来获取类对象。

choose(className)打印出该类所有的对象:

ios逆向工具--cycript

你可能感兴趣的:(ios逆向工具--cycript)