四、Cycript

作者: Lovell_ | 来源:发表于2018-11-28 23:02 被阅读102次

语言混合物,用来修改调试正运行在内存中的app的。

Cycript是什么,做什么用的?
  1. Cycript是Objective-C++、ES6(JavaScript)、Java等语法的混合物
  2. 可以用来探索、修改、调试正在运行的Mac\iOS APP
  3. 官网: http://www.cycript.org/
    文档: http://www.cycript.org/manual/
安装插件
  1. 在Cydia上安装Cycript和adv-cmds两个插件,前者可在iPhone上调试运行中的APP;后者可以列出系统当前的进程;
  2. 连接、登录到iPhone服务端;
adv-cmds插件使用(用于搜索iPhone进程)
  1. 连接登录到iPhone服务端,
  2. ps –Aps aux列出所有的进程
  3. ps –A | grep 关键词搜索关键词
部分进程 网易云音乐app 搜索进程关键词
Cycript语法使用

注意要调试的那个APP要保证打开,内存中运行,如果退到后台会很容易从内存中清除

> 开启Cycript监听(进入iPhone服务端操作)
cycript
cycript -p 进程ID 【不推荐,进程ID每次都会变】
cycript -p 进程名称 【推荐使用,进程名不会变】

根据进程名称开启cycript

> Cycript的语法

  1. Ctrl + C :取消输入
  2. Ctrl + D:退出Cycript监听
  3. Command + R :清屏
  4. UIApp :[UIApplication sharedApplication]
  5. var 变量名 = 变量值 :定义变量
  6. #内存地址 :用内存地址获取对象
  7. ObjectiveC.classes :当前app已加载的所有OC类
  8. *对象 :查看对象的所有成员变量
  9. view.recursiveDescription().toString() :递归打印view的所有子控件(跟LLDB一样的函数)
  10. choose(UIViewController) :查看当前界面中,存在内中的UIViewController类型的对象
  11. choose(UITableViewCell):筛选出UITableViewCell类型的对象
部分语法实操
实战:定位登录方法

1、先从Mac端拷贝个MJ的cy封装文件到iPhone端,scp -P 10011 [文件] root@localhost:/usr/lib/cycript0.9/MJTool.cy

Mac终端实操传MJTool.cy文件 iFunBox查看是否拷贝成功

2、连接登录到iPhone端,cycript监听网易云音乐进程(注意保持网易云音乐app是开启状态)

3、导入封装文件,查看当前界面

  • @import MJTool
  • 调用MJFrontVc(),查看网易云音乐当前界面的控制器

4、打印控制器的所有方法

注意:方法里面传的是对象

5、调用登录方法

控制器对象调用登录方法,手机上弹框提示:手机号不能为空!操控成功!!!

6、找到账号框和密码框

app账号框输入:6666
app密码框输入:8888

打印控制器的子view:找到6666和8888,即找到了账号框和密码框:

找到账号框和密码框

验证:拿到账号框对象,账号框输入7777,app的输入框数字也变为7777,说明这个账号框是对的

7、用MJTool.cy看下该控制器的其他的东西

