Cycript
是Cydia
的创始人Jay Freeman
开发的可以查看和修改运行时App的内存信息的工具。它混合了OC
、JavaScript
语法的解释器,所以我们可以在使用时混合使用两者的语言。
官网 (www.cycript.org/ ) 提供了一下Cycript
的经典使用方法,如下图所示。
1. 安装Cycript
在Cydia
中搜索Cycript
,并安装。
安装完成后,SSH
连接手机,输入cycript
命令,就能进入交互界面输入命令了。
2. 注入进程
使用ps -A
命令查看所有进程,找到我们需要注入的进程。这里以爱思助手
为例。
输入cycript -p
+ 进程名/进程id ,就可以对app进行调试了。下面一个弹窗为例:
cy# var alert = [[UIAlertView alloc] initWithTitle:@"hi" message:@"hello, world!" delegate:nil cancelButtonTitle:@"canel" otherButtonTitles:nil]
#"<UIAlertView: 0x13fcf6770; frame = (0 0; 0 0); layer = <CALayer: 0x283131260>>"
cy# [alert show]
3. 调试app
可以通过OC的语法直接查看app的一些信息。
cy# UIApp
#"<UIApplication: 0x11de03c90>"
cy# UIApp.delegate
#"<AsTools.AppDelegate: 0x281d7e8a0>"
cy# UIApp.keyWindow
#"<UIWindow: 0x11dd1c190; frame = (0 0; 375 667); autoresize = W+H; gestureRecognizers = <NSArray: 0x2830544b0>; layer = <UIWindowLayer: 0x283e68440>>"
cy# UIApp.keyWindow.rootViewController
#"<AsTools.NRViewController: 0x11dd03560>"
cy# UIApp.keyWindow.rootViewController.view
#"<RCTRootView: 0x11dd50390; frame = (0 0; 375 667); autoresize = W+H; layer = <CALayer: 0x283e6aaa0>>"
choose()
获取当前内存中某个类的所有实例对象
cy# choose(UILabel)
[#"<UILabel: 0x11fbc8c40; frame = (0 64; 375 24); text = '\xe9\xa6\x96\xe6\xac\xa1\xe5\x8f\x91\xe9\x80\x81\xe6\x88\x90\xe5\x8a\x9f {\"show\":1,\"showtim...'; hidden = YES; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x281d305f0>>",#"<UILabel: 0x11de5b150; frame = (0 64; 375 12); text = '\xe6\x97\xa5\xe5\xbf\x97\xe6\xb5\x8b\xe8\xaf\x95'; hidden = YES; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x281d58780>>"]
发现0x11fbc8c40
是隐藏起来的,更改属性将他显示出来,并且更改一下字体颜色
cy# #0x11fbc8c40.hidden = false
false
cy# #0x11fbc8c40.textColor = [UIColor greenColor];
#"UIExtendedSRGBColorSpace 0 1 0 1"
cycript
不支持中文显示,可以使用在线工具进行转换显示。
4.引用外部脚本
mjcript里面封装了一些实用的函数,方便我们在调试app的时候用到。下面介绍一下如何使用。
- 首先下载到本地
- 然后通过
scp
拷贝到手机上
scp mjcript.cy root@192.168.9.53:/usr/lib/cycript0.9
- 通过
@import
引入mjcript
@import mjcript
然后可以使用里面提供的方法了。
// 包名
MJAppId;
// bundle path
MJAppPath;
// document path
MJDocPath;
// caches path
MJCachesPath;
// 加载系统动态库(/System/Library/Frameworks/xxx.framework,/System/Library/Private/Frameworks/xxx.framework)
MJLoadFramework("BluetoothManager");
// keyWindow
MJKeyWin();
// 根控制器
MJRootVc();
// 找到显示在最前面的控制器
MJFrontVc();
// 递归打印UIViewController view的层级结构
MJVcSubviews(vc);
// 递归打印最上层UIViewController view的层级结构
MJFrontVcSubViews();
// 获取按钮绑定的所有TouchUpInside事件的方法名
MJBtnTouchUpEvent(btn);
// CG函数
MJPointMake(x, y);
MJSizeMake(w, h);
MJRectMake(x, y, w, h);
// 递归打印controller的层级结构
MJChildVcs(vc);
// 递归打印view的层级结构
MJSubviews(view);
// 判断是否为字符串 "str" @"str"
MJIsString(value);
// 判断是否为数组 []、@[]
MJIsArray(value);
// 判断是否为数字 666 @666
MJIsNumber(value);
// 打印所有的子类
MJSubclasses(className, reg);
// 打印所有的对象方法
MJInstanceMethods(className, reg);
// 打印所有的对象方法名字
MJInstanceMethodNames(className, reg);
// 打印所有的类方法
MJClassMethods(className, reg);
// 打印所有的类方法名字
MJClassMethodNames(className, reg);
// 打印所有的成员变量
MJIvars(obj, reg);
// 打印所有的成员变量名字
MJIvarNames(obj, reg);