
在上篇文章中,我們講了LLDB的常用指令,以及這些指令的作用,但是LLDB的功能遠(yuǎn)遠(yuǎn)不止這些,今天我們來(lái)看一下LLDB的高級(jí)功能吧。
今天的DEMO也比較簡(jiǎn)單,可以在點(diǎn)擊這里下載到:Demo8_LLDB高級(jí)用法
接下來(lái)本文會(huì)從以下幾點(diǎn)進(jìn)行闡述:
- ASLR簡(jiǎn)介
- chise安裝&使用
- DerekSelander-LLDB
- Cycript安裝&簡(jiǎn)單使用
- 腳本自動(dòng)鏈接
- Cycript練習(xí)
- Cycript高級(jí)用法
- cy文件封裝
1. ASLR簡(jiǎn)介
ASLR(Address space layout randomization)是一種針對(duì)緩沖區(qū)溢出的安全保護(hù)技術(shù),通過(guò)對(duì)堆、棧、共享庫(kù)映射等線(xiàn)性區(qū)布局的隨機(jī)化,通過(guò)增加攻擊者預(yù)測(cè)目的地址的難度,防止攻擊者直接定位攻擊代碼位置,達(dá)到阻止溢出攻擊的目的。
大部分主流的操作系統(tǒng)已經(jīng)實(shí)現(xiàn)了ASLR。
| 平臺(tái) | 描述 |
|---|---|
| Linux | Linux已在內(nèi)核版本2.6.12中添加ASLR。 |
| Windows | Windows Server 2008,Windows 7,Windows Vista,Windows Server 2008 R2,默認(rèn)情況下啟用ASLR,但它僅適用于動(dòng)態(tài)鏈接庫(kù)和可執(zhí)行文件。 |
| Mac OS X | Apple在Mac OS X Leopard10.5(2007年十月發(fā)行)中某些庫(kù)導(dǎo)入了隨機(jī)地址偏移,但其實(shí)現(xiàn)并沒(méi)有提供ASLR所定義的完整保護(hù)能力。而Mac OS X Lion10.7則對(duì)所有的應(yīng)用程序均提供了ASLR支持。Apple宣稱(chēng)為應(yīng)用程序改善了這項(xiàng)技術(shù)的支持,能讓32及64位的應(yīng)用程序避開(kāi)更多此類(lèi)攻擊。從OS X Mountain Lion10.8開(kāi)始,核心及核心擴(kuò)充(kext)與zones在系統(tǒng)啟動(dòng)時(shí)也會(huì)隨機(jī)配置。 |
| iOS(iPhone, iPod touch, iPad) | Apple在iOS4.3內(nèi)導(dǎo)入了ASLR。 |
| Android | Android 4.0提供地址空間配置隨機(jī)加載(ASLR),以幫助保護(hù)系統(tǒng)和第三方應(yīng)用程序免受由于內(nèi)存管理問(wèn)題的攻擊,在Android 4.1中加入地址無(wú)關(guān)代碼(position-independent code)的支持。 |
1.1 ASLR 案例
創(chuàng)建iOS項(xiàng)目,在 touchBegan:withEvent: 調(diào)用一個(gè)簡(jiǎn)單的方法。
Build一下,將LLDBDemo的可執(zhí)行文件復(fù)制一份出來(lái),使用Hopper查看,獲取到自己寫(xiě)的方法的地址。
3.使用 breakpoint -a 0xxx 下一個(gè)地址斷點(diǎn)。
4.使用 MachOView 分析PageZero地址。
注意:image list的首地址和hopper中的地址,他們中間有一個(gè)偏移地址。因?yàn)閕mage list 每次加載進(jìn)內(nèi)存都會(huì)默認(rèn)加一個(gè)ASLR,所以我們得到一個(gè)數(shù)據(jù)的地址時(shí)要減去image list地址,這時(shí)可以通過(guò)MachO文件來(lái)查看數(shù)據(jù)。
macho中的地址+hopper中的函數(shù)地址就是當(dāng)前的函數(shù)地址
定義一個(gè)全局變量,找到這個(gè)變量的地址,使用MachO對(duì)應(yīng)的變量,找MachO中的偏移值。
2. chisel 安裝
1.github開(kāi)源,可通過(guò)homebrew安裝
2.安裝完成添加一個(gè)路徑到 .lldbinit中
注意:chisel配置環(huán)境依據(jù)github上的方法來(lái),否則環(huán)境錯(cuò)誤將調(diào)用不了。
3. chisel 使用
1.chisel 本質(zhì) 注意配置完chise需要重啟xcode或者在lldb命令中使用 command source ~/.lldbinit。
2.pviews / pview self.view / pview -u self 命令的使用。
3.pvc 查看控制器的層級(jí)結(jié)構(gòu)。
4.presponder 控件地址 輸出這個(gè)按鈕的響應(yīng)鏈條。
5.pactions 地址 得到當(dāng)前按鈕的響應(yīng)事件。
6.pclass 對(duì)象地址 得到對(duì)象的繼承關(guān)系。
7.fv/fvc 類(lèi)名 查看視圖/查看控制器。
8.methods 類(lèi)對(duì)象地址 找到當(dāng)前類(lèi)的方法,屬性,地址。
9.pinternals 類(lèi)對(duì)象地址 查到當(dāng)前對(duì)象的屬性,當(dāng)前對(duì)象的屬性值。
10.fvc -v 對(duì)象地址 根據(jù)對(duì)像的地址找到對(duì)象的類(lèi)型。
11.taplog 找到當(dāng)前界面中響應(yīng)的控件的對(duì)象、地址.
注意:taplog使用需要注意以下2點(diǎn)
1.界面控件是可響應(yīng)的
2.這個(gè)命令會(huì)使當(dāng)前的程序掛掉
- filcker 對(duì)象地址 將當(dāng)前的控件閃爍顯示,快速找到某一個(gè)控件。
- vs 對(duì)象地址 動(dòng)態(tài)的操作這個(gè)控件,進(jìn)入到LLDB中,根據(jù)提示調(diào)試。
4. DerekSelander-LLDB 安裝
1.github 安裝 參照 chisel 安裝
2.search UIView 查找所有View
3.使用monkeyDev 調(diào)試
4.快速定位
4.1 通過(guò)內(nèi)存地址下斷點(diǎn)
4.2 使用 search 類(lèi)名 查到對(duì)象的地址
4.3 使用 methods 地址 找到對(duì)象的成員變量/方法
4.4 使用 b -a 地址 設(shè)置斷點(diǎn)
4.5 使用 bt 查看當(dāng)前的調(diào)用棧,會(huì)發(fā)現(xiàn)當(dāng)前的狀態(tài)是去符號(hào)的狀態(tài)
4.6 sbt 恢復(fù)當(dāng)前函數(shù)的符號(hào)
使用方法參照github
5. Cycript-安裝
5.1 Cycript 簡(jiǎn)介
Cycript是由Cydia創(chuàng)始人Saurik推出的一款腳本語(yǔ)言,Cycript混合了OC、JavaScript語(yǔ)法的解釋器,這意味著我們能夠在一個(gè)命令中使用Oc或者JavaScript,甚至兩者并用。它能夠掛鉤正在運(yùn)行的進(jìn)程,能夠在運(yùn)行時(shí)修改很多東西。
5.2 Cycript 安裝
- 官網(wǎng): http://www.cycript.org/
- 下載后使用Cycript這個(gè)可執(zhí)行文件
- 為了方便,我們可以放在 /opt/cycript_0.9.594 (opt目錄有可選的意思)
- 為了方便使用,可以在~/.bash_profile中配置環(huán)境變量(執(zhí)行文件路徑)。
5.3 Cycript 簡(jiǎn)單使用
1.首先鏈接手機(jī)
monkeyDev 使用,monkeydev 默認(rèn)連接手機(jī)端口 6666
2.應(yīng)用跑起來(lái),打開(kāi)終端,查看手機(jī)ip
3.ccycript -r xxx.xxx.xxx.xxx:6666
4.終端輸入U(xiǎn)IWindow keyWindow()
5.[UIApplication shardAppliccation]
6.var keyWindow = UIWindow.keyWindow()
7.keyWindow
8.keyWindow.rootViewController
9.#內(nèi)存地址 拿到這個(gè)對(duì)象
10.*#內(nèi)存地址 拿到某個(gè)對(duì)象的所有成員變量
11.也可以使用上面的 keyWindow
12.[i for(i in *keyWindow)] // 拿到keyWindow的所有成員變量,只拿key
13.keyWindow.reccursiveDescription // 拿到視圖的層級(jí)關(guān)系,會(huì)發(fā)現(xiàn)拿到的都是亂碼
14.keyWindow.reccursiveDescription.toString() // 格式化輸出
15.choose[UIButton] // 獲取Button類(lèi)型的控件 不知是全項(xiàng)目中的還是當(dāng)前文件中的,這個(gè)要測(cè)試
16.使用 control+D 退出,然后重新連接,之前的keyWindow 還是在的。(因?yàn)楫?dāng)前的進(jìn)程還是在的,如果把當(dāng)前的進(jìn)程刪掉就沒(méi)有了)
- 腳本自動(dòng)連接
- 將所有的腳本放在一個(gè)文件夾中,給腳本可執(zhí)行權(quán)限,并在.base_podfile中添加相應(yīng)的路徑
5.4 Cycript 簡(jiǎn)單使用案例 這里要修改VX相關(guān)的內(nèi)容,由于沒(méi)有多余的VX號(hào),這里就做個(gè)簡(jiǎn)單的記錄。
1.進(jìn)入cycript環(huán)境
2.修改當(dāng)前界面的狀態(tài)欄
[UIApp setStatusBarHidden:YES]; // 隱藏狀態(tài)欄
[UIApp setStatusBarHidden:NO]; // 顯示狀態(tài)欄
[UIApp setApplicationIconBadgeNumber:9999]; // 修改消息條數(shù)
3.修改轉(zhuǎn)賬金額數(shù)據(jù)
chose[UILabel] // 查找UILabel
搜索剛才的 0.01 的文本
拿到對(duì)象使用 #對(duì)象.text = "¥xxx" // 注意,當(dāng)這個(gè)界面消失的時(shí)候,這個(gè)對(duì)象就沒(méi)有了,所以界面也沒(méi)有了
5.5 cycript 高級(jí)用法
1.cycript 內(nèi)置的對(duì)象 ObjectiveC.classes // 列舉當(dāng)前項(xiàng)目中的所有的類(lèi)
2.APPID 獲取當(dāng)前的 Build id
3.pviews() // 獲取項(xiàng)目中的Views
4.pvcs() // 獲取控制器
5.調(diào)試某一個(gè)按鈕
LLDB 找到某一個(gè)按鈕,獲取按鈕的類(lèi)型
使用 choose(AttachmentButton)
pactions(#地址) // 給個(gè)對(duì)象,輸出它的Actions
rp(#對(duì)象地址) // 獲取這個(gè)對(duì)象的響應(yīng)鏈條
6.monkeyDev Config 中的URL ,通過(guò)瀏覽器打開(kāi),會(huì)發(fā)現(xiàn)一個(gè)*.cy文件
1.自己創(chuàng)建 *.cy文件,創(chuàng)建空類(lèi)型的文件,文件依賴(lài)當(dāng)前的工程
2.文件類(lèi)型改成JavaScript或者oc、C++語(yǔ)法,重啟Xcode才會(huì)有語(yǔ)法高亮
3.在cy環(huán)境下測(cè)試函數(shù),輸入以下代碼
sum = function(a,b){return a+b;}
sub(10,20)
4.在cy文件中添加上述代碼,并導(dǎo)入到app中,TARGETS -> 項(xiàng)目 -> Build Phases -> Copy Files 中添加 test.cy 文件
5.在cy環(huán)境下 @inport test 文件,否則找不到文件
6.接下來(lái)我們就可以在我們的文件中添加自己需要的代碼了
注意:我們?cè)谖募刑砑拥淖兞恳煤瘮?shù)的方法獲得,否則變量會(huì)在執(zhí)行第一次之后就固定了。
7.js 匿名函數(shù)自執(zhí)行表達(dá)式
( function(export(參數(shù))){
code ...
// 代碼自動(dòng)執(zhí)行
// 變量后需要用逗號(hào)隔開(kāi)
})(export)
如有問(wèn)題歡迎下方留言評(píng)論