七 iOS逆向 - Cycript

  • Cycript简介
  • Cycript基本使用
  • 封装Cycript脚本
  • Cycript使用示例
一 Cycript简介

Cycript允许开发人员使用Objective-C ++和JavaScript语法的混合,通过具有语法突出显示和制表符完成功能的交互式控制台,可以用来探索、修改、调试正在运行的Mac\iOS APP
(它还可以在Android和Linux上独立运行,并提供对Java的访问,但不需要注入。)
Cycript 官方网址http://www.cycript.org

通过Cydia安装Cycript,即可在iPhone上调试运行中的APP,安装步骤如下图

然后我们登录到手机就可以使用了

applede-iPhone:~ root# cy
cycc     cycript  cynject
applede-iPhone:~ root# cycript
cy# 1+1
2
cy#

通过安装界面我们可以知道Cycript是由Jay Freeman开发的,没错他就是Cydia的作者,Cycript主要用来探索、修改、调试正在运行的Mac\iOS APP的,现在工具我们已经安装好了,那么我们该怎么去调试一个iOS App应用呢?我们接着往下看。

二 Cycript基本使用

下面我们以调试一个爱奇艺app来看一下它的简单使用流程

2.1 使用流程
步骤一 安装adv-cmds,为了查看进程需要ps命令,所以需要安装这个插件
手机上安装这个插件
步骤二 查找爱奇艺这个应用的进程,前提是你的手机要打开这个应用
applede-iPhone:~ root# ps -A
  PID TTY           TIME CMD
    1 ??         7:45.21 /sbin/launchd
   21 ??         0:58.51 /usr/sbin/syslogd
   42 ??         3:58.87 /usr/libexec/logd
  685 ??         0:14.17 /System/Library/PrivateFrameworks/AssistantServices.framework/assistantd
  687 ??         0:34.87 /usr/libexec/fseventsd
  689 ??         1:07.56 /usr/sbin/mediaserverd
  695 ??         0:31.61 /usr/libexec/routined
  699 ??         0:59.72 /usr/libexec/configd
  701 ??         0:06.32 /System/Library/Frameworks/HealthKit.framework/healthd
  703 ??         1:38.31 /System/Library/CoreServices/powerd.bundle/powerd
  711 ??         0:04.43 /usr/libexec/keybagd -t 15
  719 ??         1:22.97 /usr/sbin/wifid
  725 ??         0:47.07 /System/Library/PrivateFrameworks/IDS.framework/identityservicesd.app/identityservicesd
  741 ??         0:00.73 /usr/sbin/wirelessproxd
  745 ??         0:06.65 /usr/libexec/sharingd
  747 ??         0:21.23 /usr/libexec/timed
  749 ??        21:19.84 /usr/libexec/locationd
  751 ??         0:04.53 /usr/sbin/BTServer
  753 ??         0:14.06 /System/Library/PrivateFrameworks/IMCore.framework/imagent.app/imagent
  755 ??         0:20.56 /usr/libexec/assertiond
  759 ??         0:00.25 /usr/libexec/tipsd
  761 ??         8:39.53 /usr/libexec/UserEventAgent (System)
  763 ??         7:22.66 /usr/libexec/lockdownd
  767 ??         0:31.36 /System/Library/PrivateFrameworks/IAP.framework/Support/iaptransportd
  779 ??         0:09.82 /usr/sbin/fairplayd.H2
  781 ??         9:36.63 /System/Library/Frameworks/CoreTelephony.framework/Support/CommCenter
  792 ??         2:58.75 /usr/sbin/notifyd
  808 ??         1:42.85 /usr/sbin/cfprefsd daemon
  811 ??         1:09.30 /usr/sbin/distnoted daemon
  813 ??         1:05.38 /usr/libexec/lsd
  833 ??         0:11.55 /System/Library/PrivateFrameworks/WirelessDiagnostics.framework/Support/awdd
  836 ??         8:35.88 /usr/libexec/securityd
  840 ??         4:08.65 /usr/libexec/nehelper
  842 ??         0:01.53 /usr/sbin/WirelessRadioManagerd
  847 ??         2:46.70 /usr/libexec/coreduetd
  858 ??         0:38.76 /usr/libexec/lockbot
  868 ??         3:20.95 /System/Library/PrivateFrameworks/ApplePushService.framework/apsd
  877 ??         1:16.26 /usr/libexec/hangtracerd
  891 ??        11:34.58 /System/Library/Frameworks/Accounts.framework/accountsd
  895 ??         0:38.13 /System/Library/PrivateFrameworks/iTunesStore.framework/Support/itunesstored
  907 ??         0:02.71 /System/Library/PrivateFrameworks/TCC.framework/tccd
  915 ??         0:57.96 /usr/sbin/mDNSResponder
  918 ??         0:35.55 /usr/libexec/nsurlsessiond
  931 ??         0:14.15 /System/Library/PrivateFrameworks/TelephonyUtilities.framework/callservicesd
  936 ??         1:03.62 /usr/libexec/DuetHeuristic-BM
  939 ??         0:28.37 /usr/libexec/nsurlstoraged
  948 ??         1:28.61 /usr/libexec/symptomsd
  976 ??         1:07.50 /usr/libexec/nesessionmanager
  980 ??         0:08.33 /System/Library/TextInput/kbd
  983 ??         0:38.32 /System/Library/PrivateFrameworks/DataAccess.framework/Support/dataaccessd
  989 ??         0:01.93 /usr/libexec/biometrickitd --launchd
 1015 ??         1:25.70 /System/Library/PrivateFrameworks/CloudDocsDaemon.framework/bird
 1036 ??         2:55.34 /System/Library/PrivateFrameworks/CloudKitDaemon.framework/Support/cloudd
 1048 ??         0:07.45 /System/Library/PrivateFrameworks/ManagedConfiguration.framework/Support/profiled
 1055 ??         0:03.77 /System/Library/PrivateFrameworks/UserActivity.framework/Agents/useractivityd
 1061 ??         0:09.41 /usr/libexec/duetexpertd
 1078 ??         0:00.05 /usr/libexec/captiveagent
 1098 ??         0:00.25 /usr/sbin/filecoordinationd
 1141 ??         0:08.62 /System/Library/PrivateFrameworks/AssetCacheServices.framework/XPCServices/AssetCacheLocatorService.xpc/AssetCacheLocatorService -d
 1601 ??         0:00.56 /usr/libexec/afcd
 1868 ??         0:09.41 /usr/libexec/notification_proxy
 2105 ??         2:15.42 /System/Library/PrivateFrameworks/PhotoAnalysis.framework/Support/photoanalysisd
 4026 ??         0:00.63 /usr/libexec/dprivacyd