7.1 类方法:MJClassMethodNames(#0x129c57f60)

该控制器没类方法

7.2 对象方法:MJInstanceMethodNames(#0x129c57f60)

对象方法

8、提个需求:把『登录』按钮删掉

找到『登录』两个字:
上面已经遍历控制器的子view了,只要找到登录这两个字就行了,但是文字都是unicode,『登录』的unicode是什么呢?可借助python,新建个终端,python , unicode('登录','UTF-8'),即可得出『登录』的unicode :

command + F 搜索 \u767b\u5f55,找到对应的button:

执行删除操作:[#0x129c4c6c0 removeFromSuperview],app上的登录按钮不见了。

注意:我们只是删掉了内存中的登录按钮,关掉app再次启动,登录按钮依然在。

上面的这些,只是在内存中动态调试。如何永久的删掉登录呢,后面还要学很多东西

10、添加个红色的view,用到MJTool

cy# MJFrontVc()
#"<NMPhoneLoginViewController: 0x129c57f60>"
cy# var redV = [[UIView alloc] init]
#"<UIView: 0x129ba8010; frame = (0 0; 0 0); layer = <CALayer: 0x1294e6350>>"
cy# redV.backgroundColor = [UIColor redColor]
#"UIDeviceRGBColorSpace 1 0 0 1"
cy# redV.frame = MJRectMake(10,100,100,100)
{0:{0:10,1:100},1:{0:100,1:100}}
cy# [#0x129c57f60.view addSubview:redV]
cy# 

11、MJTool工具中正则表达式使用——筛选

cy# MJFrontVc()
#"<NMPhoneLoginViewController: 0x129c57f60>"

// 筛选带有login的对象方法,注意是匹配大小写的
cy# MJInstanceMethodNames(#0x129c57f60,/login/)
[&"loginButtonClicked:",&"loginView"]

// 筛选以View结尾的对象方法,注意大小写
cy# MJInstanceMethodNames(#0x129c57f60,/View$/)
[&"loginView",&"loadView"]

12、实战:封装Cycript文件

本次用sublime封装好了后,拷贝到iPhone中,两种拷贝方式:

12.1、终端拷贝:scp -P 10011 ~/Desktop/test.cy root@localhost:/usr/lib/cycript0.9
12.2、利用iFunBox,直接拖拽到cycript0.9文件夹下。

注意,如果Cycript文件修改了,重新拷贝到cycript0.9文件夹后,需要1、control+d退出监视、2、退出app、3、重启操控的app,4、重新监视app喜马拉雅cycript -p ting5、@import test即可看到外界可用的内容。

12.3 两种写法的区别,获取一次和每次都重新获取的写法,比如:UIApp.keyWindow.rootViewController

a. 获取一次:

exports.rootVc = UIApp.keyWindow.rootViewController;

b.每次都重新获取,写成函数:

exports.rootVc = function() {
    return UIApp.keyWindow.rootViewController;
};

12.4 进入喜马拉雅APP的本地沙盒看看

Cycript文件内容:

(function(exports) {

    // JS的语法和OC的语法混在一起

    exports.sum = function(a,b){
        return a + b;
    };

    exports.minus = function(a,b){
        return a - b;
    };

    exports.age = 18;

    // appId是一成不变的,获取一次就行
    exports.appId = [NSBundle mainBundle].bundleIdentifier;

    // 根控制器是变化的,每次都应该重新获取,写成函数
    exports.rootVc = function() {
        return UIApp.keyWindow.rootViewController;
    };

    // 沙盒路径是固定的值,获取一次就行
    exports.docPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];

})(exports);

服务器终端执行本地缓存路径结果:

cy# test.docPath
@"/var/mobile/Containers/Data/Application/5C9D8696-C8FF-4233-96AD-213F514BCCA3/Documents"
cy# 

利用iFunBox进入沙盒,这样就可以查看到喜马拉雅的本地存储结构是怎么做的

image.png
  1. 在执行test.docPath能不能去掉test文件名——弄成全局

可以,写成全局的,如何写成全局的:
在cy文件中去掉exports,就是全局的了,无需用文件名来调用了。

弄成全局后,要注意2点:

  1. 导入test文件的时候不会提示文件中的全局,勿慌;
  2. cy文件多了以后,全局名可能会重复——解决办法:加前缀。

导入test后,写成全局的LFSum和LFDocPath没有提示了。

  1. 作者saurik也有个cy文件,放在如下路径,这是为了防止重名。我们也可以效仿,用反域名来设置文件夹层级。不过这样很麻烦,我们放在cycript0.9文件夹下就行了。

15、如果有东西创建失败,说明要导入某个库MJLoadFramework('XXX')

16、想知道控制器是如何划分结构的——使用MJTool.cy:
MJRootVc(),MJChildVcs(#0x14801f600),或者一步到位MJChildVcs(MJRootVc())

17、想知道当前view是如何划分结构的——使用MJTool.cy:

18、想知道控制器有哪些对象方法——使用MJTool.cy:
MJInstanceMethodNames(#0x12324432)
MJInstanceMethodNames(#0x12324432,/click/) // 筛选出带有click的

19、控制器有哪些成员变量——使用MJTool.cy:
MJIvarNames(#0x12324432)
MJIvarNames(#0x12324432,/click/) // 筛选出带有click的

20、获取某个类的所有子类——使用MJTool.cy:

//当前app有哪些UIViewController的子类
MJSubclasses(UIViewController)
MJSubclasses("UIViewController",/NMR/)

//查看app有哪些自定义导航控制器
MJSubclasses(UINavigationController)
MJSubclasses("UINavigationController")
MJSubclasses("UINavigationController",/NMR/)

21、改微信钱包零钱

大致步骤:

  1. 连接登录iPhone服务端,打开微信,进入微信钱包页面,搜索进程ps -A,监视微信进程cycript -p WeChat,导入工具@import MJTool
  2. MJFrontVc():当前控制器
  3. MJVcSubviews(#0x13e90c200):当前控制器的所有子view
  4. command + F 搜索零钱的数字,确定是哪个对象
  5. (#0x14065f880).text = '\xa5848,340.00',修改零钱
  6. (#0x14065f880).backgroundColor = [UIColor redColor],修改背景
  7. (#0x14065f880).frame = MJRectMake(0,85,320,13),修改宽高

到这里为止,都还只是借用cycript的封装,修改调试内存中的东西,还不能达到永久修改的目的。


总结

操作步骤:
1、连接登录iPhone端;
2、打开app,ps -A 列出iPhone所有进程,找到app进程名称;
3、监视进程cycript -p 进程名词
4、用Cycript(一般用封装好的cy工具,方便),对app进行增、删、改、查。

相关文章

网友评论

    本文标题:四、Cycript

    本文链接:https://www.haomeiwen.com/subject/wofhqqtx.html