iOS 逆向编程(十四)Cycript 语法入门

简介: iOS 逆向编程(十四)Cycript 语法入门

一、Cycript 语法简介

  • 根据 上一篇文章 进入 Cycript 调试模式之后,就需要通过脚本语言来进行操作调试了,比如:获取页面控制器获取对象属性手动调用对象方法页面上添加自己的UI…等等。
  • Cycript 也是有语法例子的,可以进去参考,命令格式:
命令 结果
UIApp 获取当前 App 的 Appdelegate 对象
UIApp.keyWindow 获取当前的keyWindow对象
UIWindow.keyWindow 获取当前的keyWindow对象
var 定义一个对象
#内存地址 获得当前内存地址的对象
#内存地址 获得当前内存地址的对象
*对象 获得对象的所有成员变量
choose(UILabel) 查找当前界面的所有UILabel

  • 在进入cycript调试环境后,就可以直接写OCJS… 等支持的语法了,例如:
  • OC(其实也就是跟 OC 语法非常非常像的语法格式):
cy# [UIApp description]
@"<NMApplication: 0x113d4d710>"
  • UIApp 等于 UIApplication 对象,这两种写法都一样,脚本给与的缩写。
cy# UIApp
#"<NMApplication: 0x113d4d710>"
  • JS
cy# [for (x of [1,2,3]) x+1]
[2,3,4]

二、定义变量

  • 不支持 OC 里面那种 NSString *name = @"dzm" 这种写法
$ var 变量名 = 变量值
• 1
// 进入调试
iPhone:~ root# cycript -p neteasemusic
// 创建变量 window
cy# var window = UIApp.keyWindow
#"<OTTouchObservingWindow: 0x10a65b610; baseClass = UIWindow; frame = (0 0; 320 568); gestureRecognizers = <NSArray: 0x28043da10>; layer = <UIWindowLayer: 0x280af58a0>>"
// 输出变量 window 跟上面的 UIApp.keyWindow 值一致
cy# window
#"<OTTouchObservingWindow: 0x10a65b610; baseClass = UIWindow; frame = (0 0; 320 568); gestureRecognizers = <NSArray: 0x28043da10>; layer = <UIWindowLayer: 0x280af58a0>>"

三、获取常用对象(举例)

  • UIApp 等于 UIApplication 对象。
cy# [UIApp description]
@"<NMApplication: 0x113d4d710>"
cy# UIApp
#"<NMApplication: 0x113d4d710>"
  • 获取 keyWindow 对象(OTTouchObservingWindow 其实就是 UIWindow,只是编译之后 iOS 内部做了转换)。
cy# UIApp.keyWindow
#"<OTTouchObservingWindow: 0x10a65b610; baseClass = UIWindow; frame = (0 0; 320 568); gestureRecognizers = <NSArray: 0x281ac01e0>; layer = <UIWindowLayer: 0x28146e0a0>>"
  • 获取 rootViewController
cy# UIApp.keyWindow.rootViewController
#"<NMRootNavigationController: 0x10a8cd400>"

四、内存地址访问对象

  • 获取到 keyWindow 的内存地址 0x10a65b610
cy# UIApp.keyWindow
#"<OTTouchObservingWindow: 0x10a65b610; baseClass = UIWindow; frame = (0 0; 320 568); gestureRecognizers = <NSArray: 0x281ac01e0>; layer = <UIWindowLayer: 0x28146e0a0>>"
  • 可以通过 #0x10a65b610 这种方式通过内存地址访问这个对象,你会发现跟上面输出 的对象是一样的:
cy# #0x10a65b610
#"<OTTouchObservingWindow: 0x10a65b610; baseClass = UIWindow; frame = (0 0; 320 568); gestureRecognizers = <NSArray: 0x28043da10>; layer = <UIWindowLayer: 0x280af58a0>>"
  • 也可以通过内存地址的方式获取该对象下面的其他属性值:
cy# #0x10a65b610.rootViewController
#"<NMRootNavigationController: 0x10a8cd400>"

