美文网首页
iOS逆向实战--025:Cycript

iOS逆向实战--025:Cycript

作者: 帅驼驼 | 来源:发表于2021-05-20 12:08 被阅读0次

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

    安装

    下载后使用Cycript可执行文件

    • 可以存放在/opt/cycript_0.9.594opt目录有可选的意思

    为了方便使用,可以在~/.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()
    -------------------------
    #"<WCAccountLoginFirstViewController: 0x14b0b4200>"
    
    总结

    Cycipt

    • 是一种脚本语言,混合了多种语法(混合多种语法的解释器),所以可以兼容
    • Cycipt可以附加到进程,用来动态调试
    • 将常用功能封装为cy文件

    相关文章

      网友评论

          本文标题:iOS逆向实战--025:Cycript

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