Cycript 是一個可以理解Objective-C語法的javascript解釋器, 它可以掛鉤正在運行的進程, 以在運行時修改不少東西, 通常咱們用於動態調試應用, 通常來講若是要調試的代碼是用OC編寫的,用cycript調試會很方便, 若是是用C編寫的,經過lldb來調試了.javascript
cy# @import com.saurik.substrate.MS
iPhone:/usr/lib/cycript0.9/com/saurik/substrate root# ls -lrt total 4 -rw-r--r-- 1 root staff 1968 Jan 11 2016 MS.cy
剛開始分析逆向的時候,經常利用它進行控制器class的定位,完成相似功能的工具備AFlexLoaderjava
cycript注入ios
cycript注入動態庫的方式,這必需要在越獄環境下才能實現。git
cycript的原理是動態庫注入,可是其動態庫注入的原理,與咱們常見的經過LC_LOAD_DYLIB在可執行文件中注入動態庫不一樣. cycript的操做是 : 抓取到要掛載的應用, 因爲越獄機上擁有權限,因此直接在掛載的進程上建立一個掛起的線程, 而後在這個線程裏申請一片用於加載動態庫的內存,而後恢復線程,動態庫就被注入。
二次打包動態庫的注入,是經過修改可執行文件的Load Commands來實現的. 在Load Commands中增長一個LC_LOAD_DYLIB , 寫入dylib路徑,這樣程序執行的時候, 就會編譯這個 LC_LOAD_DYLIB 找到要注入的 dylib,加載動態庫 .github
.toString()
#address
cy# [#0x1031f9b0] [#"<UILabel: 0x1031f9b0; frame = (32.5 236.738; 255 20.4378); text = '\xe5\xbc\x80\xe9\x80\x9a\xe6\x8c\x87\xe7\xba\xb9\xe6\x94\xaf\xe4\xbb\x98\xef\xbc\x8c\xe8\xae\xa9\xe4\xbb\x98\xe6\xac\xbe\xe6\x9b\xb4\xe5\xae\x89\xe5\x85\xa8\xe4\xbe\xbf\xe6\x8d\xb7'; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x1031f900>>"]
[[NSBundle mainBundle] bundleIdentifier]
[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask][0]
iPhone:~ root# ps -e |grep /var/mobile*
iPhone:~ root# cycript -p Moon
cy# [UIApp description] @"<DFApplication: 0x4870560>" cy# [#0x4870560 _ivarDescription].toString() `<DFApplication: 0x4870560>: in DFApplication: in UIApplication: \t_delegate (<UIApplicationDelegate>*): <DFClientDelegate: 0x4878510>
cy# [for (x of [1,2,3]) x+1] [2,3,4]
cy# choose(CALayer) instanceof Array true
cy# var a = malloc(128) (typedef void*)(0x8b00b90)
cy# a = ({m: 4, b: 5}) {m:4,b:5} cy# a["m"] 4
cy# [&](int a)->int{return a} (extern "C" int 80904192(int))
cy# UIApp.keyWindow.recursiveDescription().toString() `<UIWindow: 0x16df0a70; frame = (0 0; 320 568); gestureRecognizers = <NSArray: 0x16ec15a0>; layer = <UIWindowLayer: 0x16df0db0>> | <UILayoutContainerView: 0x16ecea00; frame = (0 0; 320 568); autoresize = W+H; layer = <CALayer: 0x16e0a3e0>> | | <UITransitionView: 0x16e09400; frame = (0 0; 320 568); clipsToBounds = YES; autoresize = W+H; layer = <CALayer: 0x16e09270>> | | | <UIViewControllerWrapperView: 0x1804b890; frame = (0 0; 320 568); autoresize = W+H; layer = <CALayer: 0x1802a180>> | | | | <UILayoutContainerView: 0x16f550d0; frame = (0 0; 320 568); autoresize = W+H; gestureRecognizers = <NSArray: 0x1803b010>; layer = <CALayer: 0x16f55180>> | | | | | <UINavigationTransitionView: 0x18037850; frame = (0 0; 320 568); clipsToBounds = YES; autoresize = W+H; layer = <CALayer: 0x180379a0>> | | | | | | <UIViewControllerWrapperView: 0x18075800; frame = (0 0; 320 568); autoresize = W+H; layer = <CALayer: 0x180758a0>> | | | | | | | <UIView: 0x181009f0; frame = (0 64; 320 504); autoresize = W+H; layer = <CALayer: 0x18100a80>> | | | | | | | | <UIView: 0x19316d10; frame = (0 0; 320 504); autoresize = W+H; layer = <CALayer: 0x19316ca0>> | | | | | | | | | <WXRootView: 0x182de340; frame = (0 0; 320 504); layer = <CALayer: 0x182dfcd0>> | | | | | | | | | | <WXView: 0x182ddb10; frame = (0 0; 320 504); layer = <WXLayer: 0x16deb050>> | | | | | | | | | | | <WXView: 0x182f8ae0; frame = (0 0; 320 0); layer = <WXLayer: 0x182db010>> | | | | | | | | | | | <WXView: 0x182dbc10; frame = (0 0; 320 29.5); layer = <WXLayer: 0x182e2c40>> | | | | | | | | | | | | <WXImageView: 0x182133a0; baseClass = UIImageView; frame = (13 6; 17 17); clipsToBounds = YES; opaque = NO; layer = <WXLayer: 0x182de5e0>> | | | | | | | | | | | | <WXText: 0x193435b0; text cy#
cy# [#0x181009f0 nextResponder] #"<MoonWXParentViewController: 0x18100e30>"
接下來就能夠對MoonWXParentViewController 進行hook分析web
Shortcut to find the ViewController’s class name on the keyWindowsegmentfault
快捷的獲取 ViewController 的方法。數組
cy# [[[UIWindow keyWindow] rootViewController] _printHierarchy].toString() `<DFNavigationController 0x5857400>, state: appeared, view: <UILayoutContainerView 0x8c1aa10> | <ALPLauncherController 0x876f370>, state: disappeared, view: <UILayoutContainerView 0x876f700> not in the window | | <HPHomeWidgetGroup 0x58a0800>, state: disappeared, view: <DTBaseView 0x87b1390> not in the window | | | <HCHomeCardViewController 0x592b000>, state: disappeared, view: <DTBaseView 0xc32ceb0> not in the window | | <O2OIndexViewController 0x4891a00>, state: disappeared, view: <DTBaseView 0x8ca2ed0> not in the window | | <APContactRecentViewController 0x4871e00>, state: disappeared, view: <DTBaseView 0x477c790> not in the window | | <WWAssetsViewController 0x58ad600>, state: disappeared, view: <DTBaseView 0x87c1820> not in the window | <H5WebViewController 0x5b3e400>, state: disappeared, view: <DTBaseView 0xfafb810> not in the window | <H5WebViewController 0x5b9d800>, state: disappeared, view: <DTBaseView 0x1104c140> not in the window | <H5WebViewController 0x5822600>, state: appeared, view: <DTBaseView 0xd8e9180>`
支持iOS8以後ruby
Prints all names and values of instance variables of a specified object
比一個一個打印屬性方便多了
cy# [#0x5822600 _ivarDescription].toString()
cy# [#0x5822600 _ivarDescription].toString() `<H5WebViewController: 0x5822600>: in H5WebViewController: \t_fontScale (NSString*): @"100%"<__NSCFConstantString: 0x338132c> \t_is3DTouchPeek (BOOL): 0 \t_is3DTouchPop (BOOL): 0 \t_gestureBack (BOOL): 0 \t_isFromNavigationBarHidden (BOOL): 0 \t_webPageLoadSuccess (BOOL): 1 \t_isBackProcessing (BOOL): 0 \t_isBackProcessed (BOOL): 0 \t_hideLeftButtonsByJs (BOOL): 0 \t_isDefaultOptionMenu (BOOL): 0 \t_isWebViewBackgroundColorSetted (BOOL): 1 \t_pullRefreshing (BOOL): 1 \t_isFromStatusBarHidden (BOOL): 0 \t_isInitAsSubView (BOOL): 0 \t_isDissmissProcess (BOOL): 0 \t_isAphaOverLimit (BOOL): 0 \t_isWebLoading (BOOL): 0 \t_isWebFinishLoad (BOOL): 1 \t_isViewAppeared (BOOL): 1 \t_isViewAppearAgain (BOOL): 0 \t_isViewWillDisAppear (BOOL): 0 \t_isViewDidDisAppear (BOOL): 0 \t_isAlipaySchemeWillRedirect (BOOL): 0 \t_isAlipaySchemeDidRedirect (BOOL): 0 \t_isAddObserver (BOOL): 0 \t_isFromStartApp (BOOL): 0 \tname (NSString*): nil \t_serviceDelegate (<H5ServiceDelegate>*): nil \t_contentView (PSDView*): nil \t_delegate (<PSDViewControllerDelegate>*): <PSDScene: 0x11067380> \t_statesView (UIView*): <UIView: 0xd9fa5d0> \t_customPreviewActionItems (NSArray*): nil \t_interceptUrl (NSString*): nil \t_appConfig (NSDictionary*): nil \t_url (NSURL*): https://render.alipay.com/p/f/fd-j6lzqrgm/addressbook.html \t_lastPageId (NSString*): nil \t_refreshHeaderView (AUPullLoadingView*): nil \t_stickyBouncer (H5StickyBouncer*): nil \t_backDate (NSDate*): nil \t_backBtnPressCount (int): 0 \t_serverErrorView (APExceptionView*): nil \t_fontBar (H5AdjustFontControl*): nil \t_statusBarStyle (int): 0 \t_htmlZoomValue (NSString*): @"1"<__NSCFString: 0x11130b50> \t_lastMainRequest (NSURLRequest*): <NSMutableURLRequest: 0x11064ac0> \t_failureNumber (int): 0 \t_webviewDomainLabel (UILabel*): <UILabel: 0xfb63630> \t_delayExecList (NSMutableArray*): <__NSArrayM: 0x110794a0> \t_paddingBottom (float): 0 \t_externNativeApiManager (H5ExternNativeApiManager*): <H5ExternNativeApiManager: 0x11089e10> \t_startLoadTime (NSDate*): <__NSDate: 0x11102510> \t_co
cy# [#0x5822600 url] #"https://render.alipay.com/p/f/fd-j6lzqrgm/addressbook.html"
展現的架構是基於layout
cy# [[UIApp keyWindow] _autolayoutTrace].toString() ` UIWindow:0x46c54d0 | UILayoutContainerView:0x8c1aa10 | | UINavigationTransitionView:0x8757090 | | | UIViewControllerWrapperView:0xb68c2d0 | | | | DTBaseView:0xd8e9180 | | | | | H5WebView:0x46ba350 | | | | | | UILabel:0xfb63630'\u7f51\u9875\u7531 render.alipay.com \u63d0\u4f9b' | | | | | | _UIWebViewScrollView:0xfaaacf0 | | | | | | | UIWebBrowserView:0x5984a00 | | | | | | | UIImageView:0xfaa4850 | | | | | | | UIImageView:0xfaaa940 | | | | | UIView:0xd9fa5d0 | | | | | NBProgressView:0x1108ae60 | | | | | | UIView:0x1108c790 | | APNavigationBar:0x8734d50 | | | _UINavigationBarBackground:0x8735800 | | | | _UIBackdropView:0x11106fd0 | | | | | _UIBackdropEffectView:0x111018d0 | | | | | UIView:0x11111bb0 | | | | UIImageView:0x8735c20 | | | H5NavigationTitleView:0x1114f680 | | | | UIControl_mainTitleConten...:0xfbf7f70 | | | | | UILabel:0x11100e30'\u901a\u8baf\u5f55\u670b\u53cb' | | | | UIControl_subtitleContent...:0xfbf7a90 | | | | | UILabel:0xb6f4050 | | | | UIControl_rightIconConten...:0xb681ca0 | | | | | UIImageView:0xfbfa810 | | | UIView:0x46a0090 | | | AUBarButtonItemButton_bac...:0x11146fb0 | | | | UIImageView:0x1112ffe0 | | | | UILabel:0xfb8a8c0'\u8fd4\u56de' | | | _UINavigationBarBackIndicatorView:0x8c0a660`
iPhone:~ root# ps -e |grep /var/mobile* 333 ?? 0:13.39 /var/mobile/Containers/Bundle/Application/DB9E7889-BC60-4B5C-91BD-E59D08204958/WeChat.app/WeChat 552 ?? 0:34.13 /var/mobile/Containers/Bundle/Application/239A0B7E-AA8C-4E43-873D-16254934321A/Taobao4iPhone.app/Taobao4iPhone 635 ?? 5:42.15 /var/mobile/Containers/Bundle/Application/3FDB82B6-8D3A-47BF-A27C-184D1E052854/AlipayWallet.app/AlipayWallet 923 ?? 0:01.37 /var/mobile/Containers/Bundle/Application/3A5795F5-1E2B-42B6-A904-D7BF2178D5EB/KillOneMosquito.app/KillOneMosquito 928 ttys000 0:00.01 grep /var/mobile
/usr/lib/cycript0.9/com
MS.cy 位於/usr/lib/cycript0.9/com/saurik/substrate
所以可使用`cy# @import com.saurik.substrate.MS
`進行導入。
Install to utils.cy to /usr/lib/cycript0.9/com/tyilo: mkdir -p /usr/lib/cycript0.9/com git clone https://github.com/Tyilo/cycript-utils.git /usr/lib/cycript0.9/com/tyilo Then in cycript: cy# @import com.tyilo.utils; 0
iPhone:~ root# apt-get install git Reading package lists... Done Building dependency tree Reading state information... Done The following extra packages will be installed: curl expat The following NEW packages will be installed: curl expat git 0 upgraded, 3 newly installed, 0 to remove and 16 not upgraded. Need to get 3065kB of archives. After this operation, 21.1MB of additional disk space will be used. Do you want to continue [Y/n]? y WARNING: The following packages cannot be authenticated! curl expat git Install these packages without verification [y/N]? y Get:1 http://apt.saurik.com ios/1141.14/main curl 7.33.0-9 [276kB] Get:2 http://apt.saurik.com ios/1141.14/main expat 2.0.1-3 [69.3kB] Get:3 http://apt.saurik.com ios/1141.14/main git 2.8.1-5 [2720kB] Fetched 3065kB in 25s (120kB/s) Selecting previously unselected package curl. (Reading database ... 1926 files and directories currently installed.) Preparing to unpack .../curl_7.33.0-9_iphoneos-arm.deb ... Unpacking curl (7.33.0-9) ... Selecting previously unselected package expat. Preparing to unpack .../expat_2.0.1-3_iphoneos-arm.deb ... Unpacking expat (2.0.1-3) ... Selecting previously unselected package git. Preparing to unpack .../git_2.8.1-5_iphoneos-arm.deb ... Unpacking git (2.8.1-5) ... Setting up curl (7.33.0-9) ... Setting up expat (2.0.1-3) ... Setting up git (2.8.1-5) ...
apt-get 第一次經過Lydia下載「APT0.6 Transitional" 以後能夠先update
iPhone:~ root# git -c http.sslVerify=false clone https://github.com/zhangkn/cycript-utils.git /usr/lib/cycript0.9/com/tyilo Cloning into '/usr/lib/cycript0.9/com/tyilo'... remote: Counting objects: 46, done. remote: Total 46 (delta 0), reused 0 (delta 0), pack-reused 46 Unpacking objects: 100% (46/46), done. Checking connectivity... done.
返回值是一個 數組,表示在當前堆棧中查找到的全部MyClass類的對象數據。
cy# a = choose(UILabel).toString() "<UILabel: 0x1031f9b0; frame = (32.5 236.738; 255 20.4378); text = '\u5f00\u901a\u6307\u7eb9\u652f\u4ed8\uff0c\u8ba9\u4ed8\u6b3e\u66f4\u5b89\u5168\u4fbf\u6377'; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x1031f900>>,<UILabel: 0x10321c70; frame = (13.2267 349.997; 255 19.1604); text = '\u6211\u5df2\u9605\u8bfb\u5e76\u540c\u610f\u300a\u6307\u7eb9\u652f\u4ed8\u76f8\u5173\u534f\u8bae\u300b'; gestureRecognizers = <NSArray: 0x103224d0>; layer = <_UILabelLayer: 0x10321d30>>,<UILabel: 0x1032c0e0; frame = (0 0; 0 0); text = ''; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x1032c1a0>>,<UILabel: 0x10338a60; frame = (62 0; 34 47); text = '\u8d26\u5355'; userInteractionEnabled = NO; layer = <_UILabelLayer: 0xe2eeb30>>,<UILabel: 0x10338ee0; frame = (0 58; 90 15.509); text = '\u52a0\u8f7d\u4e2d'; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x1ad6cde0>>,<VZFTextNodeBackingView: 0x10344f10; baseClass = UILabel; frame = (6 74.5; 82.5 15.5); text = '\u798f\u5eb7\u4fdd\u5065\u4e2d\u5fc3(\u97f6\u5c71\u5357\u8def\u5e97)'; userInteractionEnabled = NO; layer = <VZFTextNodeBackingLayer: 0x10385e00>>,<UILabel: 0x103d5100; frame = (0 105; 0 0); text = ''; opaque = NO; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x10307af0>>,<UILabel: 0x103e3790; frame = (62 0; 34 47); text = '\u4f59\u989d'; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x103e73a0>>,<UILabel: 0x103e3970; frame = (98 0; 191 47); text = '13.09 \u5143'; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x103e3a30>>,<UILabel: 0xc40b010; frame = (2.5 36.4385; 75 13.123); text = '\u5145\u503c\u4e2d\u5fc3'; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x8bf21a0>>,<UILabel: 0xc40bbe0; frame = (2.5 36.4385; 75 13.123); text = '\u751f\u6d3b\u7f34\u8d39'; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x8be6bb0>>,<UILabel: 0xc4156a0; frame = (2.5 36.4385; 75 13.123); text = '\u829d\u9ebb\u4fe1\u7528'; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x8beb6d0>>,<UILabel: 0xc416fe0; frame = (0 0; 0 0); userInteractionE cy# a
MS.HookMessage : 這個函數的實現是調用MSHookMessageEx ,用法以下 :
devzkndeMacBook-Pro:lib devzkn$ /Users/devzkn/Downloads/cycript_0.9.594/cycript dyld: Library not loaded: /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/libruby.2.0.0.dylib Referenced from: /Users/devzkn/Downloads/cycript_0.9.594/Cycript.lib/cycript-apl Reason: image not found Abort trap: 6
devzkndeMacBook-Pro:.ssh devzkn$ sudo mkdir -p /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ Password: mkdir: /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/: Operation not permitted
先關閉系統的SIP,而後運行以下命令,把原來引用的位置建立符號連接到如今新版本的位置:
sudo mkdir -p /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ sudo ln -s /System/Library/Frameworks/Ruby.framework/Versions/2.3/usr/lib/libruby.2.3.0.dylib /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/libruby.2.0.0.dylib
/System/Library/Frameworks/Ruby.framework/Versions/Current/usr/lib