美文网首页
19-Cycript

19-Cycript

作者: 深圳_你要的昵称 | 来源:发表于2021-05-29 18:46 被阅读0次

前言

本篇文章将介绍逆向实战中经常使用的一门语言 👉 Cycript,它是由Cydia创始人Saurik推出的一款脚本语言Cycript混合了OC、JavaScript语法的解释器,这意味着我们能够在一个命令中使用OC或者JavaScript,甚至两者并用。它能够挂钩正在运行的进程,能够在运行时修改很多东西。

一、Cycript安装

Cycript官网,目前最新版本0.9.594。直接下载SDK解压放在/opt目录中👇

接着在~/.bash_profile~/.zshrc中配置环境变量👇

export PATH=/opt/cycript_0.9.594/cycript

接着验证一下👇

cycript

进入cy#表示配置成功。

⚠️注意:如果已经安装了Monkey不需要配置和安装cycript了。因为monkey自带了cycript,并且配置环境变量应改为👇

export CY=/opt/cycript_0.9.594/
export PATH=/opt/MonkeyDev/bin:$PATH:$CY

二、基本使用

只要将cycript注入到应用中,我们就可以调用其中的命令了,Monkey重签名注入的时候帮我们注入了,例如我们之前文章15-Hook原理(二)反Hook防护 & MokeyDev
中的例子MonKeyDemo👇

app包里面就包含了libcycript.dylib,当Cycript注入到目标应用,应用进程就会调用Cycript的方法,开启相应的端口,以供第三方监听。第三方可通过端口链接进程,进入cy环境,HOOK当前进程中的内存数据

2.1 进入Cycript环境

cycript

2.2 退出Cycript环境

control + d

2.3 附加进程

连接进程进入Cycript环境,例如👇

cycript -r 192.168.3.127:6666

这里手机和电脑要在同一wifi,并且进入应用程序进程。ip为手机的ip。端口号默认为6666

2.4 cycript调试命令

以上附加进程链接好了后,就可以使用cycript调试命令查看信息了,例如👇

  • 获取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)"

当程序的进程结束,定义的所有变量一起释放

  1. #对象地址 👉 拿到该对象,可用于调用方法
#0x1270e9200
-------------------------
#"<MMUINavigationController: 0x1270e9200> ChildViewControllers:(\n    \"<WCAccountLoginFirstViewController: 0x1270d7600>\"\n)"
  1. *对象 👉 可以取出对象的成员变量
*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>>",...

这和LLDBsearch很像。

三、进阶

3.1 脚本自动连接

  1. 创建cyShell目录
  2. cyShell目录下,创建cyConnect.sh脚本
  3. 打开cyConnect.sh脚本,写入以下代码👇
cycript -r 10.165.44.19:6666
  1. 增加可执行权限👇
chmod +x cyConnect.sh
  1. 配置环境变量👇
export cyShell=/Users/Aron/cyShell/
export PATH=/opt/MonkeyDev/bin:$cyShell:$PATH

这样能全局使用👇

cyConnect.sh
cy#

直接就能自动连接了。

3.2 Cycript 修改内存

接下来通过几个案例,使用Cycript脚本,看看如何修改内存。

案例一:修改应用图标的红点数
  1. 使用MonkeyDev安装并运行wx8.0.2.ipa
  2. 使用cyConnect.sh附加进程
  3. 修改BadgeString👇
[UIApp setApplicationBadgeString: @"999"]

⚠️注意:修改当前内存中的数据,应用重复挂起唤醒,数据就会被刷新。

案例二:修改红包金额

例如:正常的红包内容如下👇

  1. 首先通过choose(UILabel)找到红包金额👇
choose(UILabel).toString()

搜索1.00得到地址0x149eaef00👇

  1. 修改红包的金额👇
cy# #0x149eaef00.text = @"¥88888888.00"

同样的方式,找到借款UILabel的地址 0x14c33b460,将text改为还款👇

cy# #0x14c33b460.text = @"还款"
  1. 修改后的内容👇
案例三:修改聊天内容

有2种方式👇

  1. 通过cycript搜索控件进行修改
  2. 通过Xcodeview debug找到控件进行修改

可以看到内容在accessibilitydescription中👇

接着我们在logos文件夹下的.xm文件中,使用logos语法hook方法,代码如下👇

%hook RichTextView