15319 ??         0:09.81 /System/Library/PrivateFrameworks/AppStoreDaemon.framework/appstored.bundle/appstored
15382 ??         0:22.13 /usr/libexec/atc
15451 ??         0:02.88 /System/Library/PrivateFrameworks/CoreParsec.framework/parsecd
15460 ??         0:02.48 /System/Library/PrivateFrameworks/GeoServices.framework/geod
19001 ??         0:41.82 /System/Library/PrivateFrameworks/MobileContainerManager.framework/Support/containermanagerd
19007 ??         0:11.98 /System/Library/PrivateFrameworks/AuthKit.framework/akd
19013 ??         0:01.89 /usr/libexec/adid
20825 ??         0:02.16 /usr/libexec/pkd
21158 ??         0:26.20 /usr/libexec/mobileassetd
21179 ??         0:01.93 /System/Library/PrivateFrameworks/CoreSuggestions.framework/suggestd
22153 ??         1:05.72 /System/Library/PrivateFrameworks/AggregateDictionary.framework/Support/aggregated
22795 ??         0:07.83 /System/Library/PrivateFrameworks/AssistantServices.framework/assistant_service
22818 ??         0:03.37 /System/Library/PrivateFrameworks/CalendarDaemon.framework/Support/calaccessd
23001 ??         0:00.01 /usr/libexec/rocketd
23003 ??         0:00.02 /usr/local/bin/dropbear -F -R -p 127.0.0.1:22
23061 ??         0:03.90 /System/Library/PrivateFrameworks/Search.framework/searchd
23145 ??         0:00.79 /usr/libexec/mobileactivationd
23157 ??         0:00.30 /System/Library/CoreServices/EscrowSecurityAlert.app/EscrowSecurityAlert
23161 ??         0:00.08 /usr/libexec/online-auth-agent
23164 ??         0:00.92 /System/Library/PrivateFrameworks/PassKitCore.framework/passd
23166 ??         0:00.96 /System/Library/PrivateFrameworks/CacheDelete.framework/deleted
23168 ??         0:01.18 /System/Library/PrivateFrameworks/MusicLibrary.framework/Support/medialibraryd
23175 ??         0:00.09 /usr/libexec/OTATaskingAgent server-init
23178 ??         0:01.95 /System/Library/CoreServices/CacheDeleteDaily
23180 ??         0:00.28 /usr/bin/sysdiagnose
23185 ??         0:00.18 /System/Library/PrivateFrameworks/GenerationalStorage.framework/revisiond
23187 ??         0:00.38 /System/Library/PrivateFrameworks/QuickLookThumbnailing.framework/Support/com.apple.quicklook.ThumbnailsAgent
23189 ??         0:07.65 /System/Library/Frameworks/AssetsLibrary.framework/Support/assetsd
23191 ??         0:00.19 /usr/libexec/replayd
23193 ??         0:00.09 /System/Library/PrivateFrameworks/CoreSymbolication.framework/coresymbolicationd
23195 ??         0:00.65 /System/Library/PrivateFrameworks/Pasteboard.framework/Support/pasted
23205 ??         0:00.85 /System/Library/PrivateFrameworks/CloudServices.framework/XPCServices/com.apple.sbd.xpc/com.apple.sbd
23208 ??         0:11.63 /usr/libexec/gamed
23211 ??         0:00.06 /System/Library/PrivateFrameworks/CloudDocsDaemon.framework/XPCServices/ContainerMetadataExtractor.xpc/ContainerMetadataExtractor
23214 ??         0:00.53 /usr/libexec/webbookmarksd
23216 ??         0:00.22 aslmanager
23219 ??         0:00.27 /System/Library/CoreServices/CacheDeleteITunesStore
23221 ??         0:02.55 /System/Library/CoreServices/CacheDeleteAppContainerCaches
23295 ??         0:00.06 /usr/sbin/absd
23304 ??         0:00.76 /usr/libexec/mmaintenanced
23312 ??         0:00.21 /usr/libexec/diagnosticd
23333 ??         0:00.03 /usr/libexec/misagent
23336 ??         0:00.21 /System/Library/PrivateFrameworks/IMDPersistence.framework/XPCServices/IMDPersistenceAgent.xpc/IMDPersistenceAgent
23421 ??         0:00.08 /usr/libexec/MobileGestaltHelper
23424 ??         0:00.46 /usr/libexec/ptpd -t usb
23430 ??         0:00.04 /usr/libexec/mobile_assertion_agent
23436 ??         0:34.01 /usr/libexec/installd
23437 ??         0:00.00 (MSUnrestrictProc)
23439 ??         0:00.95 /System/Library/PrivateFrameworks/MobileInstallation.framework/XPCServices/com.apple.MobileInstallationHelperService.xpc/com.apple.Mobi
23444 ??         0:01.00 /usr/libexec/mobile_installation_proxy
23450 ??         0:00.27 /usr/libexec/pipelined
23454 ??         0:00.37 /System/Library/PrivateFrameworks/MapsSupport.framework/mapspushd
23463 ??         0:00.15 /Applications/Contacts.app/PlugIns/ContactsCoreSpotlightExtension.appex/ContactsCoreSpotlightExtension
23466 ??         0:00.18 /System/Library/PrivateFrameworks/MediaRemote.framework/Support/mediaremoted
23481 ??         0:00.03 /usr/libexec/afc2d -S -L -d /
23841 ??         0:00.08 /usr/libexec/misd
23844 ??         0:00.02 /usr/libexec/pfd
23871 ??         0:00.27 /System/Library/PrivateFrameworks/VisualVoicemail.framework/vmd
23874 ??         0:03.14 /System/Library/PrivateFrameworks/SoftwareUpdateServices.framework/Support/softwareupdateservicesd
24701 ??         0:17.31 /System/Library/CoreServices/SpringBoard.app/SpringBoard
24703 ??         0:28.49 /usr/libexec/backboardd
24740 ??         0:00.07 /System/Library/PrivateFrameworks/UIFoundation.framework/XPCServices/com.apple.uifoundation-bundle-helper.xpc/com.apple.uifoundation-bu
24830 ??         0:00.93 /System/Library/PrivateFrameworks/AssistantServices.framework/XPCServices/com.apple.siri.ClientFlow.ClientScripter.xpc/com.apple.siri.C
24878 ??         0:00.87 /System/Library/PrivateFrameworks/NanoTimeKitCompanion.framework/nanotimekitcompaniond
24905 ??         0:01.82 /System/Library/PrivateFrameworks/Accessibility.framework/Frameworks/AccessibilityUI.framework/XPCServices/com.apple.accessibility.Acce
25826 ??         0:09.35 /Applications/Cydia.app/Cydia
26128 ??         0:28.02 /var/containers/Bundle/Application/50D7ECBF-5F64-44A7-940F-22D884E16BE8/iQiYiPhoneVideo.app/iQiYiPhoneVideo
26130 ??         0:00.38 /System/Library/Frameworks/WebKit.framework/XPCServices/com.apple.WebKit.Networking.xpc/com.apple.WebKit.Networking
26132 ??         0:00.70 /System/Library/Frameworks/WebKit.framework/XPCServices/com.apple.WebKit.WebContent.xpc/com.apple.WebKit.WebContent
26139 ??         0:00.50 /System/Library/PrivateFrameworks/MobileBackup.framework/backupd
26144 ??         0:00.17 /usr/local/bin/dropbear -F -R -p 127.0.0.1:22
26145 ttys000    0:00.04 -sh
26148 ttys000    0:00.01 ps -A

