之前文章已經對LLDB進行了介紹和使用。LLDB在我們除錯應用的時候確實很爽,但他每次都要斷住程式,這在分析並且修改APP的時候確實是一個優勢,但是在面對一個比較大型的專案,我們需要整體分析的時候,這樣除錯就顯得有些力不從心了。而Cycript就可以彌補上這個需求。
Cycript是由Cydia創始人Saurik推出的一款指令碼語言,Cycript混合了OC、JavaScript語法的直譯器,這意味著我們能夠在一個命令中使用Oc或者JavaScript,甚至兩者並用。它能夠掛鉤正在執行的程式,能夠在執行時修改很多東西。
一、語言分類
-
編譯型語言(OC) 需要將原始碼經過編譯器編譯,生成對應架構的可執行檔案(二進位制)
-
解釋型語言(Python) 原始碼不需要編譯器提前編譯,而是在執行的時候,經過一套對應的直譯器,臨時將原始碼翻譯成二進位制讓CPU識別。
編譯型語言就相當於一個英語嫻熟的人看一本英文書籍,不需要藉助別的工具了。代價就是學英語這個過程很慢(編譯時間長)。 解釋型語言就相當於一個不會英語的人看一本英文書籍,這時候就需要藉助工具(字典)才能正常閱讀。好處的就是沒有學習(編譯)這麼個耗時的過程。
理論上解釋型語言在執行效率上會比解釋型語言慢很多,但實際上現在有很多牛逼的直譯器,在執行特定的程式碼的時候效率也非常快。原理就是在執行的的時候會將之前解釋過的程式碼快取起來,之後就不需要重複解釋了。如:pypy3
這片文章的主角Cycript就是解釋型語言!
二、安裝
1、下載安裝
Cycript的安裝極其簡單,在這裡下載SDK,下載下來的就是一個可執行檔案。檔案不大,只有2.9M。
開啟終端,CD進入Cycript目錄直接執行Cycript
./cycript
複製程式碼
不出意外這個時候會有如下報錯:
這是因為本地Ruby版本和Cycript要求的版本不一樣導致(其實程式碼都一樣,只是版本號換了就不認識了,真蠢)。
2、解決Ruby
Step 1 檢視本地Ruby版本:
cd /System/Library/Frameworks/Ruby.framework/Versions/
ls
複製程式碼
本地顯示版本號為:2.3,而Cycript要求的版本號2.0。
解決方案:
複製一本Ruby原始碼,將其版本號(資料夾名稱)改為2.0
Step 2 關閉系統的SIP
在 OS X El Capitan 中有一個跟安全相關的模式叫 SIP(System Integrity Protection ),它禁止讓軟體以 root 身份來在 Mac 上執行,在升級到 OS X 10.11 中或許你就會看到部分應用程式被禁用了,這些或許是你通過終端或者第三方軟體源安裝。對於大多數使用者來說,這種安全設定很方便,但是也有些開發者或者高階 Mac 使用者不需要這樣的設定。
- 電腦重啟按住command+R,進入恢復模式
- 開啟終端,輸入
csrutil disable
,重啟 - 如果想開啟SIP,重複上兩步,命令改為
csrutil enable
Step 3 直接把2.3的複製一份,改為2.0即可
重啟電腦後,執行如下命令:
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
複製程式碼
注:根據每個人ruby版本不同,將上面第二條命令的/System/Library/Frameworks/Ruby.framework/Versions/2.3/usr/lib/libruby.2.3.0.dylib中的2.3改成本機的ruby版本。 這裡不是降級ruby,只是複製一份2.0的ruby的dylib,讓cycript執行起來。
再次執行
./cycript
複製程式碼
如果出現 cy#
即代表進入Cycript環境了。
3、配置環境變數
Step 1 移動Cycript
/opt
目錄是專門放置一些額外功能包的目錄,所以我們將Cycript也放在該目錄下。
Step 2 環境變數
進入使用者的根目錄,裡面有個檔案.bash_profile
,用文字編輯器開啟。
export CY=/opt/cycript_0.9.594/
export PATH = $CY:$PATH
複製程式碼
Save儲存。之後就可以在任意目錄下使用Cycript了。
三、簡單使用
1、基本的語法
2、基本除錯
在上篇文章中已經介紹了Monkey,並且可以看出它已經幫我們整合了Cycript的動態庫。所以一下就配合著Monkey來進行除錯。
馬不停蹄,新建一個Monkey工程,將已經砸殼成功的優酷ipa包放入對應的Target目錄下。詳情參考:
由於Monkey預設開放了一個埠號6666,如圖:
所以我們就使用Cycript連線埠號6666,找到手機連線的Wifi的IP地址:
所裡在終端輸入指令:
cycript -r 192.168.32.113:6666
複製程式碼
如果你那一直停在這一步,沒有進入Cycript環境
那麼有三種可能
- 手機和電腦必須處於同一個wifi
- wifi有問題,換一個wifi試試,或者直接使用手機開個熱點,電腦連上你的熱點
- 埠號被佔用,需要換一個埠(先換Monkey開放的埠,再換指令連線的埠)
一切正常後就可以開始除錯了,見如下圖:
// 檢視當前的KeyWindow
UIWindow.keyWindow()
// 自定義變數
var keyWindow = UIWindow.keyWindow()
keyWindow
// 隱藏狀態列
[UIApp setStatusBarHidden:YES];
// 使用地址檢視
#0x108e3cd80
// 檢視一個物件下的所有變數
*#0x108e3cd80
// 檢視一個物件下成員變數的名字
[i for(i in *keyWindow)]
// 格式化輸出當前View的層級關係
keyWindow.recursiveDescription().toString()
// 顯示當前View下的所有的Button
choose(UIButton)
複製程式碼
3、高階用法
在之前的文章 LLDB,自制LLDB指令碼,竄改微信紅包金額 中介紹了LLDB可以自己定義指令碼以方便自己使用,同樣Cycript也是可以做到自定義API。
1、新建cy檔案
新建一個cy檔案,取名FYTest.cy
2、定義變數和函式
在FYTest.cy中定義變數和函式
// 獲取AppID
FYAPPID = NSBundle.mainBundle.bundleIdentifier;
// 獲取沙盒目錄
FYAPPPATH = NSBundle.mainBundle.bundlePath;
FYRootVC = function(){
return UIApp.keyWindow.rootViewController;
};
FYGetCurrentVCFromRootVC = function(rootVC){
var currentVC;
if([rootVC presentedViewController]){
rootVC = [rootVC presentedViewController];
}
if([rootVC isKindOfClass:[UITabBarController class]]){
currentVC = FYGetCurrentVCFromRootVC(rootVC.selectedViewController);
}else if([rootVC isKindOfClass:[UINavigationController class]]){
currentVC = FYGetCurrentVCFromRootVC(rootVC.visibleViewController);
}else{
currentVC = rootVC;
}
return currentVC;
};
// 獲取當前VC
FYCurrentVC = function(){
return FYGetCurrentVCFromRootVC(FYRootVC());
};
複製程式碼
3、匯入Cy檔案
4、使用Cy檔案
FYTest.cy檔案雖然已經在我們的APP裡面了,但是我們每次使用的時候還是需要匯入一次。
@import FYTest
複製程式碼
5、大神們封裝好的cy
Monkey預設幫我們預裝好了幾個cy檔案,分別在一下兩張圖的位置:
-
MachO中的cy
-
通過網路載入的cy
具體有哪些變數可以用,哪些函式可以用都可以在這找到哦:ms,md
四、總結
到此,所有非越獄環境下的東西已經整理完了,接下來將要開啟新的篇章:手機越獄、砸殼、以及彙編靜態分析。如果你覺得有幫助,就點個小心心吧