五、ObjectiveC.classes 获取已加载的所有OC类

  • ObjectiveC.classes:你可以理解成获取列出来所有的 .h 头文件或者 class 对象,就是列出当前已经加载所有类。
cy# ObjectiveC.classes
{
 // 系统类 
 __NSGenericDeallocHandler:__NSGenericDeallocHandler,_NSZombie_:_NSZombie_,__NSMessageBuilder:__NSMessageBuilder,.....
 // 自定义类
 RMLog:RMLog,NMSearchShowCell,NMSearchPlaylistCell:NMSearchPlaylistCell,NMDjRadioPurchaseProgramCell:NMDjRadioPurchaseProgramCell,......
}
  • 这样一看做 iOS 都知道啥意思了,都是类名,自定义类,Cell 之类的。

六、查看对象的所有成员变量

  • 在后面经常会需要知道 某个对象 里面有哪些成员 变量 或者 属性
  • 只需要在对象前面加个 * 号即可,例如:*UIApp :
cy# *UIApp
{isa:NSKVONotifying_NMApplication,_hasOverrideClient:0,_hasOverrideHost:0,_hasInputAssistantItem:0,_delegate:#"<NMAppDelegate: 0x2838b2010>",_event:#"<UIEvent: 0x2804cdce0>",_motionEvent:#"<UIMotionEvent: 0x2831b4d00> timestamp: 0 subtype: 0",_remoteControlEvent:#"<UIRemoteControlEvent: 0x28149b1c0>",_remoteControlEventObservers:1,_topLevelNibObjects:null,_networkResourcesCurrentlyLoadingCount:0,_hideNetworkActivityIndicatorTimer:null,_editAlertController:null,_statusBar:#"<UIStatusBar: 0x10a863800; frame = (0 0; 320 20); opaque = NO; autoresize = W+BM; layer = <CALayer: 0x280a8ab20>>",_statusBarRequestedStyle:0,_statusBarWindow:#"<UIStatusBarWindow: 0x10a6561d0; frame = (0 0; 320 568); opaque = NO; gestureRecognizers = <NSArray: 0x280438930>; ......}
  • 上面的所有属性都是以 , 逗号分开,每一个逗号就是一个成员变量。
    挑个出来看看,比如 代理属性,前面是 属性名称,后面是
_delegate:#"<NMAppDelegate: 0x2838b2010>"

七、递归打印 View 的所有子控件

  • iOS开发中,可以通过控制台 LLDB打断点后po的方式递归输出指定视图的所有子控件。
  • 语法 po [self.view.window recursiveDescription]
(lldb) po [self.view.window recursiveDescription]
 <UIWindow: 0x7f9f8b618460; frame = (0 0; 375 667); gestureRecognizers = <NSArray: 0x60000077a1c0>; layer = <UIWindowLayer: 0x600000926de0>>
    | <UITransitionView: 0x7f9f8b719630; frame = (0 0; 375 667); autoresize = W+H; layer = <CALayer: 0x60000093b300>>
    |    | <UIDropShadowView: 0x7f9f8b71a060; frame = (0 0; 375 667); clipsToBounds = YES; autoresize = W+H; layer = <CALayer: 0x60000093b280>>
    |    |    | <UIView: 0x7f9f8b719ef0; frame = (0 0; 375 667); autoresize = W+H; layer = <CALayer: 0x60000093b2c0>>
 <UIWindow: 0x7f9f8b618460; frame = (0 0; 375 667); gestureRecognizers = <NSArray: 0x60000077a1c0>; layer = <UIWindowLayer: 0x600000926de0>>
    | <UITransitionView: 0x7f9f8b719630; frame = (0 0; 375 667); autoresize = W+H; layer = <CALayer: 0x60000093b300>>
    |    | <UIDropShadowView: 0x7f9f8b71a060; frame = (0 0; 375 667); clipsToBounds = YES; autoresize = W+H; layer = <CALayer: 0x60000093b280>>
    |    |    | <UIView: 0x7f9f8b719ef0; frame = (0 0; 375 667); autoresize = W+H; layer = <CALayer: 0x60000093b2c0>>
  • Cycript 里面递归输出子控件,其实也是使用 recursiveDescription
cy# [UIApp.keyWindow recursiveDescription]
......
cy# [UIApp.keyWindow recursiveDescription].toString()
......
  • 由于输出太多我就不贴了,跟上面 iOS 中一样,一层一层的列出来。一种是递归列出所有子控件,一种是将列出的子控件转成字符串输出,两者没什么区别,就是排版的区别,都可以。

七、choose 删选出指定类型的对象

  • 意思是:指定一个类,只要是继承或者等于这个类的都会被列出来,只会列出已加载到缓存中。
  • 例如 UIViewController,列出当前已加载到缓存是继承或者直接使用 UIViewController 的,网易云首页举例
cy# choose(UIViewController)
  • 输出:
    [#"<NMVoiceHomeViewController: 0x11a400200>",#"<NMSettingTabViewController: 0x11a404020>",#"<NMSingTabViewController: 0x11a407540>",#"<NMContainerViewController: 0x11a409ce0>",#"<NMContainerViewController: 0x11a414d60>",#"<NMMainViewController: 0x10a6d8780>",#"<NMContainerViewController: 0x10a5f5220>",#"<NMMineTabViewController: 0x10a5f6910>",#"<NMContainerViewController: 0x11a519390>",#"<NMContainerViewController: 0x11a52f3f0>",#"<NMTabBarController: 0x10b946000>",#"<NMNavigationController: 0x10b9a7000>",#"<NMNavigationController: 0x10b9cc400>",#"<NMNavigationController: 0x10b9d6c00>",#"<NMNavigationController: 0x10b9e0200>",#"<NMNavigationController: 0x10b9ea600>",#"<NMNavigationController: 0x10a83f400>",#"<NMRootNavigationController: 0x10a8cd400>",#"<NMNavigationController: 0x10a8e7200>",#"<NMNavigationController: 0x10a912a00>",#"<NMNavigationController: 0x10a919c00>",#"<NMNavigationController: 0x10a975800>"]
    上面这些就是当前软件已经加载到缓存的控制器,且都是继承或者等于 UIViewController
    如果一个都没有则为空数组,如果输出崩溃,则重新进入调试模式即可:
cy# choose(UITableViewCell)
[]
  • 现在只是语法大致了解一下,后面会通过 Cycript 写一些脚本用来快捷调试,比如:拿到当前正在显示的控制器,这个就可以充利用上面的属性获取方式以及 iOS 开发中的获取控制器方式配合来获取了。
  • 后面会写到封装这样一个脚本,毕竟这个会很方便的帮我们找到当前控制器,也就知道在哪个文件可以做调整了。

相关文章
|
1月前
|
开发框架 移动开发 Android开发
安卓与iOS开发中的跨平台解决方案:Flutter入门
【9月更文挑战第30天】在移动应用开发的广阔舞台上,安卓和iOS两大操作系统各自占据半壁江山。开发者们常常面临着选择:是专注于单一平台深耕细作,还是寻找一种能够横跨两大系统的开发方案?Flutter,作为一种新兴的跨平台UI工具包,正以其现代、响应式的特点赢得开发者的青睐。本文将带你一探究竟,从Flutter的基础概念到实战应用,深入浅出地介绍这一技术的魅力所在。
77 7
|
2月前
|
Swift iOS开发 UED
揭秘一款iOS应用中令人惊叹的自定义动画效果,带你领略编程艺术的魅力所在!
【9月更文挑战第5天】本文通过具体案例介绍如何在iOS应用中使用Swift与UIKit实现自定义按钮动画,当用户点击按钮时,按钮将从圆形变为椭圆形并从蓝色渐变到绿色,释放后恢复原状。文中详细展示了代码实现过程及动画平滑过渡的技巧,帮助读者提升应用的视觉体验与特色。
61 11
|
3月前
|
开发工具 C语言 Swift
探索iOS开发之旅:从入门到精通
【8月更文挑战第30天】在这篇文章中,我们将一起踏上一场关于iOS开发的奇妙旅程。无论你是刚刚接触iOS开发的新手,还是希望提升自己技能的开发者,这篇文章都将为你提供有价值的指导和启示。我们将从基础的iOS开发概念开始,逐步深入到高级技巧和最佳实践。通过这篇文章,你将了解到如何构建一个成功的iOS应用程序,以及如何不断提升自己的开发技能。让我们一起开启这场探索之旅吧!
57 4
|
3月前
|
Swift iOS开发 UED
【绝妙创意】颠覆你的视觉体验!揭秘一款iOS应用中令人惊叹的自定义动画效果,带你领略编程艺术的魅力所在!
【8月更文挑战第13天】本文通过一个具体案例,介绍如何使用Swift与UIKit在iOS应用中创建独特的按钮动画效果。当按钮被按下时,其形状从圆形变化为椭圆形,颜色则从蓝色渐变为绿色;释放后,动画反向恢复原状。利用UIView动画方法及弹簧动画效果,实现了平滑自然的过渡。通过调整参数,开发者可以进一步优化动画体验,增强应用的互动性和视觉吸引力。
51 7
|
3月前
|
安全 测试技术 调度
iOS开发-多线程编程
【8月更文挑战第12天】在iOS开发中,属性的内存管理至关重要,直接影响应用性能与稳定性。主要策略包括:`strong`(强引用),保持对象不被释放;`weak`(弱引用),不保持对象,有助于避免循环引用;`assign`(赋值),适用于基本数据类型及非指针对象类型;`copy`(复制),复制对象而非引用,确保不变性。内存管理基于引用计数,利用自动引用计数(ARC)自动管理对象生命周期。此外,需注意避免循环引用,特别是在block中。最佳实践包括理解各策略、避免不必要的强引用、及时释放不再使用的对象、注意block中的内存管理,并使用工具进行内存分析。正确管理内存能显著提升应用质量。
|
4月前
|
移动开发 开发工具 Android开发
探索安卓与iOS开发的差异:平台特性与编程实践
【7月更文挑战第8天】在移动开发的广阔天地中,安卓和iOS这两大操作系统各自占据着半壁江山。它们在用户界面设计、系统架构及开发工具上展现出截然不同的特色。本文将深入探讨这两个平台在技术实现和开发生态上的关键差异,并分享一些实用的开发技巧,旨在为跨平台开发者提供有价值的见解和建议。
|
4月前
|
IDE 开发工具 Android开发
安卓与iOS开发环境对比分析:选择适合自己的编程平台
移动应用开发的两大阵营——安卓和iOS,各自拥有不同的开发环境和工具集。本文通过深入比较这两个平台的编程语言、集成开发环境(IDE)、用户界面设计、测试框架以及部署流程,旨在为开发者提供一个全面的视角来选择最符合个人或项目需求的开发环境。
|
1月前
|
Java Android开发 Swift
安卓与iOS开发对比:平台选择对项目成功的影响
【10月更文挑战第4天】在移动应用开发的世界中,选择合适的平台是至关重要的。本文将深入探讨安卓和iOS两大主流平台的开发环境、用户基础、市场份额和开发成本等方面的差异,并分析这些差异如何影响项目的最终成果。通过比较这两个平台的优势与挑战,开发者可以更好地决定哪个平台更适合他们的项目需求。
110 1
|
7天前
|
安全 数据处理 Swift
深入探索iOS开发中的Swift语言特性
本文旨在为开发者提供对Swift语言在iOS平台开发的深度理解,涵盖从基础语法到高级特性的全面分析。通过具体案例和代码示例,揭示Swift如何简化编程过程、提高代码效率,并促进iOS应用的创新。文章不仅适合初学者作为入门指南,也适合有经验的开发者深化对Swift语言的认识。
25 9