调用ps -A查看手机上运行的所有进程,一般我们最近打开的应用都在最后面,我们看后面几条,就找到一条这个

26128 ??         0:28.02 /var/containers/Bundle/Application/50D7ECBF-5F64-44A7-940F-22D884E16BE8/iQiYiPhoneVideo.app/iQiYiPhoneVideo
步骤三 我们拿到iQiYiPhoneVideo这个名称开始进入调试
applede-iPhone:~ root# cycript -p iQiYiPhoneVideo
cy#
步骤四 打印一下爱奇艺应用的基本信息,我们接着输入,我们打印爱奇艺的bundle id ,和appName
cy# [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleIdentifier"]
@"com.qiyi.iphone"
cy#  [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleDisplayName"];
@"\xe7\x88\xb1\xe5\xa5\x87\xe8\x89\xba"
cy#  [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleDisplayName"];

名字打出来的是字节类型了,我们用python转化打印一下

xmldeMacBook-Pro:~ xml$ python
Python 2.7.10 (default, Aug 17 2018, 17:41:52)
[GCC 4.2.1 Compatible Apple LLVM 10.0.0 (clang-1000.0.42)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> print '\xe7\x88\xb1\xe5\xa5\x87\xe8\x89\xba'
爱奇艺
>>>

我们今后调试应用的时候基本就是这个流程,先找到你要调试的app的进程,然后开启Cycript,最后开始调试,你发现我们输入的OC语法基本都支持,就跟我们平时开发一样,下面我们了解一下Cycript的一些基本语法

2.2 Cycript基本语法

注意:调试的过程中调试的app一定是在打开前台状态,手机也不能熄屏,否者调试会卡住。
1 常量语法,UIApp

cy# UIApp
#"<UIApplication: 0x106b693e0>"
cy# UIApp.key
keyCommands  keyWindow
cy# UIApp.keyWindow
#"<UIWindow: 0x106b87880>Frame: (0.000000, 0.000000, 320.000000, 568.000000)\ttag:0"
cy# UIApp.keyWindow.rootViewController
#"<RootViewController: 0x1070d7400>"
cy#

2 定义变量 var 变量名 = 变量值

cy# var rootController = UIApp.keyWindow.rootViewController
#"<RootViewController: 0x1070d7400>"
cy# rootController.view
#"<UIView: 0x10672d380>Frame: (0.000000, 0.000000, 320.000000, 568.000000)\ttag:0"
cy#

3 用内存地址获取对象,#+内存地址

cy# #0x10672d380
#"<UIView: 0x10672d380>Frame: (0.000000, 0.000000, 320.000000, 568.000000)\ttag:0"

4 查看已加载所有OC类 ObjectiveC.classes

cy# ObjectiveC.classes
//打印的东西太多了,就不贴出来了

5 查看对象的所有成员变量 *+对象

cy# *UIApp
{isa:UIApplication,_hasOverrideClient:false,_hasOverrideHost:false,_hasInputAssistantItem:false,_delegate:#"<AppDelegate: 0x11fd2e1d0>",_exclusiveTouchWindows:[NSSet setWithArray:@[]]],_event:#"<UIEvent: 0x17402c0e0>",_motionEvent:#"<UIMotionEvent: 0x1741663c0> timestamp: 0 subtype: 0",_remoteControlEvent:#"<UIRemoteControlEvent: 0x1700541f0>",_remoteControlEventObservers:0,_topLevelNibObjects:null,_networkResourcesCurrentlyLoadingCount:0,_hideNetworkActivityIndicatorTimer:null,_editAlertView:null,_statusBar:#"<UIStatusBar: 0x120842a00>Frame: (0.000000, 0.000000, 320.000000, 20.000000)\ttag:0",_statusBarRequestedStyle:1,_statusBarWindow:#"<UIStatusBarWindow: 0x11fd2eec0>Frame: (0.000000, 0.000000, 320.000000, 568.000000)\ttag:0",_observerBlocks:@[],_postCommitActions:@[],_postCommitActionsNeedToSynchronize:false,_mainStoryboardName:null,_tintViewDurationStack:null,_statusBarTintColorLockingControllers:null,_statusBarTintColorLockingCount:0,_idleModeController:null,_displayLayoutMonitor:null,_normativeWhitePointAdaptivityStyle:0,_eventFetcher:#"<UIEventFetcher: 0x1700c2ed0>",_eventDispatcher:#"<UIEventDispatcher: 0x170054220>",_applicationFlags:@error,_defaultTopNavBarTintColor:null,_undoButtonIndex:0,_redoButtonIndex:0,_moveEvent:#"<UIMoveEvent: 0x170054040>",_physicalKeyCommandMap:@{},_physicalKeycodeMap:[NSOrderedSet orderedSetWithArray:@[]]],_alwaysHitTestsForMainScreen:false,_backgroundHitTestWindow:null,_classicMode:0,_ignoredStyleOverrides:0,_externalDeactivationReasons:0,_actionsPendingInitialization:null,_idleTimerDisabledReasons:@error,_keyRepeatAction:null,_currentTimestampWhenFirstTouchCameDown:0,_currentLocationWhereFirstTouchCameDown:{x:0,y:0},_sceneSettingsPreLifecycleEventDiffInspector:#"<UIApplicationSceneSettingsDiffInspector: 0x17402d640> {\n    observerInfo = <BSMutableSettings: 0x17402c8a0> { };\n    otherSettingsObserverInfo = <BSMutableSettings: 0x17402cf00> {\n        (3) = (\n    \"<__NSMallocBlock__: 0x174057f10>\"\n);\n    };\n}",_sceneSettingsPostLifecycleEventDiffInspector:#"<UIApplicationSceneSettingsDiffInspector: 0x17402cf80> {\n    observerInfo = <BSMutableSettings: 0x17402d2e0> { };\n    otherSettingsObserverInfo = <BSMutableSettings: 0x17402cfa0> {\n        (2) = (\n    \"<__NSMallocBlock__: 0x174058000>\"\n);\n        (3) = (\n    \"<__NSMallocBlock__: 0x174058090>\"\n);\n        (4) = (\n    \"<__NSMallocBlock__: 0x174058240>\"\n);\n        (5) = (\n    \"<__NSMallocBlock__: 0x174058120>\"\n);\n        (7) = (\n    \"<__NSMallocBlock__: 0x174058360>\"\n);\n        (8) = (\n    \"<__NSMallocBlock__: 0x1740582d0>\"\n);\n        (10) = (\n    \"<__NSMallocBlock__: 0x1740581b0>\"\n);\n    };\n}",_sceneSettingsGeometryMutationDiffInspector:#"<UIApplicationSceneSettingsDiffInspector: 0x17402cf20> {\n    observerInfo = <BSMutableSettings: 0x17402c880> {\n        (2) = (\n    \"<__NSGlobalBlock__: 0x1b29935e0>\"\n);\n        (4) = (\n    \"<__NSGlobalBlock__: 0x1b2993620>\"\n);\n    };\n    otherSettingsObserverInfo = <BSMutableSettings: 0x17402c7c0> { };\n}",_saveStateRestorationArchiveWithFileProtectionCompleteUntilFirstUserAuthentication:false,_fenceTaskAssertion:null,_cachedSystemAnimationFence:null,_systemNavigationAction:null,_activityContinuationManager:#"<UIActivityContinuationManager: 0x170056e90>",__gestureEnvironment:#"<UIGestureEnvironment: 0x1700c1500>",_forceStageObservable:null,_HIDGameControllerEventObserver:null,_HIDGameControllerEventQueue:null,_motionEventBehavior:null,optOutOfRTL:false,_isDisplayingActivityContinuationUI:false,_lastTimestampWhenFirstTouchCameDown:0,_lastTimestampWhenAllTouchesLifted:0,_virtualHorizontalSizeClass:0,_virtualVerticalSizeClass:0,_shortcutService:null,___queuedOrientationChange:null,__expectedViewOrientation:1,_lastLocationWhereFirstTouchCameDown:{x:0,y:0},_lastLocationWhereAllTouchesLifted:{x:0,y:0},_virtualWindowSizeInSceneReferenceSpace:{width:320,height:568}}
cy#

6 递归打印view的所有子控件
** 注意这里的对象只能是view或其子对象,其他对象报错**

cy# rootController.view.recursiveDescription().toString()
`<UIView: 0x106c6fdd0>Frame: (0.000000, 0.000000, 320.000000, 568.000000)\ttag:0
   | <UIView: 0x11ac308b0>Frame: (0.000000, 0.000000, 320.000000, 568.000000)\ttag:0
   |    | <NotesView: 0x11ab2ea30>Frame: (0.000000, 64.000000, 320.000000, 504.000000)\ttag:0
   |    |    | <SPActivityIndicatorView: 0x11ab2cd20>Frame: (150.000000, 306.000000, 20.000000, 20.000000)\ttag:0
   |    |    |    | <UIView: 0x11ab2ec40>Frame: (0.000000, 0.000000, 20.000000, 20.000000)\ttag:0
   |    |    |    |    | <CAShapeLayer: 0x1746216c0> (layer)
   |    |    |    |    |    | <CAShapeLayer: 0x1746216e0> (layer)
   |    |    |    |    |    |    | <CAShapeLayer: 0x174621840> (layer)
   |    |    |    |    |    |    | <CAShapeLayer: 0x174621860> (layer)
   |    |    |    |    | <CAShapeLayer: 0x174621700> (layer)
   |    |    |    |    | <CAShapeLayer: 0x1746217a0> (layer)
   |    |    | <UILabel: 0x11ab2ca90>Frame: (20.000000, 231.000000, 320.000000, 20.000000)\ttag:0
   |    |    |    | <_UILabelContentLayer: 0x170631c40> (layer)
   |    |    | <UIButton: 0x11ab2c170>Frame: (26.000000, 261.000000, 120.500000, 40.500000)\ttag:0
   |    | <UIView: 0x11ac36580>Frame: (0.000000, 0.000000, 320.000000, 568.000000)\ttag:0

7 筛选出某种类型的对象 choose(object)

cy# choose(UIViewController)
[#"<QYPlayRecordMessageController: 0x11e037960>",#"<QRFeedBackViewController: 0x11e068e50>",#"<QRFeedBackViewController: 0x11e06a1a0>",#"<QYPhonePlayerController: 0x118d7eb80>",#"<QYRecomChannelHomeViewController: 0x10785b800>",#"<RootViewController: 0x1078b9800>",#"<QYRecomChannelViewControllerV3: 0x10718fa00>",#"<QYPlayerViewController: 0x107276200>"]
cy#

一般常用语法就这么对,够用了,开发中一句一句敲代码还是挺麻烦的,如果我们要执行多行代码的就麻烦了,就得使用函数了,但是在命令行里敲还是麻烦,如果我们把常用的功能封装成一个工具类,到时候直接用就很方便了,下面我们看怎么封装一个Cycript脚本。

三 封装Cycript脚本
步骤一 新建一个.py文件
cycripttest.py
步骤二 随便找个编辑器进行编辑
(function(exports) {

    // app id
    AppId = [NSBundle mainBundle].bundleIdentifier;

    // mainBundlePath
    AppPath = [NSBundle mainBundle].bundlePath;

    // keyWindow
    KeyWid = function() {
        return UIApp.keyWindow;
    };

    // 根控制器
    RootVc =  function() {
        return UIApp.keyWindow.rootViewController;
    };

})(exports);

步骤三 将文件放到iphone/Device/usr/lib/cycript9.0/
通过ifunbox直接拖到iPhone相应文件目录下即可
步骤四 如何使用
applede-iPhone:~ root# cycript -p iQiYiPhoneVideo
cy# @import cycripttest
{}
cy# AppId
@"com.qiyi.iphone"
cy# AppPath
@"/var/containers/Bundle/Application/50D7ECBF-5F64-44A7-940F-22D884E16BE8/iQiYiPhoneVideo.app"
cy#
cy# KeyWid
function (){return UIApp.keyWindow}
cy# KeyWid()
#"<UIWindow: 0x143d41390>Frame: (0.000000, 0.000000, 320.000000, 568.000000)\ttag:0"
cy#

以上就是脚本的编写和使用过程,今后你直接将你需要的功能放到这个脚本里面就好了,如果你正在调试一个app,如果脚本变动了,需要退出app,重新进入调试,为了防止冲突,这个脚本你也可以放到cycript9.0/你自定义的目录下比如cycript9.0/com/xu/cycripttest.py,但是引入的时候你也需要改变一下 @import com.xu.cycripttest

四 Cycript使用示例。

我们用户网易云音乐的界面来练习cycript如何操作输入文本框,以及处理按钮点击等操作。


网易云音乐登录页面
1 先定位登录页面
applede-iPhone:~ root# cycript -p neteasemusic
cy# @import mjcript     //这里使用MJ封装的脚本库,网上有的
{}
cy# MJFrontVc
function (){return s(UIApp.keyWindow.rootViewController)}
cy# MJFrontVc()
#"<NMPhoneLoginViewController: 0x11a57a050>"

我们定位到登录页面是NMPhoneLoginViewController: 0x11a57a050,接下来我们要定位手机号输入框

2 从NMPhoneLoginViewController,view的子view去查找手机号编辑框
cy# MJSubviews(#0x11a57a050)
throw new Error("Invalid parameter") /*
    MJSubviews */
cy# MJSubviews(#0x11a57a050.view)
`<NMPhoneLoginView: 0x118b18e50; frame = (0 0; 320 568); gestureRecognizers = <NSArray: 0x170842490>; layer = <CALayer: 0x170234b00>>
   | <UIView: 0x118b25d10; frame = (16 79; 288 86); layer = <CALayer: 0x170233ca0>>
   |    | <FXIconTextField: 0x11c8eef00; baseClass = UITextField; frame = (0 0; 288 43); text = ''; opaque = NO; autoresize = H; tintColor = UIExtendedSRGBColorSpace 0 0 0.00392157 0.5; gestureRecognizers = <NSArray: 0x17464ab60>; layer = <CALayer: 0x170233da0>>
   |    |    | <UIView: 0x103fb05b0; frame = (0 42; 288 0.5); userInteractionEnabled = NO; layer = <CALayer: 0x170233a20>>
   |    |    | <UITextFieldLabel: 0x103fb0750; frame = (31 0; 257 42.5); text = '\u624b\u673a\u53f7'; opaque = NO; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x170880f50>>
   |    |    |    | <_UILabelContentLayer: 0x170633520> (layer)
   |    |    | <UIFieldEditor: 0x104bbc000; frame = (31 0; 257 43); text = ''; clipsToBounds = YES; opaque = NO; gestureRecognizers = <NSArray: 0x170645400>; layer = <CALayer: 0x170232940>; contentOffset: {0, 0}; contentSize: {257, 43}>
   |    |    |    | <_UIFieldEditorContentView: 0x118b25060; frame = (0 0; 257 43); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x170827380>>
   |    |    |    |    | <UITextSelectionView: 0x11a5bc270; frame = (0 0; 0 0); userInteractionEnabled = NO; layer = <CALayer: 0x17423c240>>
   |    |    |    |    |    | <UIView: 0x118b37270; frame = (0 10; 2 22); alpha = 0; userInteractionEnabled = NO; animations = { opacity=<CABasicAnimation: 0x17022cca0>; }; layer = <CALayer: 0x170827b20>>
   |    |    | <UIView: 0x118b35990; frame = (0 -1; 31 45); layer = <CALayer: 0x170233dc0>>
   |    |    |    | <UIImageView: 0x118b1f790; frame = (2 12.5; 20 20); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x170233d80>>
   |    | <FXIconTextField: 0x103fb09e0; baseClass = UITextField; frame = (0 43; 288 43); text = ''; opaque = NO; tintColor = UIExtendedSRGBColorSpace 0 0 0.00392157 0.5; gestureRecognizers = <NSArray: 0x174853b90>; layer = <CALayer: 0x170233760>>
   |    |    | <UIView: 0x103faa5a0; frame = (0 42; 288 0.5); userInteractionEnabled = NO; layer = <CALayer: 0x170233440>>
   |    |    | <UIView: 0x103fafd10; frame = (0 -1; 31 45); layer = <CALayer: 0x170233520>>
   |    |    |    | <UIImageView: 0x103fafeb0; frame = (2 12.5; 20 20); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x170233500>>
   |    |    | <UITextFieldLabel: 0x103faa740; frame = (31 0; 257 42.5); text = '\u5bc6\u7801'; opaque = NO; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x17029ae50>>
   |    |    |    | <_UILabelContentLayer: 0x17423bea0> (layer)
   | <UIButton: 0x103fa8710; frame = (16 195; 288 40); clipsToBounds = YES; opaque = NO; layer = <CALayer: 0x1702331c0>>
   |    | <UIImageView: 0x104290520; frame = (0 0; 288 40); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x17423c340>>
   |    | <UIButtonLabel: 0x118b18300; frame = (126.5 10; 35 20.5); text = '\u767b\u5f55'; opaque = NO; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x17029ab30>>
   |    |    | <_UILabelContentLayer: 0x17423c180> (layer)
   | <NMPasswordButton: 0x103fa89d0; baseClass = UIButton; frame = (125 255; 70 25); opaque = NO; layer = <CALayer: 0x170233020>>
   |    | <UIButtonLabel: 0x103fa8ca0; frame = (6.5 4; 57.5 17); text = '\u91cd\u8bbe\u5bc6\u7801'; opaque = NO; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x17029a8b0>>
   |    |    | <_UILabelContentLayer: 0x17423c320> (layer)
   |    | <UIView: 0x103f4a460; frame = (6 23; 58 1); layer = <CALayer: 0x17022f1c0>>`
cy#

我们看到有这么一行


那么这个\u624b\u673a\u53f7是什么,我们用python打印一下看看

xmldeMacBook-Pro:~ xml$ python
Python 2.7.10 (default, Aug 17 2018, 17:41:52)
[GCC 4.2.1 Compatible Apple LLVM 10.0.0 (clang-1000.0.42)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> print u'\u624b\u673a\u53f7'
手机号
>>>

我们看到就是手机号,UITextFieldLabel: 0x103fb0750,就是它的对象,我们仔细看这个对象的父控件是FXIconTextField: 0x11c8eef00;从名称上看这是是一个自定义的带有图标的文本编辑框
那我们输入文本试一下

cy# #0x11c8eef00.text = "15856885688"
"15856885688"


输入命令回车,我们就发现手机界面立马就填上了手机号,那说明我们找的这个控件(FXIconTextField: 0x11c8eef00)就是编辑框了,
同理我们找出密码框,界面上他们是挨着的,我们通过打印的信息就能看到,下面也有一个FXIconTextField: 0x103fb09e0

这回我们不看里面子控件有没有密码lable,我们直接输文本看看界面有没有变化

cy# #0x103fb09e0.text = "123456"
"123456"


界面立马反应了,密码输入框变化了,那这里我们就找到了密码输入控件FXIconTextField: 0x103fb09e0

3 按钮登录

这里我们要找到按钮控件,然后触发它的点击事件,从界面上看登录按钮在密码框下面,我们在打印信息里往下看就行了,


靠猜测我们基本能判定UIButton: 0x103fa8710就是登录按钮,NMPasswordButton: 0x103fa89d0这个是找回密码按钮。接下来验证我们的猜测,我们触发按钮的点击事件。

cy# [#0x103fa8710  sendActionsForControlEvents:UIControlEventTouchUpInside]

我们看到界面上就有反应了,到此这三个控件就找到了,本节我们就演示了用过cycript定位控件。
总结:有些时候我们在查找控件大部分都是根据我们的经验去猜测判断,所以丰富的iOS开发经验,在逆向工程中是有很大帮助的。首先我们要根据UI页面结构,去猜测它的控件构成,然后一步步的去验证我们的猜想。最后我们再总结下定位界面元素有哪些步骤
1 找到当前页面的主控制器
2 打印控制器所有的子控件
3 根据UI结构和打印的子控件结构,去分析可能是哪个控件,( 有文本的情况下会乱码,我们用python,就能还原中文)
4 猜测是哪个控件,然后想办法去验证,改变文本,触发事件等等,然后看UI界面变化,有时候我们没找对的话,需要反复操作3,4步骤,直到找到为止。
当然了这只是cycript一个应用示例,其他使用还有带我们实际开发过程中,去总结,去探索。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,847评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,208评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,587评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,942评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,332评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,587评论 1 218
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,853评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,568评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,273评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,542评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,033评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,373评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,031评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,073评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,830评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,628评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,537评论 2 269

推荐阅读更多精彩内容