- (_Bool)setPrefixContent:(id)arg1 TargetContent:(NSString *)arg2 TargetParserString:(id)arg3 SuffixContent:(id)arg4 {
//    arg2 为文案
    if([arg2 isEqualToString:@"钱已经借给你了。"]) {
        arg2 = @"钱已经换给你了,请查收!";
    }
    return %orig;
}

%end

至此整个内容就修改完成了👇

3.3 高级用法

  • 获取bundle identifier
    使用APPID命令👇
cy# APPID
-------------------------
@"com.xxxxxx.MonKeyDemo"
  • 获取视图层级
    使用pviews()命令👇
pviews()
-------------------------
`<iConsoleWindow: 0x113790b60; baseClass = UIWindow; frame = (0 0; 375 667); gestureRecognizers = <NSArray: 0x2811ce0d0>; layer = <UIWindowLayer: 0x281f12020>>
   | <UITransitionView: 0x113797170; frame = (0 0; 375 667); autoresize = W+H; layer = <CALayer: 0x281f13120>>
   |    | <UIDropShadowView: 0x113798100; frame = (0 0; 375 667); autoresize = W+H; layer = <CALayer: 0x281f13240>>
   |    |    | <UILayoutContainerView: 0x113793ba0; frame = (0 0; 375 667); clipsToBounds = YES; autoresize = W+H; gestureRecognizers = <NSArray: 0x2811cf060>; layer = <CALayer: 0x281f124c0>>
   |    |    |    | <UINavigationTransitionView: 0x1137950f0; frame = (0 0; 375 667); clipsToBounds = YES; autoresize = W+H; layer = <CALayer: 0x281f12760>>
   |    |    |    |    | <UIViewControllerWrapperView: 0x11378b1d0; frame = (0 0; 375 667); autoresize = W+H; layer = <CALayer: 0x281fd9400>>
   |    |    |    |    |    | <UIView: 0x113794990; frame = (0 0; 375 667); autoresize = W+H; layer = <CALayer: 0x281fe8180>>
   |    |    |    |    |    |    | <UIView: 0x113793980; frame = (0 20; 375 732); autoresize = W; layer = <CALayer: 0x281fe8ac0>>
   |    |    |    |    |    |    |    | <UIImageView: 0x113316830; frame = (0 -20; 375 667); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x281fec780>>
   |    |    |    |    |    |    | <UIView: 0x113316140; frame = (0 582; 375 65); autoresize = W+TM; layer = <CALayer: 0x281fecc60>>
   |    |    |    |    |    |    |    | <FixTitleColorButton: 0x113306f70; baseClass = UIButton; frame = (20 18; 157.5 47); clipsToBounds = YES; opaque = NO; autoresize = RM; layer = <CALayer: 0x281fecea0>>
   |    |    |    |    |    |    |    |    | <UIButtonLabel: 0x113328f90; frame = (60.5 12.5; 37 22); text = '\u767b\u5f55'; opaque = NO; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x283c4acb0>>
   |    |    |    |    |    |    |    | <FixTitleColorButton: 0x1137562e0; baseClass = UIButton; frame = (197.5 18; 157.5 47); clipsToBounds = YES; opaque = NO; autoresize = LM; layer = <CALayer: 0x281fc70a0>>
   |    |    |    |    |    |    |    |    | <UIButtonLabel: 0x1137590e0; frame = (60.5 12.5; 37 22); text = '\u6ce8\u518c'; opaque = NO; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x283c46710>>
   |    |    |    |    |    |    | <UIButton: 0x11375a080; frame = (287 20; 88 49); opaque = NO; autoresize = LM; layer = <CALayer: 0x281fc72e0>>
   |    |    |    |    |    |    |    | <UIButtonLabel: 0x113762910; frame = (15 16; 58 17); text = '\u7b80\u4f53\u4e2d\u6587'; opaque = NO; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x283c46850>>
   |    |    |    | <MMUINavigationBar: 0x113793d20; baseClass = UINavigationBar; frame = (0 20; 375 44); opaque = NO; autoresize = W; layer = <CALayer: 0x281f124e0>>
   |    |    |    |    | <_UIBarBackground: 0x113794170; frame = (0 -20; 375 64); userInteractionEnabled = NO; layer = <CALayer: 0x281f12560>>
   |    |    |    |    |    | <UIImageView: 0x11378df60; frame = (0 0; 375 64); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x281fd9a80>>
   |    |    |    |    |    | <_UIBarBackgroundShadowView: 0x1137957a0; frame = (0 64; 375 0); layer = <CALayer: 0x281f129a0>> clientRequestedContentView effect=none
   |    |    |    |    |    |    | <_UIBarBackgroundShadowContentImageView: 0x113795b10; frame = (0 0; 375 0); opaque = NO; autoresize = W+H; userInteractionEnabled = NO; layer = <CALayer: 0x281f12a60>>
   |    |    |    |    | <_UINavigationBarContentView: 0x113794350; frame = (0 0; 375 44); layer = <CALayer: 0x281f12580>> layout=0x1137945d0
   |    |    |    |    |    | <_UITAMICAdaptorView: 0x11378e920; frame = (187 4; 1 36); autoresizesSubviews = NO; layer = <CALayer: 0x281fe81a0>>
   |    |    |    |    |    |    | <MMTitleView: 0x113338b90; frame = (0 0; 1 36); layer = <CALayer: 0x281f36fa0>>
   |    |    |    |    |    |    |    | <MMUILabel: 0x1133382f0; baseClass = UILabel; frame = (0 0; 0 36); userInteractionEnabled = NO; layer = <_UILabelLayer: 0x283c48a00>>
   |    |    |    |    | <UIView: 0x11373a720; frame = (0 44; 375 0.5); hidden = YES; autoresize = W+TM; layer = <CALayer: 0x281f5a3a0>>
   |    |    |    |    | <UIView: 0x1137903d0; frame = (0 0; 0 0); userInteractionEnabled = NO; layer = <CALayer: 0x281f127a0>>`

