Cycript是由Cydia创始人Saurik推出的一款脚本语言,Cycript混合了OC、JavaScript语法的解释器,这意味着我们能够在一个命令中使用OC或者JavaScript,甚至两者并用。它能够挂钩正在运行的进程,能够在运行时修改很多东西。
安装
下载后使用
Cycript可执行文件
- 可以存放在
/opt/cycript_0.9.594,opt目录有可选的意思为了方便使用,可以在
~/.bash_profile、~/.zshrc中配置环境变量
cycript可以使用官方的,也可以使用MonkeyDev中集成的详情可查看:官方文档
基本使用
cy文件
Cycript是一门脚本语言,它可以加载封装好的.cy文件- 将常用的
Cycript功能封装到.cy文件中,便于调试非越狱设备,导入
.cy文件
- 利用
MonkeyDev工具导入.cy文件MonkeyDev本身集成了Cycript。我们只需要将.cy文件,通过Xcode导入Framworks目录即可进入
Cycript环境
cycript-------------------------cy#使用
control + d退出环境
MonkeyDev中集成了Cycript,使用MonkeyDev重签名应用,会自动注入libcycript.dylib相关文件
当
Cycript注入到目标应用,应用进程就会调用Cycript的方法,开启相应的端口,以供第三方监听第三方可通过端口链接进程,进入
cy环境,HOOK当前进程中的内存数据案例1:
附加进程
使用
MonkeyDev安装并运行wx8.0.2.ipa设备和
Mac在同一网络环境,来到终端,使用设备ip + 端口附加进程
cycript -r 10.165.44.19:6666-------------------------cy#
- 端口号默认为
6666案例2:
常用命令
获取
keyWindow
UIWindow.keyWindow()-------------------------#"<iConsoleWindow: 0x125f560b0; baseClass = UIWindow; frame = (0 0; 414 736); gestureRecognizers = <NSArray: 0x283f09680>; layer = <UIWindowLayer: 0x283179fc0>>"获取
UIApplication单例对象
UIApp-------------------------#"<UIApplication: 0x14aa16c80>"定义变量并赋值
var keyWd = UIWindow.keyWindow()-------------------------#"<iConsoleWindow: 0x125f560b0; baseClass = UIWindow; frame = (0 0; 414 736); gestureRecognizers = <NSArray: 0x283f09680>; layer = <UIWindowLayer: 0x283179fc0>>"
keyWd.rootViewController-------------------------#"<MMUINavigationController: 0x1270e9200> ChildViewControllers:(\n \"<WCAccountLoginFirstViewController: 0x1270d7600>\"\n)"
- 当程序的进程结束,定义的所有变量会一起释放
#对象地址:拿到该对象,可用于调用方法
#0x1270e9200-------------------------#"<MMUINavigationController: 0x1270e9200> ChildViewControllers:(\n \"<WCAccountLoginFirstViewController: 0x1270d7600>\"\n)"
*对象:可以取出对象的成员变量
*keyWd-------------------------{isa:iConsoleWindow,_responderFlags:@error,_constraintsExceptingSubviewAutoresizingConstraints:null,...查看视图结构
keyWd.recursiveDescription()-------------------------@"<iConsoleWindow: 0x125f560b0; baseClass = UIWindow; frame = (0 0; 414 736); gestureRecognizers = <NSArray: 0x283f09680>; layer = <UIWindowLayer: 0x283179fc0>>\n | <UITransitionView: 0x125f51960; frame = (0 0; 414 736); autoresize = W+H; layer = <CALayer: 0x28317a500>>\n...格式化打印,遇
\n换行
keyWd.recursiveDescription().toString()-------------------------`<iConsoleWindow: 0x125f560b0; baseClass = UIWindow; frame = (0 0; 414 736); gestureRecognizers = <NSArray: 0x283f09680>; layer = <UIWindowLayer: 0x283179fc0>>| <UITransitionView: 0x125f51960; frame = (0 0; 414 736); autoresize = W+H; layer = <CALayer: 0x28317a500>>| | <UIDropShadowView: 0x125f59770; frame = (0 0; 414 736); autoresize = W+H; layer = <CALayer: 0x28317a680>>| | | <UILayoutContainerView: 0x125e71790; frame = (0 0; 414 736); clipsToBounds = YES; autoresize = W+H; gestureRecognizers = <NSArray: 0x283f0ff90>; layer = <CALayer: 0x283140140>>| | | | <UINavigationTransitionView: 0x125e7a190; frame = (0 0; 414 736); clipsToBounds = YES; autoresize = W+H; layer = <CALayer: 0x283140360>>| | | | | <UIViewControllerWrapperView: 0x125f37540; frame = (0 0; 414 736); autoresize = W+H; layer = <CALayer: 0x28315abc0>>...查询当前进程中该类型的对象
choose (UIButton)-------------------------[#"<FixTitleColorButton: 0x125e2b280; baseClass = UIButton; frame = (20 18; 177 47); clipsToBounds = YES; opaque = NO; autoresize = RM; layer = <CALayer: 0x2831463c0>>",#"<FixTitleColorButton: 0x125e55b20; baseClass = UIButton; frame = (217 18; 177 47); clipsToBounds = YES; opaque = NO; autoresize = LM; layer = <CALayer: 0x283138820>>",...
脚本的封装和使用
一些常用的
Cycript功能,我们会将其进行封装,做成脚本文件,方便调式案例1
将自动链接功能封装脚本
创建
cyShell目录在
cyShell目录下,创建cyConnect.sh脚本打开
cyConnect.sh脚本,写入以下代码:
cycript -r 10.165.44.19:6666在终端为脚本增加可执行权限
chmod +x cyConnect.sh案例2
配置环境变量
终端使用
vim ~/.zshrc定义
CyShell变量
export CyShell=/Users/zang/Zang/Tools/cyShell加入到
PATH中
export PATH=$CyShell:$THEOS/bin:$MonkeyDevPath/bin:$PATH打开终端,在任意目录下,都可使用
cyConnect.sh
cyConnect.sh-------------------------cy#
高级用法
案例1:
修改应用图标的红点数
使用
MonkeyDev安装并运行wx8.0.2.ipa使用
cyConnect.sh附加进程修改
BadgeString
[UIApp setApplicationBadgeString: @"999"]
- 修改当前内存中的数据,应用重复挂起唤醒,数据会被刷新
案例2:
修改控件的属性
延用上述案例,进入登录页
打印
keyWindow下所有视图
UIWindow.keyWindow().recursiveDescription().toString()在终端使用
command + f,搜索+86
<WCUITextField: 0x116387c00; baseClass = UITextField; frame = (20 0; 73 44); text = '+86'; opaque = NO; autoresize = W+H; tintColor = UIExtendedSRGBColorSpace 0.027451 0.756863 0.376471 1; gestureRecognizers = <NSArray: 0x2817946f0>; borderStyle = None; background = <_UITextFieldNoBackgroundProvider: 0x2819310a0: textfield=<WCUITextField 0x116387c00>>; layer = <CALayer: 0x281b76700>>修改
WCUITextField文本框的text属性
#0x116387c00.text = @"+95"
Cycript对一些常用方法进行了封装查看所有视图
pviews()
pviews方法的代码实现
pviews-------------------------function (){return UIApp.keyWindow.recursiveDescription().toString()}
拿到当前控制器
pvcs()
pvcs方法的代码实现
pvcs-------------------------function (){return UIWindow.keyWindow().rootViewController._printHierarchy().toString()}
上述方法,由
MonkeyDev封装,提供给开发者使用找到封装的方法
打开
Mokey项目,在Config目录下,找到MDConfig.plist文件
MonkeyDev封装的.cy文件,里面存储了它提供的常用方法使用
Cycript找到指定控制器的某个控件,过程比较繁琐。更好的方式:在非越狱设备上,使用应用重签名,通过Debug View Hierarchy快速定位控件,找到对应的地址,然后使用Cycript对其进行修改
cy文件的封装
案例1:
封装自定义
cy文件在
MokeyDemo项目中,创建test.cy文件将
test.cy文件拖入项目打开
test.cy文件,写入以下代码:
sum = function(a,b){return a + b;}在
MokeyDemo项目中,使用Copy Files添加test.cy
test.cy是脚本文件,不是MachO,不需要勾选签名重新运行项目
使用
cyConnect.sh附加进程导入脚本
@import test-------------------------{}调用
sum方法
sum(10,20)-------------------------30案例2:
实现获取当前控制器的代码封装
打开
test.cy文件,写入以下代码:``` (function(exports){ APPID = [NSBundle mainBundle].bundleIdentifier, APPPATH = [NSBundle mainBundle].bundlePath, APPHOME = NSHomeDirectory(),
rootVC = function(){ return UIApp.keyWindow.rootViewController; };
keyWindow = function(){ return UIApp.keyWindow; };
getCurrentVC = function(rootVC){
var currentVC;if([rootVC presentedViewController]){rootVC = [rootVC presentedViewController];}if([rootVC isKindOfClass:[UITabBarController class]]){currentVC = getCurrentVC(rootVC.selectedViewController);}else if([rootVC isKindOfClass:[UINavigationController class]]){currentVC = getCurrentVC(rootVC.visibleViewController);}else{currentVC = rootVC;}return currentVC;
};
currentVC = function(){ return getCurrentVC(rootVC()); };
})(exports);
> 重新运行项目> 使用`cyConnect.sh`附加进程> 导入脚本>
@import test
{}
> 获取`APPID`>
APPID
@”com.lg.MokeyDemo”
> 获取`APPPATH`>
APPPATH
@”/private/var/containers/Bundle/Application/D620C178-5030-48E4-9276-981150FF7299/MokeyDemo.app”
> 获取`APPHOME`>
APPHOME
@”/var/mobile/Containers/Data/Application/C2ED1E99-47C4-4C29-8AE6-9C5C136CEE04”
> 调用`currentVC`方法>
currentVC()
““
```
总结
Cycipt
- 是一种脚本语言,混合了多种语法(混合多种语法的解释器),所以可以兼容
Cycipt可以附加到进程,用来动态调试- 将常用功能封装为
cy文件