也可以查看pviews方法代码实现👇

pviews
-------------------------
function (){return UIApp.keyWindow.recursiveDescription().toString()}
  • 获取视图控制器
    使用pvcs()命令👇
cy# pvcs()
-------------------------
"<MMUINavigationController 0x11396f600>, state: appeared, view: <UILayoutContainerView 0x113793ba0>\n   | <WCAccountLoginFirstViewController 0x11400fa00>, state: appeared, view: <UIView 0x113794990>"

pvcs方法的代码实现👇

pvcs
-------------------------
function (){return UIWindow.keyWindow().rootViewController._printHierarchy().toString()}

上面这些功能,Cycript脚本也有,但是这些命令却不是Cycript自带的,那么它们是哪里来的呢?

在Monkey工程我们可以在Config->MDConfig.plist中发现Cycript下有msmd两个.cy文件👇

这些命令就封装在这两个文件中(工程运行的时候自动从网络上下载)。
ms.cy
md.cy

使用Cycript找到指定控制器某个控件,过程比较繁琐
更好的方式 👉 在非越狱设备上,使用应用重签名,通过Debug View Hierarchy快速定位控件,找到对应的地址,然后使用Cycript对其进行修改

四、cy文件的封装

案例一:封装简单案例
  1. MokeyDemo项目中,创建test.cy文件
  2. 打开test.cy文件,写入以下代码👇
sum = function(a,b){
   return a + b;
}
  1. test.cy文件拖入项目,在MokeyDemo项目中,使用Copy Files添加test.cy👇

⚠️注意:test.cy是脚本文件,不是MachO不需要勾选签名

  1. 重新运行项目,使用cyConnect.sh附加进程

  2. 导入脚本👇

@import test
-------------------------
{}

调用sum方法👇

sum(10,20)
-------------------------
30
案例二:实现获取当前控制器
  1. 修改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);

  1. 重新运行项目,使用cyConnect.sh附加进程
  2. 同样导入脚本👇
@import test
-------------------------
{}
  1. 调用方法👇
  • 获取APPID
APPID
-------------------------
@"com.xxxxxx.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()
-------------------------
#"<WCAccountLoginFirstViewController: 0x14b0b4200>"

总结

  • Cycipt
    • 是一种脚本语言,兼容了多种语法(支持多种语法的解释器
    • Cycipt可以附加到进程,用来动态调试
      • 也可自定义脚本配置环境变量中,方便执行
    • 将常用功能封装为.cy文件

相关文章

  • 19-Cycript

    前言 本篇文章将介绍逆向实战中经常使用的一门语言 ? Cycript,它是由Cydia创始人Saurik推出的一款...

  • iOS-逆向19-Cycript高级用法和Logos

    谁的青春不迷茫,总是在想的多,做的少。 《iOS底层原理文章汇总》[https://www.jianshu.com...

网友评论

      本文标题:19-Cycript

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